ACE/FAQ/APG/Reactor
Материал из Wiki.crossplatform.ru
(Различия между версиями)
ViGOur (Обсуждение | вклад)
(Новая страница: «__TOC__ Категория:ACE FAQ == ClientService.h == <source lang="cpp"> /** * $Id: ClientService.h 80826 2008-03-04 14:51:23Z wotte $ * * Sample code fr…»)
(Новая страница: «__TOC__ Категория:ACE FAQ == ClientService.h == <source lang="cpp"> /** * $Id: ClientService.h 80826 2008-03-04 14:51:23Z wotte $ * * Sample code fr…»)
Текущая версия на 19:13, 6 февраля 2012
Содержание |
[править] ClientService.h
/** * $Id: ClientService.h 80826 2008-03-04 14:51:23Z wotte $ * * Sample code from The ACE Programmer's Guide, * copyright 2003 Addison-Wesley. All Rights Reserved. */ #ifndef __CLIENTSERVICE_H_ #define __CLIENTSERVICE_H_ #include "ace/Synch_Traits.h" #include "ace/Null_Condition.h" #include "ace/Null_Mutex.h" // Listing 3 code/ch07 #include "ace/Message_Block.h" #include "ace/SOCK_Stream.h" #include "ace/Svc_Handler.h" class ClientService : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> { typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super; public: int open (void * = 0); // Called when input is available from the client. virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when output is possible. virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when this handler is removed from the ACE_Reactor. virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask); }; // Listing 3 #endif /* __CLIENTSERVICE_H_ */
[править] Client.h
/** * $Id: Client.h 80826 2008-03-04 14:51:23Z wotte $ * * Sample code from The ACE Programmer's Guide, * copyright 2003 Addison-Wesley. All Rights Reserved. */ #ifndef __CLIENT_H_ #define __CLIENT_H_ #include "ace/Synch_Traits.h" #include "ace/Null_Condition.h" #include "ace/Null_Mutex.h" // Listing 1 code/ch07 #include "ace/Reactor.h" #include "ace/INET_Addr.h" #include "ace/SOCK_Stream.h" #include "ace/SOCK_Connector.h" #include "ace/Connector.h" #include "ace/Svc_Handler.h" #include "ace/Reactor_Notification_Strategy.h" class Client : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> { typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super; public: Client () : notifier_ (0, this, ACE_Event_Handler::WRITE_MASK) {} virtual int open (void * = 0); // Called when input is available from the client. virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when output is possible. virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when a timer expires. virtual int handle_timeout (const ACE_Time_Value ¤t_time, const void *act = 0); private: enum { ITERATIONS = 5 }; int iterations_; ACE_Reactor_Notification_Strategy notifier_; }; // Listing 1 #endif /* __CLIENT_H_ */
[править] A simple client program using ACE_Svc_Handler and ACE_Connector
/** * $Id: Client.cpp 91626 2010-09-07 10:59:20Z johnnyw $ * * A simple client program using ACE_Svc_Handler and ACE_Connector. */ #include "ace/OS_NS_stdio.h" #include "ace/OS_NS_errno.h" #include "ace/OS_NS_string.h" #include "ace/OS_NS_sys_time.h" #include "Client.h" // Listing 2 code/ch07 int Client::open (void *p) { ACE_Time_Value iter_delay (2); // Two seconds if (super::open (p) == -1) return -1; this->notifier_.reactor (this->reactor ()); this->msg_queue ()->notification_strategy (&this->notifier_); this->iterations_ = 0; return this->reactor ()->schedule_timer (this, 0, ACE_Time_Value::zero, iter_delay); } // Listing 2 // Listing 3 code/ch07 int Client::handle_input (ACE_HANDLE) { char buf[64]; ssize_t recv_cnt = this->peer ().recv (buf, sizeof (buf) - 1); if (recv_cnt > 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%.*C"), static_cast<int> (recv_cnt), buf)); return 0; } if (recv_cnt == 0 || ACE_OS::last_error () != EWOULDBLOCK) { this->reactor ()->end_reactor_event_loop (); return -1; } return 0; } // Listing 3 // Listing 4 code/ch07 int Client::handle_timeout(const ACE_Time_Value &, const void *) { if (++this->iterations_ >= ITERATIONS) { this->peer ().close_writer (); return 0; } ACE_Message_Block *mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (128), -1); int nbytes = ACE_OS::sprintf (mb->wr_ptr (), "Iteration %d\n", this->iterations_); ACE_ASSERT (nbytes > 0); mb->wr_ptr (static_cast<size_t> (nbytes)); this->putq (mb); return 0; } // Listing 4 // Listing 5 code/ch07 int Client::handle_output (ACE_HANDLE) { ACE_Message_Block *mb = 0; ACE_Time_Value nowait (ACE_OS::gettimeofday ()); while (-1 != this->getq (mb, &nowait)) { ssize_t send_cnt = this->peer ().send (mb->rd_ptr (), mb->length ()); if (send_cnt == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("send"))); else mb->rd_ptr (static_cast<size_t> (send_cnt)); if (mb->length () > 0) { this->ungetq (mb); break; } mb->release (); } if (this->msg_queue ()->is_empty ()) this->reactor ()->cancel_wakeup (this, ACE_Event_Handler::WRITE_MASK); else this->reactor ()->schedule_wakeup (this, ACE_Event_Handler::WRITE_MASK); return 0; } // Listing 5 // Listing 6 code/ch07 int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_INET_Addr port_to_connect (ACE_TEXT ("HAStatus"), ACE_LOCALHOST); ACE_Connector<Client, ACE_SOCK_CONNECTOR> connector; Client client; Client *pc = &client; if (connector.connect (pc, port_to_connect) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("connect")), 1); ACE_Reactor::instance ()->run_reactor_event_loop (); return (0); } // Listing 6 // Listing 7 code/ch07 // Listing 7
[править] HAStatus
// $Id: HAStatus-AC.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/OS_NS_errno.h" #include "ace/OS_NS_sys_time.h" #include "ace/os_include/os_netdb.h" #include "ClientService.h" // Listing 1 code/ch07 #include "ace/Log_Msg.h" #include "ace/INET_Addr.h" #include "ace/SOCK_Acceptor.h" #include "ace/Reactor.h" #include "ace/Acceptor.h" typedef ACE_Acceptor<ClientService, ACE_SOCK_ACCEPTOR> ClientAcceptor; // Listing 1 // Listing 4 code/ch07 int ClientService::open (void *p) { if (super::open (p) == -1) return -1; ACE_TCHAR peer_name[MAXHOSTNAMELEN]; ACE_INET_Addr peer_addr; if (this->peer ().get_remote_addr (peer_addr) == 0 && peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connection from %s\n"), peer_name)); return 0; } // Listing 4 // Listing 5 code/ch07 int ClientService::handle_input (ACE_HANDLE) { const size_t INPUT_SIZE = 4096; char buffer[INPUT_SIZE]; ssize_t recv_cnt, send_cnt; recv_cnt = this->peer ().recv (buffer, sizeof(buffer)); if (recv_cnt <= 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connection closed\n"))); return -1; } send_cnt = this->peer ().send (buffer, static_cast<size_t> (recv_cnt)); if (send_cnt == recv_cnt) return 0; if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("send")), 0); if (send_cnt == -1) send_cnt = 0; ACE_Message_Block *mb = 0; size_t remaining = static_cast<size_t> ((recv_cnt - send_cnt)); ACE_NEW_RETURN (mb, ACE_Message_Block (remaining), -1); mb->copy (&buffer[send_cnt], remaining); int output_off = this->msg_queue ()->is_empty (); ACE_Time_Value nowait (ACE_OS::gettimeofday ()); if (this->putq (mb, &nowait) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p; discarding data\n"), ACE_TEXT ("enqueue failed"))); mb->release (); return 0; } if (output_off) return this->reactor ()->register_handler (this, ACE_Event_Handler::WRITE_MASK); return 0; } // Listing 5 // Listing 6 code/ch07 int ClientService::handle_output (ACE_HANDLE) { ACE_Message_Block *mb = 0; ACE_Time_Value nowait (ACE_OS::gettimeofday ()); while (-1 != this->getq (mb, &nowait)) { ssize_t send_cnt = this->peer ().send (mb->rd_ptr (), mb->length ()); if (send_cnt == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("send"))); else mb->rd_ptr (static_cast<size_t> (send_cnt)); if (mb->length () > 0) { this->ungetq (mb); break; } mb->release (); } return (this->msg_queue ()->is_empty ()) ? -1 : 0; } // Listing 6 // Listing 7 code/ch07 int ClientService::handle_close (ACE_HANDLE h, ACE_Reactor_Mask mask) { if (mask == ACE_Event_Handler::WRITE_MASK) return 0; return super::handle_close (h, mask); } // Listing 7 // Listing 2 code/ch07 int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_INET_Addr port_to_listen ("HAStatus"); ClientAcceptor acceptor; if (acceptor.open (port_to_listen, ACE_Reactor::instance (), ACE_NONBLOCK) == -1) return 1; ACE_Reactor::instance ()->run_reactor_event_loop (); return (0); } // Listing 2 // Listing 8 code/ch07 // Listing 8
[править] HAStatus
// $Id: HAStatus.cpp 91626 2010-09-07 10:59:20Z johnnyw $ #include "ace/OS_NS_sys_time.h" #include "ace/os_include/os_netdb.h" // Listing 1 code/ch07 #include "ace/Auto_Ptr.h" #include "ace/Log_Msg.h" #include "ace/INET_Addr.h" #include "ace/SOCK_Acceptor.h" #include "ace/Reactor.h" class ClientAcceptor : public ACE_Event_Handler { public: virtual ~ClientAcceptor (); //FUZZ: disable check_for_lack_ACE_OS int open (const ACE_INET_Addr &listen_addr); //FUZZ: enable check_for_lack_ACE_OS // Get this handler's I/O handle. virtual ACE_HANDLE get_handle (void) const { return this->acceptor_.get_handle (); } // Called when a connection is ready to accept. virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when this handler is removed from the ACE_Reactor. virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask); protected: ACE_SOCK_Acceptor acceptor_; }; // Listing 1 // Listing 6 code/ch07 #include "ace/Message_Block.h" #include "ace/Message_Queue.h" #include "ace/SOCK_Stream.h" #include "ace/Synch.h" class ClientService : public ACE_Event_Handler { public: ACE_SOCK_Stream &peer (void) { return this->sock_; } //FUZZ: disable check_for_lack_ACE_OS int open (void); //FUZZ: enable check_for_lack_ACE_OS // Get this handler's I/O handle. virtual ACE_HANDLE get_handle (void) const { return this->sock_.get_handle (); } // Called when input is available from the client. virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when output is possible. virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); // Called when this handler is removed from the ACE_Reactor. virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask); protected: ACE_SOCK_Stream sock_; ACE_Message_Queue<ACE_NULL_SYNCH> output_queue_; }; // Listing 6 // Listing 5 code/ch07 ClientAcceptor::~ClientAcceptor () { this->handle_close (ACE_INVALID_HANDLE, 0); } // Listing 5 // Listing 2 code/ch07 int ClientAcceptor::open (const ACE_INET_Addr &listen_addr) { if (this->acceptor_.open (listen_addr, 1) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("acceptor.open")), -1); return this->reactor ()->register_handler (this, ACE_Event_Handler::ACCEPT_MASK); } // Listing 2 // Listing 3 code/ch07 int ClientAcceptor::handle_input (ACE_HANDLE) { ClientService *client; ACE_NEW_RETURN (client, ClientService, -1); auto_ptr<ClientService> p (client); if (this->acceptor_.accept (client->peer ()) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("Failed to accept ") ACE_TEXT ("client connection")), -1); p.release (); client->reactor (this->reactor ()); if (client->open () == -1) client->handle_close (ACE_INVALID_HANDLE, 0); return 0; } // Listing 3 // Listing 4 code/ch07 int ClientAcceptor::handle_close (ACE_HANDLE, ACE_Reactor_Mask) { if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE) { ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL; this->reactor ()->remove_handler (this, m); this->acceptor_.close (); } return 0; } // Listing 4 // Listing 7 code/ch07 int ClientService::open (void) { ACE_TCHAR peer_name[MAXHOSTNAMELEN]; ACE_INET_Addr peer_addr; if (this->sock_.get_remote_addr (peer_addr) == 0 && peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connection from %s\n"), peer_name)); return this->reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK); } // Listing 7 // Listing 8 code/ch07 int ClientService::handle_input (ACE_HANDLE) { const size_t INPUT_SIZE = 4096; char buffer[INPUT_SIZE]; ssize_t recv_cnt, send_cnt; if ((recv_cnt = this->sock_.recv (buffer, sizeof(buffer))) <= 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Connection closed\n"))); return -1; } send_cnt = this->sock_.send (buffer, static_cast<size_t> (recv_cnt)); if (send_cnt == recv_cnt) return 0; if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("send")), 0); if (send_cnt == -1) send_cnt = 0; ACE_Message_Block *mb = 0; size_t remaining = static_cast<size_t> ((recv_cnt - send_cnt)); ACE_NEW_RETURN (mb, ACE_Message_Block (remaining), -1); mb->copy (&buffer[send_cnt], remaining); int output_off = this->output_queue_.is_empty (); ACE_Time_Value nowait (ACE_OS::gettimeofday ()); if (this->output_queue_.enqueue_tail (mb, &nowait) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p; discarding data\n"), ACE_TEXT ("enqueue failed"))); mb->release (); return 0; } if (output_off) return this->reactor ()->register_handler (this, ACE_Event_Handler::WRITE_MASK); return 0; } // Listing 8 // Listing 9 code/ch07 int ClientService::handle_output (ACE_HANDLE) { ACE_Message_Block *mb = 0; ACE_Time_Value nowait (ACE_OS::gettimeofday ()); while (0 <= this->output_queue_.dequeue_head (mb, &nowait)) { ssize_t send_cnt = this->sock_.send (mb->rd_ptr (), mb->length ()); if (send_cnt == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("send"))); else mb->rd_ptr (static_cast<size_t> (send_cnt)); if (mb->length () > 0) { this->output_queue_.enqueue_head (mb); break; } mb->release (); } return (this->output_queue_.is_empty ()) ? -1 : 0; } // Listing 9 // Listing 10 code/ch07 int ClientService::handle_close (ACE_HANDLE, ACE_Reactor_Mask mask) { if (mask == ACE_Event_Handler::WRITE_MASK) return 0; mask = ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL; this->reactor ()->remove_handler (this, mask); this->sock_.close (); this->output_queue_.flush (); delete this; return 0; } // Listing 10 // Listing 12 code/ch07 class LoopStopper : public ACE_Event_Handler { public: LoopStopper (int signum = SIGINT); // Called when object is signaled by OS. virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); }; LoopStopper::LoopStopper (int signum) { ACE_Reactor::instance ()->register_handler (signum, this); } int LoopStopper::handle_signal (int, siginfo_t *, ucontext_t *) { ACE_Reactor::instance ()->end_reactor_event_loop (); return 0; } // Listing 12 // Listing 13 code/ch07 #include "ace/Signal.h" class LogSwitcher : public ACE_Event_Handler { public: LogSwitcher (int on_sig, int off_sig); // Called when object is signaled by OS. virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); // Called when an exceptional event occurs. virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE); private: LogSwitcher () {} int on_sig_; // Signal to turn logging on int off_sig_; // Signal to turn logging off int on_off_; // 1 == turn on, 0 == turn off }; LogSwitcher::LogSwitcher (int on_sig, int off_sig) : on_sig_ (on_sig), off_sig_ (off_sig) { ACE_Sig_Set sigs; sigs.sig_add (on_sig); sigs.sig_add (off_sig); ACE_Reactor::instance ()->register_handler (sigs, this); } // Listing 13 // Listing 14 code/ch07 int LogSwitcher::handle_signal (int signum, siginfo_t *, ucontext_t *) { if (signum == this->on_sig_ || signum == this->off_sig_) { this->on_off_ = signum == this->on_sig_; ACE_Reactor::instance ()->notify (this); } return 0; } // Listing 14 // Listing 15 code/ch07 int LogSwitcher::handle_exception (ACE_HANDLE) { if (this->on_off_) ACE_LOG_MSG->clr_flags (ACE_Log_Msg::SILENT); else ACE_LOG_MSG->set_flags (ACE_Log_Msg::SILENT); return 0; } // Listing 15 // Listing 11 code/ch07 int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_INET_Addr port_to_listen ("HAStatus"); ClientAcceptor acceptor; acceptor.reactor (ACE_Reactor::instance ()); if (acceptor.open (port_to_listen) == -1) return 1; ACE_Reactor::instance ()->run_reactor_event_loop (); return (0); } // Listing 11
[править] Reschedule
/** * $Id: Reschedule.cpp 80826 2008-03-04 14:51:23Z wotte $ * * Changing the interval */ #include "ace/OS_NS_time.h" #include "ace/Log_Msg.h" #include "ace/Reactor.h" #include "ace/Event_Handler.h" class MyTimerHandler : public ACE_Event_Handler { public: int handle_timeout (const ACE_Time_Value ¤t_time, const void * = 0 ) { time_t epoch = ((timespec_t)current_time).tv_sec; ACE_DEBUG ((LM_INFO, ACE_TEXT ("handle_timeout: %s"), ACE_OS::ctime(&epoch))); return 0; } }; // Listing 1 code/ch07 class SigintHandler : public ACE_Event_Handler { public: SigintHandler (long timerId, int currentInterval) : ACE_Event_Handler(), timerId_(timerId), currentInterval_(currentInterval) { } int handle_signal (int, siginfo_t * = 0, ucontext_t * = 0) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("Resetting interval of timer ") ACE_TEXT ("%d to %d\n"), this->timerId_, ++this->currentInterval_)); ACE_Time_Value newInterval (this->currentInterval_); ACE_Reactor::instance()-> reset_timer_interval (this->timerId_, newInterval); return 0; } private: long timerId_; int currentInterval_; }; // Listing 1 int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_Time_Value initialDelay (3); ACE_Time_Value interval (5); // Listing 2 code/ch07 MyTimerHandler *handler = new MyTimerHandler (); long timerId = ACE_Reactor::instance ()->schedule_timer (handler, 0, initialDelay, interval); // Listing 2 // Listing 3 code/ch07 SigintHandler *handleSigint = new SigintHandler (timerId, 5); ACE_Reactor::instance ()->register_handler (SIGINT, handleSigint); // Listing 3 ACE_Reactor::instance ()->run_reactor_event_loop (); return 0; }
[править] Schedule Timers
/** * $Id: Schedule_Timers.cpp 80826 2008-03-04 14:51:23Z wotte $ * * Scheduling timers with the Reactor */ #include "ace/OS_NS_time.h" #include "ace/Log_Msg.h" #include "ace/Reactor.h" #include "ace/Event_Handler.h" // Listing 1 code/ch07 class MyTimerHandler : public ACE_Event_Handler { public: int handle_timeout (const ACE_Time_Value ¤t_time, const void * = 0) { time_t epoch = ((timespec_t)current_time).tv_sec; ACE_DEBUG ((LM_INFO, ACE_TEXT ("handle_timeout: %s\n"), ACE_OS::ctime (&epoch))); return 0; } }; // Listing 1 // Create a SIGINT handler so that we can exit // the program politely class SigintHandler : public ACE_Event_Handler { public: int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0) { if (signum == SIGINT) { ACE_Reactor::instance ()->end_reactor_event_loop (); } return 0; } }; int ACE_TMAIN (int, ACE_TCHAR *[]) { // Listing 2 code/ch07 MyTimerHandler * timer = new MyTimerHandler (); ACE_Time_Value initialDelay (3); ACE_Time_Value interval (5); ACE_Reactor::instance()->schedule_timer (timer, 0, initialDelay, interval); // Listing 2 // Exclude 1 SigintHandler * handleExit = new SigintHandler (); ACE_Reactor::instance()->register_handler (SIGINT, handleExit); // Exclude 1 ACE_Reactor::instance ()->run_reactor_event_loop (); return 0; }
[править] Timer Cancel
/** * $Id: Timer_Cancel.cpp 80826 2008-03-04 14:51:23Z wotte $ * * Changing the interval and canceling */ #include "ace/OS_NS_time.h" #include "ace/Log_Msg.h" #include "ace/Reactor.h" #include "ace/Event_Handler.h" class MyTimerHandler : public ACE_Event_Handler { public: int handle_timeout (const ACE_Time_Value ¤t_time, const void * = 0) { time_t epoch = ((timespec_t)current_time).tv_sec; ACE_DEBUG ((LM_INFO, ACE_TEXT ("handle_timeout: %s"), ACE_OS::ctime(&epoch))); return 0; } }; #if !defined (ACE_LACKS_UNIX_SIGNALS) // Listing 1 code/ch07 class SignalHandler : public ACE_Event_Handler { public: SignalHandler (long timerId, int currentInterval) : ACE_Event_Handler(), timerId_(timerId), currentInterval_(currentInterval) { } int handle_signal (int sig, siginfo_t * = 0, ucontext_t * = 0) { if (sig == SIGINT) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("Resetting interval of timer ") ACE_TEXT ("%d to %d\n"), this->timerId_, ++this->currentInterval_)); ACE_Time_Value newInterval (this->currentInterval_); ACE_Reactor::instance ()-> reset_timer_interval (this->timerId_, newInterval); } else if (sig == SIGTSTP) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("Canceling timer %d\n"), this->timerId_)); ACE_Reactor::instance ()->cancel_timer (this->timerId_); } return 0; } private: long timerId_; int currentInterval_; }; // Listing 1 #endif /* ACE_LACKS_UNIX_SIGNALS */ int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_Time_Value initialDelay (3); ACE_Time_Value interval (5); // Listing 2 code/ch07 MyTimerHandler *handler = new MyTimerHandler (); long timerId = ACE_Reactor::instance ()->schedule_timer (handler, 0, initialDelay, interval); // Listing 2 #if !defined (ACE_LACKS_UNIX_SIGNALS) // Listing 3 code/ch07 SignalHandler *mutateTimer = new SignalHandler (timerId, 5); ACE_Reactor::instance ()->register_handler (SIGINT, mutateTimer); ACE_Reactor::instance ()->register_handler (SIGTSTP, mutateTimer); // Listing 3 #else ACE_UNUSED_ARG (timerId); #endif /* ACE_LACKS_UNIX_SIGNALS */ ACE_Reactor::instance ()->run_reactor_event_loop (); return 0; }
[править] Timer State Data
/** * $Id: Timer_State_Data.cpp 91813 2010-09-17 07:52:52Z johnnyw $ * * Reactor examples * * Timers & state data */ #include "ace/OS_NS_time.h" #include "ace/Log_Msg.h" #include "ace/Reactor.h" #include "ace/Event_Handler.h" // Listing 0 code/ch07 class TemperatureSensor { public: TemperatureSensor (const char *location) : location_(location), count_(0), temperature_(0.0) // ... { } const char *location () const { return this->location_; } int querySensor (void) { // ... return ++this->count_; } float temperature (void) const { return this->temperature_; } private: const char *location_; int count_; float temperature_; // ... }; // Listing 0 // Listing 1 code/ch07 class TemperatureQueryHandler : public ACE_Event_Handler { public: TemperatureQueryHandler () : ACE_Event_Handler(), counter_(0), averageTemperature_(0.0) // ... { } int handle_timeout (const ACE_Time_Value ¤t_time, const void *arg) { time_t epoch = ((timespec_t)current_time).tv_sec; const TemperatureSensor *const_sensor = reinterpret_cast<const TemperatureSensor *> (arg); TemperatureSensor *sensor = const_cast<TemperatureSensor *> (const_sensor); int queryCount = sensor->querySensor (); this->updateAverageTemperature (sensor); ACE_DEBUG ((LM_INFO, ACE_TEXT ("%s\t") ACE_TEXT ("%d/%d\t") ACE_TEXT ("%.2f/%.2f\t") ACE_TEXT ("%s\n"), sensor->location (), ++this->counter_, queryCount, this->averageTemperature_, sensor->temperature (), ACE_OS::ctime(&epoch))); return 0; } private: void updateAverageTemperature (TemperatureSensor *) { // ... } int counter_; float averageTemperature_; }; // Listing 1 // Create a SIGINT handler so that we can exit // the program politely class SigintHandler : public ACE_Event_Handler { public: int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0) { if (signum == SIGINT) { ACE_Reactor::instance ()->end_reactor_event_loop (); } return 0; } }; int ACE_TMAIN (int, ACE_TCHAR *[]) { // Listing 2 code/ch07 TemperatureQueryHandler *temperatureMonitor = new TemperatureQueryHandler (); // Listing 2 ACE_Time_Value initialDelay (3); ACE_Time_Value intervalOne (5); // Listing 3 code/ch07 TemperatureSensor *sensorOne = new TemperatureSensor ("Kitchen"); ACE_Reactor::instance ()->schedule_timer (temperatureMonitor, sensorOne, initialDelay, intervalOne); // Listing 3 ACE_Time_Value intervalTwo (4); // Listing 4 code/ch07 TemperatureSensor *sensorTwo = new TemperatureSensor ("Foyer"); ACE_Reactor::instance ()->schedule_timer (temperatureMonitor, sensorTwo, initialDelay, intervalTwo); // Listing 4 SigintHandler *handleExit = new SigintHandler (); ACE_Reactor::instance ()->register_handler (SIGINT, handleExit); ACE_Reactor::instance ()->run_reactor_event_loop (); return 0; }
[править] Timers
// $Id: Timers.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/config-all.h" #include "ace/OS_main.h" #if !defined (ACE_LACKS_FORK) #include "ace/streams.h" #include "ace/OS_NS_unistd.h" #include "ace/OS_NS_time.h" #include "ace/OS_NS_signal.h" typedef void (*timerTask_t)(void); // Listing 1 code/ch07 pid_t timerTask (int initialDelay, int interval, timerTask_t task) { if (initialDelay < 1 && interval < 1) return -1; pid_t pid = ACE_OS::fork (); if (pid < 0) return -1; if (pid > 0) return pid; if (initialDelay > 0) ACE_OS::sleep (initialDelay); if (interval < 1) return 0; while (1) { (*task) (); ACE_OS::sleep (interval); } ACE_NOTREACHED (return 0); } // Listing 1 // Listing 2 code/ch07 void foo () { time_t now = ACE_OS::time (0); cerr << "The time is " << ACE_OS::ctime (&now) << endl; } // Listing 2 void programMainLoop (void) { ACE_OS::sleep (30); } // Listing 3 code/ch07 int ACE_TMAIN (int, ACE_TCHAR *[]) { pid_t timerId = timerTask (3, 5, foo); programMainLoop (); ACE_OS::kill (timerId, SIGINT); return 0; } // Listing 3 #else #include "ace/OS_NS_stdio.h" int ACE_TMAIN (int, ACE_TCHAR *[]) { //FUZZ: disable check_for_lack_ACE_OS ACE_OS::puts ("This very unportable example requires fork().\n"); //FUZZ: enable check_for_lack_ACE_OS return 0; } #endif /* ACE_LACKS_FORK */