diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
commit | a5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch) | |
tree | bcf0a25c3d45a209a6e3ac37b233a4812f29c732 /ace/Svc_Handler.cpp | |
download | ATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz |
Initial revision
Diffstat (limited to 'ace/Svc_Handler.cpp')
-rw-r--r-- | ace/Svc_Handler.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/ace/Svc_Handler.cpp b/ace/Svc_Handler.cpp new file mode 100644 index 00000000000..499fb44ab56 --- /dev/null +++ b/ace/Svc_Handler.cpp @@ -0,0 +1,282 @@ +// Svc_Handler.cpp +// $Id$ + +#if !defined (ACE_SVC_HANDLER_C) +#define ACE_SVC_HANDLER_C + +#define ACE_BUILD_DLL +#include "ace/Svc_Handler.h" +#include "ace/Log_Msg.h" +#include "ace/Dynamic.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Svc_Handler.i" +#endif /* __ACE_INLINE__ */ + +#define PR_ST_1 ACE_PEER_STREAM_1 +#define PR_ST_2 ACE_PEER_STREAM_2 + +#if defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Lock the creation of the Singleton. +template <PR_ST_1, ACE_SYNCH_1> +ACE_Thread_Mutex ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ace_svc_handler_lock_; +#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +template <PR_ST_1, ACE_SYNCH_1> ACE_Dynamic * +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::instance (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::allocated"); + +#if defined (ACE_MT_SAFE) && defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Lock the creation of the Singleton. This should be inside of + // ACE_Svc_Handler, but GNU G++ is too lame to handle this... + static ACE_Thread_Mutex ace_svc_handler_lock_; +#endif /* defined (ACE_MT_SAFE) && defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + + static ACE_TSS_TYPE (ACE_Dynamic) *instance_; + // Determines if we were dynamically allocated. Note that this + // should be inside of ACE_Svc_Handler, but G++ is too lame to + // support this... + + // Implement the Double Check pattern. + + if (instance_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ace_svc_handler_lock_, 0)); + + if (instance_ == 0) + ACE_NEW_RETURN (instance_, ACE_TSS_TYPE (ACE_Dynamic), 0); + } + + return ACE_TSS_GET (instance_, ACE_Dynamic); +} + +template <PR_ST_1, ACE_SYNCH_1> void * +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator new (size_t n) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator new"); + // Allocate the memory and store it (usually in thread-specific + // storage, depending on config flags). + return ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_2>::instance ()->set (::new char[n]); +} + +template <PR_ST_1, ACE_SYNCH_1> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::destroy (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::destroy"); + + // Only delete ourselves if we've been allocated dynamically. + if (this->dynamic_) + // Will call the destructor, which automatically calls <shutdown>. + // Note that if we are *not* allocated dynamically then the + // destructor will call <shutdown> automatically when it gets run + // during cleanup. + delete this; +} + +template <PR_ST_1, ACE_SYNCH_1> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator delete (void *obj) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::delete"); + ::delete obj; +} + +/* Default constructor */ + +template <PR_ST_1, ACE_SYNCH_1> +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler (ACE_Thread_Manager *tm, + ACE_Message_Queue<ACE_SYNCH_2> *mq, + ACE_Reactor *reactor) + : ACE_Task<ACE_SYNCH_2> (tm, mq), + reactor_ (reactor) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler"); + + // This clever idiom transparently checks if we were allocated + // dynamically. This information is used by the <destroy> method to + // decide if we need to delete <this>... The idiom is based on a + // paper by Michael van Rooyen (mrooyen@cellnet.co.uk) that appeared + // in the April '96 issue of the C++ Report. We've spruced it up to + // work correctly in multi-threaded programs by using our ACE_TSS + // class. + this->dynamic_ = ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_2>::instance()->is_dynamic (this); +} + +// Default behavior for a ACE_Svc_Handler object is to be registered with +// the ACE_Reactor (thereby ensuring single threading). + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::open (void *) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::open"); +#if defined (DEBUGGING) + char buf[BUFSIZ]; + ACE_PEER_STREAM_ADDR client_addr; + + if (this->peer_.get_remote_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + if (client_addr.addr_to_string (buf, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "can't obtain peer's address"), -1); + + ACE_DEBUG ((LM_DEBUG, "connected to %s on fd %d\n", + buf, this->peer_.get_handle ())); +#endif /* DEBUGGING */ + if (this->reactor_ + && this->reactor_->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", + "unable to register client handler"), -1); + return 0; +} + +// Perform termination activities. + +template <PR_ST_1, ACE_SYNCH_1> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::shutdown (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::shutdown"); + // Deregister this handler with the ACE_Reactor. + if (this->reactor_) + { + ACE_Reactor_Mask mask = ACE_Event_Handler::WRITE_MASK | + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::DONT_CALL; + + // Remove self from reactor. + this->reactor_->remove_handler (this, mask); + + // Make sure there are no timers. + this->reactor_->cancel_timer( this ); + + // Note the fact that the Reactor has shut down. + this->reactor_ = 0; + } + + this->peer ().close (); +} + +template <PR_ST_1, ACE_SYNCH_1> ACE_Reactor * +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor (void) const +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor"); + return this->reactor_; +} + +template <PR_ST_1, ACE_SYNCH_1> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor"); + this->reactor_ = r; +} + +template <PR_ST_1, ACE_SYNCH_1> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::dump (void) const +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::dump"); +} + +template <PR_ST_1, ACE_SYNCH_1> ACE_INLINE ACE_PEER_STREAM & +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::peer (void) const +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::peer"); + return (PEER_STREAM &) this->peer_; +} + +// Extract the underlying PEER_STREAM (e.g., used by ACE_Connector and +// ACE_Acceptor). + +template <PR_ST_1, ACE_SYNCH_1> +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator ACE_PEER_STREAM &() +{ + return this->peer_; +} + +/* Extract the underlying I/O descriptor. */ + +template <PR_ST_1, ACE_SYNCH_1> ACE_HANDLE +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::get_handle (void) const +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::get_handle"); + return this->peer_.get_handle (); +} + +/* Set the underlying I/O descriptor. */ + +template <PR_ST_1, ACE_SYNCH_1> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::set_handle"); + this->peer_.set_handle (h); +} + +template <PR_ST_1, ACE_SYNCH_1> +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::~ACE_Svc_Handler (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::~ACE_Svc_Handler"); + this->shutdown (); +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_close"); + + this->destroy (); + return 0; +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_timeout (const ACE_Time_Value &, + const void *) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_timeout"); + return this->handle_close (); +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::close (unsigned long) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::close"); + return this->handle_close (); +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::svc (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::svc"); + return -1; +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::put (ACE_Message_Block *, + ACE_Time_Value *) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::put"); + return -1; +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::init (int, char *[]) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::init"); + return -1; +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::fini (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::fini"); + return -1; +} + +template <PR_ST_1, ACE_SYNCH_1> int +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::info (char **, size_t) const +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::info"); + return -1; +} +#undef PR_ST_1 +#undef PR_ST_2 +#endif /* ACE_SVC_HANDLER_C */ |