#include "ace/Acceptor.h" #include "ace/SOCK_Acceptor.h" #include "ace/Reactor.h" #include "ace/Thread.h" ACE_Reactor * g_reactor; static sig_atomic_t finished = 0; class Logging_Handler; extern "C" void handler (int) { finished = 1; } class Reactor_Derived : public ACE_Reactor { public : Reactor_Derived() : () { counter = 0; } virtual ~Reactor_Derived() { cout << "*****Calling the reactor destructor*****" << endl; } private : friend class Logging_Handler; // counter is used to keep track of the number of service handlers // registered with this reactor (Surely theres a better way ;-) int counter; }; class Logging_Handler : public ACE_Svc_Handler { public: Logging_Handler (void) { }; virtual void destroy (void) { if (this->thread_reactorP->remove_handler(this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL) == -1 ) ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t remove service from reactor\n"), -1); // Decrement the handler tracking variable in the reactor to // indicate this service handler has terminated --thread_reactorP->counter; this->peer ().close (); delete this; } static void *run_thread(Logging_Handler *this_) { Reactor_Derived thread_reactor; this_->thread_reactorP = &thread_reactor; // Increment our handler counter to account for this service handler ++thread_reactor.counter; if (thread_reactor.register_handler(this_, ACE_Event_Handler::READ_MASK) == -1) ACE_ERROR_RETURN ((LM_ERROR,"can'(%P|%t) t register with reactor\n"), -1); while( thread_reactor.counter > 0 ) { // If thread_reactor.counter = 0 then we have no more service // handlers connected to the reactor. We set a timeout value // of 1 second so that the handle_events loop break out every // second to check on the count ( because of it blocking // even when there are no connections we need to do this) thread_reactor.handle_events(ACE_Time_Value(1,0)); } } virtual int open (void *) { ACE_Thread::spawn(&Logging_Handler::run_thread,this); return 0; } virtual int close (u_long) { this->destroy (); return 0; } protected: virtual int handle_input (ACE_HANDLE) { char buf[128]; memset(buf,0,sizeof(buf)); switch( this->peer().recv(buf,sizeof buf) ) { case -1: ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); case 0: ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1); default: ACE_DEBUG ((LM_DEBUG, "(%p|%t) from client : %s",buf)); } return 0; } private: Reactor_Derived *thread_reactorP; }; typedef ACE_Acceptor Logging_Acceptor; static const u_short PORT = ACE_DEFAULT_SERVER_PORT; int main (int argc, char *argv[]) { g_reactor = new ACE_Reactor; // Acceptor factory. Logging_Acceptor peer_acceptor; if (peer_acceptor.open (ACE_INET_Addr (PORT)) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); else if (g_reactor->register_handler (&peer_acceptor, ACE_Event_Handler::READ_MASK) == -1) ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); // Run forever, performing logging service. ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); // Perform logging service until QUIT_HANDLER receives SIGINT. while ( !finished ) g_reactor->handle_events (); ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); return 0; }