diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-01-01 08:00:34 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-01-01 08:00:34 +0000 |
commit | ea0d28240863caf437a18071bfd03e7b146c5ade (patch) | |
tree | 91b695852b885a5f44f9be8c3a22bbf7f5a96b8d /ace | |
parent | a6e2ced2f5279e011b712995095a1712a29e22f0 (diff) | |
download | ATCD-ea0d28240863caf437a18071bfd03e7b146c5ade.tar.gz |
foo
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Acceptor.h | 7 | ||||
-rw-r--r-- | ace/Connector.cpp | 2 | ||||
-rw-r--r-- | ace/Connector.h | 2 | ||||
-rw-r--r-- | ace/Event_Handler.h | 4 | ||||
-rw-r--r-- | ace/Log_Msg.cpp | 8 | ||||
-rw-r--r-- | ace/Message_Block.cpp | 102 | ||||
-rw-r--r-- | ace/Message_Block.h | 81 | ||||
-rw-r--r-- | ace/Message_Block.i | 16 | ||||
-rw-r--r-- | ace/Reactor.cpp | 8 | ||||
-rw-r--r-- | ace/SOCK_Acceptor.h | 1 | ||||
-rw-r--r-- | ace/Svc_Handler.h | 2 | ||||
-rw-r--r-- | ace/Synch.h | 162 | ||||
-rw-r--r-- | ace/Synch.i | 80 | ||||
-rw-r--r-- | ace/Synch_T.h | 51 | ||||
-rw-r--r-- | ace/Synch_T.i | 68 |
15 files changed, 509 insertions, 85 deletions
diff --git a/ace/Acceptor.h b/ace/Acceptor.h index 7071af03800..feca8eb7d2f 100644 --- a/ace/Acceptor.h +++ b/ace/Acceptor.h @@ -1,7 +1,6 @@ /* -*- C++ -*- */ // $Id$ - // ============================================================================ // // = LIBRARY @@ -109,7 +108,7 @@ protected: // = Demultiplexing hooks. virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); // Perform termination activities when <this> is removed from the // <reactor>. @@ -252,7 +251,7 @@ protected: // Returns the listening acceptor's <ACE_HANDLE>. virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); // Perform termination activities when <this> is removed from the // <Reactor>. @@ -397,7 +396,7 @@ protected: // Returns the listening acceptor's <ACE_HANDLE>. virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); // Perform termination activities when <this> is removed from the // <reactor>. diff --git a/ace/Connector.cpp b/ace/Connector.cpp index 0cace4e72c3..03fa643dfc8 100644 --- a/ace/Connector.cpp +++ b/ace/Connector.cpp @@ -268,7 +268,7 @@ ACE_Connector<SH, PR_CO_2>::cleanup_AST (ACE_HANDLE handle, this->reactor_->cancel_timer (ast->cancellation_id ()); // Remove ACE_HANDLE from ACE_Reactor. - this->reactor_->remove_handler (handle, ACE_Event_Handler::RWE_MASK + this->reactor_->remove_handler (handle, ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL); // Remove ACE_HANDLE from the map. diff --git a/ace/Connector.h b/ace/Connector.h index 8d9e7d44a5c..02a193621b4 100644 --- a/ace/Connector.h +++ b/ace/Connector.h @@ -222,7 +222,7 @@ protected: // = Demultiplexing hooks. virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); // Terminate the Client ACE_Connector by iterating over any // unconnected ACE_Svc_Handler's and removing them from the // ACE_Reactor. diff --git a/ace/Event_Handler.h b/ace/Event_Handler.h index 07140a82ad6..f414d930ed4 100644 --- a/ace/Event_Handler.h +++ b/ace/Event_Handler.h @@ -54,8 +54,8 @@ public: EXCEPT_MASK = 0x2, #endif /* ACE_USE_POLL */ ACCEPT_MASK = 0x8, - ALL_MASK = READ_MASK | WRITE_MASK | EXCEPT_MASK | ACCEPT_MASK, - RWE_MASK = ALL_MASK, + ALL_EVENTS_MASK = READ_MASK | WRITE_MASK | EXCEPT_MASK | ACCEPT_MASK, + RWE_MASK = ALL_EVENTS_MASK, DONT_CALL = 0x100 }; diff --git a/ace/Log_Msg.cpp b/ace/Log_Msg.cpp index e0bbef3abfe..8c509eee15d 100644 --- a/ace/Log_Msg.cpp +++ b/ace/Log_Msg.cpp @@ -690,9 +690,11 @@ ACE_Log_Msg::log (const char *format_str, if (abort_prog) { - // _always_ print a message to stderr if aborting, not verbose - // to help avoid recursive aborts if something is hosed - log_record.print (ACE_Log_Msg::local_host_, 0); + // *always* print a message to stderr if we're aborting (and + // have not already done so). We don't use verbose, however, to + // avoid recursive aborts if something is hosed. + if (!ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR)) + log_record.print (ACE_Log_Msg::local_host_, 0); ACE_OS::exit (exit_value); } diff --git a/ace/Message_Block.cpp b/ace/Message_Block.cpp index 9f9503ef429..d58e13a8c03 100644 --- a/ace/Message_Block.cpp +++ b/ace/Message_Block.cpp @@ -80,7 +80,10 @@ ACE_Message_Block::ACE_Message_Block (void) cont_ (0), next_ (0), prev_ (0), - allocator_ (0) + allocator_strategy_ (0), + locking_strategy_ (0), + reference_count_ (1) + { ACE_TRACE ("ACE_Message_Block::ACE_Message_Block"); } @@ -89,20 +92,24 @@ ACE_Message_Block::ACE_Message_Block (size_t sz, ACE_Message_Type msg_type, ACE_Message_Block *msg_cont, const char *msg_data, - ACE_Allocator *alloc) + ACE_Allocator *allocator_strategy, + ACE_Lock *locking_strategy) { ACE_TRACE ("ACE_Message_Block::ACE_Message_Block"); - if (this->init (sz, msg_type, msg_cont, msg_data, alloc) == -1) + + if (this->init (sz, msg_type, msg_cont, msg_data, + allocator_strategy, locking_strategy) == -1) ACE_ERROR ((LM_ERROR, "ACE_Message_Block")); } ACE_Message_Block::~ACE_Message_Block (void) { ACE_TRACE ("ACE_Message_Block::~ACE_Message_Block"); + if (ACE_BIT_DISABLED (this->flags_, ACE_Message_Block::DONT_DELETE)) { - if (this->allocator_) - this->allocator_->free ((void *) this->base_); + if (this->allocator_strategy_) + this->allocator_strategy_->free ((void *) this->base_); else delete [] this->base_; } @@ -125,7 +132,9 @@ ACE_Message_Block::ACE_Message_Block (const char *data, cont_ (0), next_ (0), prev_ (0), - allocator_ (0) + allocator_strategy_ (0), + locking_strategy_ (0), + reference_count_ (1) { ACE_TRACE ("ACE_Message_Block::ACE_Message_Block"); } @@ -134,6 +143,7 @@ int ACE_Message_Block::size (size_t length) { ACE_TRACE ("ACE_Message_Block::size"); + if (length < this->max_size_) this->cur_size_ = length; else @@ -141,11 +151,11 @@ ACE_Message_Block::size (size_t length) int r_delta, w_delta; char *buf; - if (this->allocator_ == 0) + if (this->allocator_strategy_ == 0) ACE_NEW_RETURN (buf, char[length], -1); else // Use the allocator! { - buf = (char *) this->allocator_->malloc (length); + buf = (char *) this->allocator_strategy_->malloc (length); if (buf == 0) { errno = ENOMEM; @@ -155,8 +165,8 @@ ACE_Message_Block::size (size_t length) if (ACE_BIT_DISABLED (this->flags_, ACE_Message_Block::DONT_DELETE)) { - if (this->allocator_) - this->allocator_->free ((void *) this->base_); + if (this->allocator_strategy_) + this->allocator_strategy_->free ((void *) this->base_); else delete [] this->base_; } @@ -183,6 +193,7 @@ ACE_Message_Block::init (const char *data, size_t size) { ACE_TRACE ("ACE_Message_Block::init"); + // Should we also initialize all the other fields, as well? this->base_ = (char *) data; this->cur_size_ = size; this->max_size_ = size; @@ -195,22 +206,23 @@ ACE_Message_Block::init (size_t sz, ACE_Message_Type msg_type, ACE_Message_Block *msg_cont, const char *msg_data, - ACE_Allocator *alloc) + ACE_Allocator *allocator_strategy, + ACE_Lock *locking_strategy) { ACE_TRACE ("ACE_Message_Block::init"); this->flags_ = 0; if (msg_data == 0) { - if (alloc == 0) + if (allocator_strategy == 0) { - this->allocator_ = 0; + this->allocator_strategy_ = 0; ACE_NEW_RETURN (this->base_, char[sz], -1); } else // Use the allocator! { - this->allocator_ = alloc; - this->base_ = (char *) alloc->malloc (sz); + this->allocator_strategy_ = allocator_strategy; + this->base_ = (char *) this->allocator_strategy_->malloc (sz); if (this->base_ == 0) { errno = ENOMEM; @@ -233,6 +245,8 @@ ACE_Message_Block::init (size_t sz, this->cont_ = msg_cont; this->next_ = 0; this->prev_ = 0; + this->locking_strategy_ = locking_strategy; + this->reference_count_ = 1; return 0; } @@ -248,7 +262,7 @@ ACE_Message_Block::clone (Message_Flags mask) const ACE_NEW_RETURN (nb, ACE_Message_Block (this->max_size_, this->type_, - 0, 0, this->allocator_), + 0, 0, this->allocator_strategy_), 0); ACE_OS::memcpy (nb->base_, this->base_, this->max_size_); @@ -264,3 +278,59 @@ ACE_Message_Block::clone (Message_Flags mask) const nb->cont_ = this->cont_->clone (mask); return nb; } + +ACE_Message_Block * +ACE_Message_Block::release (void) +{ + ACE_TRACE ("ACE_Message_Block::release"); + + ACE_Message_Block *result = 0; + + if (this->locking_strategy_) + { + // We need to acquire the lock before decrementing the count. + this->locking_strategy_->acquire (); + this->reference_count_--; + + if (this->reference_count_ == 0) + delete this; + else if (this->reference_count_ > 0) + result = this; + // ACE_ASSERT (this->reference_count_ <= 0) + // This shouldn't happen... + + this->locking_strategy_->release (); + } + else + { + this->reference_count_--; + + if (this->reference_count_ == 0) + delete this; + else if (this->reference_count_ > 0) + result = this; + // ACE_ASSERT (this->reference_count_ <= 0) + // This shouldn't happen... + } + + return result; +} + +ACE_INLINE ACE_Message_Block * +ACE_Message_Block::duplicate (void) +{ + ACE_TRACE ("ACE_Message_Block::duplicate"); + + if (this->locking_strategy_) + { + // We need to acquire the lock before incrementing the count. + this->locking_strategy_->acquire (); + this->reference_count_++; + this->locking_strategy_->release (); + } + else + this->reference_count_++; + + return this; +} + diff --git a/ace/Message_Block.h b/ace/Message_Block.h index 599e1039813..30852f4dc8c 100644 --- a/ace/Message_Block.h +++ b/ace/Message_Block.h @@ -23,17 +23,21 @@ class ACE_Export ACE_Message_Block // = TITLE - // Object used to store messages in the ASX framework. + // Stores messages for use throughout ACE (particularly + // <ACE_Message_Queue>). // // = DESCRIPTION - // An ACE_Message_Block is modeled after the message data - // structures used in System V STREAMS. A Message_Block is - // composed of one or more Message_Blocks that are linked - // together by PREV and NEXT pointers. In addition, a - // ACE_Message_Block may also be linked to a chain of other - // Message_Blocks. This structure enables efficient + // An <ACE_Message_Block> is modeled after the message data + // structures used in System V STREAMS. An <ACE_Message_Block> + // is composed of one or more <ACE_Message_Blocks> that can be + // linked to form a ``fragment chain.'' In addition, + // <ACE_Message_Blocks> can be linked together by <prev_> and + // <next_> pointers to form a queue of messages (this is how + // <ACE_Message_Queue> works). This structure enables efficient // manipulation of arbitrarily-large messages *without* - // incurring memory copying overhead. + // incurring memory copying overhead since (1) + // <ACE_Message_Blocks> can be chained together via pointers and + // (2) <ACE_Message_Blocks> keep a reference count. { public: enum ACE_Message_Type @@ -90,13 +94,16 @@ public: ACE_Message_Type type = MB_DATA, ACE_Message_Block *cont = 0, const char *data = 0, - ACE_Allocator *allocator = 0); + ACE_Allocator *allocator_strategy_ = 0, + ACE_Lock *locking_strategy = 0); // Create an initialized message of type <type> containing <size> // bytes. The <cont> argument initializes the continuation field in // the <Message_Block>. If <data> == 0 then we create and own the // <data>, using <allocator> to get the data if it's non-0. If // <data> != 0 we assume ownership of the <data> (and don't delete - // it). + // it). If <locking_strategy> is non-0 then this is used to protect + // regions of code that access shared state (e.g., reference + // counting) from race conditions. int init (const char *data, size_t size = 0); @@ -107,13 +114,16 @@ public: ACE_Message_Type type = MB_DATA, ACE_Message_Block *cont = 0, const char *data = 0, - ACE_Allocator *allocator = 0); + ACE_Allocator *allocator = 0, + ACE_Lock *locking_strategy = 0); // Create an initialized message of type <type> containing <size> // bytes. The <cont> argument initializes the continuation field in // the <Message_Block>. If <data> == 0 then we create and own the // <data>, using <allocator> to get the data if it's non-0. If // <data> != 0 we assume ownership of the <data> (and don't delete - // it). + // it). If <locking_strategy> is non-0 then this is used to protect + // regions of code that access shared state (e.g., reference + // counting) from race conditions. ~ACE_Message_Block (void); // Delete all the resources held in the message. @@ -145,6 +155,16 @@ public: ACE_Message_Block *clone (Message_Flags mask = ACE_Message_Block::DONT_DELETE) const; // Return an exact "deep copy" of the message. + // = Reference counting methods. + ACE_Message_Block *duplicate (void); + // Increment our reference count by one. + + ACE_Message_Block *release (void); + // Decrement our reference count by one. If the reference count is + // > 0 then return this; else if reference count == 0 then delete + // <this> and return 0. Behavior is undefined if reference count < + // 0. + // = Operations on Message data int copy (const char *buf, size_t n); @@ -160,7 +180,9 @@ public: char *base (void) const; // Get message data. - void base (char *data, size_t size, Message_Flags = DONT_DELETE); + void base (char *data, + size_t size, + Message_Flags = DONT_DELETE); // Set message data. char *end (void) const; @@ -180,42 +202,43 @@ public: void wr_ptr (size_t n); // Set the write pointer ahead <n> bytes. - // = The length of a message is computed as the length between the - // wr_ptr() - rd_ptr ()). + // = Message length is wr_ptr() - rd_ptr (). size_t length (void) const; // Get the length of the message void length (size_t n); // Set the length of the message - // = The size of the allocated buffer is the total amount of space - // alloted. + // = Message size is the total amount of space alloted. size_t size (void) const; // Get the total amount of space in the message. int size (size_t length); // Set the total amount of space in the message. Returns 0 if // successful, else -1. - // = The coninuation field is used to chain together composite - // messages. + // = The continuation field chains together composite messages. ACE_Message_Block *cont (void) const; // Get the continuation field. void cont (ACE_Message_Block *); // Set the continuation field. - // = The <next_> pointer points to the <Message_Block> directly ahead - // in the Message_Queue. + // = The <next_> pointer is a link to the <Message_Block> directly ahead in the Message_Queue. ACE_Message_Block *next (void) const; // Get link to next message. void next (ACE_Message_Block *); // Set link to next message. - // = The <prev_> pointer points to the <Message_Block> directly - // ahead in the Message_Queue. + // = The <prev_> pointer is a link to the <Message_Block> directly ahead in the Message_Queue. ACE_Message_Block *prev (void) const; // Get link to prev message. void prev (ACE_Message_Block *); // Set link to prev message. + // = The locking strategy prevents race condition. + ACE_Lock *locking_strategy (void); + // Get the locking strategy. + ACE_Lock *locking_strategy (ACE_Lock *); + // Set a new locking strategy and return the hold one. + void dump (void) const; // Dump the state of an object. @@ -224,7 +247,7 @@ public: private: Message_Flags flags_; - // Misc flags. + // Misc flags (e.g., DONT_DELETE and USER_FLAGS). char *base_; // Pointer to beginning of message block. @@ -257,9 +280,17 @@ private: ACE_Message_Block *prev_; // Pointer to previous message in the list. - ACE_Allocator *allocator_; + ACE_Allocator *allocator_strategy_; // Pointer to the allocator defined for this message block. + ACE_Lock *locking_strategy_; + // Pointer to the locking defined for this message block. This is + // used to protect regions of code containing + + size_t reference_count_; + // Reference count for this <Message_Block> which is used to avoid + // deep copies (i.e., <clone>). + // = Disallow these operations for now (use <clone> instead). ACE_Message_Block &operator= (const ACE_Message_Block &); ACE_Message_Block (const ACE_Message_Block &); diff --git a/ace/Message_Block.i b/ace/Message_Block.i index eebe94937d6..72b4f42f67b 100644 --- a/ace/Message_Block.i +++ b/ace/Message_Block.i @@ -230,3 +230,19 @@ ACE_Message_Block::prev (void) const return this->prev_; } +ACE_INLINE ACE_Lock * +ACE_Message_Block::locking_strategy (void) +{ + ACE_TRACE ("ACE_Message_Block::locking_strategy"); + return this->locking_strategy_; +} + +ACE_INLINE ACE_Lock * +ACE_Message_Block::locking_strategy (ACE_Lock *nls) +{ + ACE_TRACE ("ACE_Message_Block::locking_strategy"); + ACE_Lock *ols = this->locking_strategy_; + this->locking_strategy_ = nls; + return ols; +} + diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp index 1a0a9d8377a..c7a629d028b 100644 --- a/ace/Reactor.cpp +++ b/ace/Reactor.cpp @@ -92,7 +92,7 @@ ACE_Handler_Repository::close (ACE_Reactor *reactor) i < this->cur_size_; i++) reactor->detach (this->event_handlers_[i].handle_, - ACE_Event_Handler::RWE_MASK); + ACE_Event_Handler::ALL_EVENTS_MASK); delete [] this->event_handlers_; this->event_handlers_ = 0; @@ -100,7 +100,7 @@ ACE_Handler_Repository::close (ACE_Reactor *reactor) for (ACE_HANDLE h = 0; h < this->max_handlep1_; h++) - reactor->detach (h, ACE_Event_Handler::RWE_MASK); + reactor->detach (h, ACE_Event_Handler::ALL_EVENTS_MASK); delete [] this->event_handlers_; this->event_handlers_ = 0; @@ -1591,7 +1591,7 @@ ACE_Reactor::check_handles (void) if (ACE_OS::poll (&p_handle, 1, 0) == -1) { result = 1; - this->detach (handle, ACE_Event_Handler::RWE_MASK); + this->detach (handle, ACE_Event_Handler::ALL_EVENTS_MASK); } #else rmask.set_bit (handle); @@ -1600,7 +1600,7 @@ ACE_Reactor::check_handles (void) &time_poll) < 0) { result = 1; - this->detach (handle, ACE_Event_Handler::RWE_MASK); + this->detach (handle, ACE_Event_Handler::ALL_EVENTS_MASK); } rmask.clr_bit (handle); #endif /* ACE_USE_POLL */ diff --git a/ace/SOCK_Acceptor.h b/ace/SOCK_Acceptor.h index fd3c2534a92..fed78c498ab 100644 --- a/ace/SOCK_Acceptor.h +++ b/ace/SOCK_Acceptor.h @@ -1,7 +1,6 @@ /* -*- C++ -*- */ // $Id$ - // ============================================================================ // // = LIBRARY diff --git a/ace/Svc_Handler.h b/ace/Svc_Handler.h index 1228ad0964a..89bf2d73d99 100644 --- a/ace/Svc_Handler.h +++ b/ace/Svc_Handler.h @@ -73,7 +73,7 @@ public: // = Demultiplexing hooks. virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); // Perform termination activities on the SVC_HANDLER. The default // behavior is to close down the <peer_> (to avoid descriptor leaks) // and to delete this (to avoid memory leaks)! If you don't want diff --git a/ace/Synch.h b/ace/Synch.h index 6d3e864d582..3a88bee5a32 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -29,6 +29,54 @@ class ACE_Time_Value; // template <class ACE_COND_MUTEX> class ACE_Condition; +class ACE_Lock + // = TITLE + // This is the abstract base class that contains the uniform + // locking API that is supported by all the ACE synchronization + // mechanisms. + // + // = DESCRIPTION + // This class is typically used in conjunction with the + // <ACE_Lock_Adapter> in order to provide a polymorphic + // interface to the ACE synchronization mechanisms (e.g., + // <ACE_Mutex>, <ACE_Semaphore>, <ACE_RW_Lock>, etc). Note that + // the reason that all of ACE doesn't use polymorphic locks is + // that (1) they add ~20% extra overhead for virtual function + // calls and (2) objects with virtual functions can't be placed + // into shared memory. +{ +public: + virtual int remove (void) = 0; + // Explicitly destroy the lock. + + virtual int acquire (void) = 0; + // Block the thread until the lock is acquired. + + virtual int tryacquire (void) = 0; + // Conditionally acquire the lock (i.e., won't block). + + virtual int release (void) = 0; + // Release the lock. + + virtual int acquire_read (void) = 0; + // Block until the thread acquires a read lock. If the locking + // mechanism doesn't support read locks then this just calls + // <acquire>. + + virtual int acquire_write (void) = 0; + // Block until the thread acquires a write lock. If the locking + // mechanism doesn't support read locks then this just calls + // <acquire>. + + virtual int tryacquire_read (void) = 0; + // Conditionally acquire a read lock. If the locking mechanism + // doesn't support read locks then this just calls <acquire>. + + virtual int tryacquire_write (void) = 0; + // Conditionally acquire a write lock. If the locking mechanism + // doesn't support read locks then this just calls <acquire>. +}; + class ACE_Export ACE_File_Lock // = TITLE // A wrapper around the UNIX file locking mechanism. @@ -111,12 +159,12 @@ class ACE_Export ACE_Semaphore { public: // = Initialization and termination. - ACE_Semaphore (u_int count, + ACE_Semaphore (u_int count = 1, // By default make this unlocked. int type = USYNC_THREAD, LPCTSTR name = 0, void * = 0, int max = 0x7fffffff); - // Initialize the semaphore, with default value of "count". + // Initialize the semaphore, with initial value of "count". ~ACE_Semaphore (void); // Implicitly destroy the semaphore. @@ -129,13 +177,33 @@ public: // greater than 0, then decrement it. int tryacquire (void); - // Conditionally decrement the semaphore if count is greater - // than 0 (i.e., won't block). + // Conditionally decrement the semaphore if count is greater than 0 + // (i.e., won't block). int release (void); // Increment the semaphore, potentially unblocking // a waiting thread. + int acquire_read (void); + // Acquire semaphore ownership. This calls <acquire> and is only + // here to make the <ACE_Semaphore> interface consistent with the + // other synchronization APIs. + + int acquire_write (void); + // Acquire semaphore ownership. This calls <acquire> and is only + // here to make the <ACE_Semaphore> interface consistent with the + // other synchronization APIs. + + int tryacquire_read (void); + // Conditionally acquire semaphore (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Semaphore> + // interface consistent with the other synchronization APIs. + + int tryacquire_write (void); + // Conditionally acquire semaphore (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Semaphore> + // interface consistent with the other synchronization APIs. + void dump (void) const; // Dump the state of an object. @@ -159,8 +227,10 @@ class ACE_Export ACE_Process_Semaphore // across processes. { public: - ACE_Process_Semaphore (u_int count, LPCTSTR name = 0, - void * = 0, int max = 0x7FFFFFFF); + ACE_Process_Semaphore (u_int count = 1, // By default make this unlocked. + LPCTSTR name = 0, + void * = 0, + int max = 0x7FFFFFFF); // Initialize the semaphore, with an initial value of <count> and a // maximum value of <max>. @@ -171,16 +241,35 @@ public: // Explicitly destroy the semaphore. int acquire (void); - // Block the thread until the semaphore count becomes - // greater than 0, then decrement it. + // Block the thread until the semaphore count becomes greater than + // 0, then decrement it. int tryacquire (void); - // Conditionally decrement the semaphore if count is greater - // than 0 (i.e., won't block). + // Conditionally decrement the semaphore if count is greater than 0 + // (i.e., won't block). int release (void); - // Increment the semaphore, potentially unblocking - // a waiting thread. + // Increment the semaphore, potentially unblocking a waiting thread. + + int acquire_read (void); + // Acquire semaphore ownership. This calls <acquire> and is only + // here to make the <ACE_Process_Semaphore> interface consistent + // with the other synchronization APIs. + + int acquire_write (void); + // Acquire semaphore ownership. This calls <acquire> and is only + // here to make the <ACE_Process_Semaphore> interface consistent + // with the other synchronization APIs. + + int tryacquire_read (void); + // Conditionally acquire semaphore (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Process_Semaphore> + // interface consistent with the other synchronization APIs. + + int tryacquire_write (void); + // Conditionally acquire semaphore (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Process_Semaphore> + // interface consistent with the other synchronization APIs. void dump (void) const; // Dump the state of an object. @@ -233,12 +322,12 @@ public: int acquire (void); // Note, for interface uniformity with other synchronization // wrappers we include the <acquire> method. This is implemented as - // a write-lock to be on the safe-side... + // a write-lock to safe... int tryacquire (void); // Note, for interface uniformity with other synchronization // wrappers we include the <tryacquire> method. This is implemented - // as a write-lock to be on the safe-side... + // as a write-lock to be safe... int release (void); // Unlock a readers/writer lock. @@ -263,8 +352,8 @@ private: class ACE_Export ACE_Mutex // = TITLE - // ACE_Mutex wrapper (valid in same process or across processes - // (depending on TYPE flag)) + // <ACE_Mutex> wrapper (valid in same process or across + // processes (depending on TYPE flag)). { public: ACE_Mutex (int type = USYNC_THREAD, @@ -288,16 +377,24 @@ public: // Release lock and unblock a thread at head of priority queue. int acquire_read (void); - // Acquire lock ownership (wait on priority queue if necessary). + // Acquire mutex ownership. This calls <acquire> and is only + // here to make the <ACE_Mutex> interface consistent with the + // other synchronization APIs. int acquire_write (void); - // Acquire lock ownership (wait on priority queue if necessary). + // Acquire mutex ownership. This calls <acquire> and is only + // here to make the <ACE_Mutex> interface consistent with the + // other synchronization APIs. int tryacquire_read (void); - // Conditionally acquire a lock (i.e., won't block). + // Conditionally acquire mutex (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Mutex> + // interface consistent with the other synchronization APIs. int tryacquire_write (void); - // Conditionally acquire a lock (i.e., won't block). + // Conditionally acquire mutex (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Mutex> + // interface consistent with the other synchronization APIs. const ACE_mutex_t &lock (void) const; // Return the underlying mutex. @@ -324,7 +421,8 @@ class ACE_Export ACE_Process_Mutex // processes). { public: - ACE_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, void *arg = 0); + ACE_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, + void *arg = 0); // Create a Process_Mutex, passing in the optional <name>. ~ACE_Process_Mutex (void); @@ -669,16 +767,24 @@ public: // Release lock and unblock a thread at head of priority queue. int acquire_read (void); - // Acquire lock ownership (wait on priority queue if necessary). + // Acquire mutex ownership. This calls <acquire> and is only here + // to make the <ACE_Thread_Mutex> interface consistent with the + // other synchronization APIs. int acquire_write (void); - // Acquire lock ownership (wait on priority queue if necessary). + // Acquire mutex ownership. This calls <acquire> and is only here + // to make the <ACE_Thread_Mutex> interface consistent with the + // other synchronization APIs. int tryacquire_read (void); - // Conditionally acquire a lock (i.e., won't block). + // Conditionally acquire mutex (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Thread_Mutex> + // interface consistent with the other synchronization APIs. int tryacquire_write (void); - // Conditionally acquire a lock (i.e., won't block). + // Conditionally acquire mutex (i.e., won't block). This calls + // <tryacquire> and is only here to make the <ACE_Thread_Mutex> + // interface consistent with the other synchronization APIs. const ACE_thread_mutex_t &lock (void) const; // Return the underlying mutex. @@ -912,8 +1018,10 @@ class ACE_Export ACE_Thread_Semaphore : public ACE_Semaphore // only within on process. { public: - ACE_Thread_Semaphore (u_int count, LPCTSTR name = 0, - void * = 0, int max = 0x7FFFFFFF); + ACE_Thread_Semaphore (u_int count = 1, // By default make this unlocked. + LPCTSTR name = 0, + void * = 0, + int max = 0x7FFFFFFF); // Initialize the semaphore, with an initial value of <count> and a // maximum value of <max>. diff --git a/ace/Synch.i b/ace/Synch.i index 3bc15d21e39..12b4260c4ef 100644 --- a/ace/Synch.i +++ b/ace/Synch.i @@ -235,6 +235,86 @@ ACE_Semaphore::release (void) return ACE_OS::sema_post (&this->semaphore_); } +// Acquire semaphore ownership. This calls <acquire> and is only +// here to make the <ACE_Semaphore> interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::acquire_read (void) +{ + return this->acquire (); +} + +// Acquire semaphore ownership. This calls <acquire> and is only +// here to make the <ACE_Semaphore> interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::acquire_write (void) +{ + return this->acquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// <tryacquire> and is only here to make the <ACE_Semaphore> +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::tryacquire_read (void) +{ + return this->tryacquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// <tryacquire> and is only here to make the <ACE_Semaphore> +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::tryacquire_write (void) +{ + return this->tryacquire (); +} + +// Acquire semaphore ownership. This calls <acquire> and is only here +// to make the <ACE_Process_Semaphore> interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Process_Semaphore::acquire_read (void) +{ + return this->acquire (); +} + +// Acquire semaphore ownership. This calls <acquire> and is only here +// to make the <ACE_Process_Semaphore> interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Process_Semaphore::acquire_write (void) +{ + return this->acquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// <tryacquire> and is only here to make the <ACE_Process_Semaphore> +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Process_Semaphore::tryacquire_read (void) +{ + return this->tryacquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// <tryacquire> and is only here to make the <ACE_Process_Semaphore> +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Process_Semaphore::tryacquire_write (void) +{ + return this->tryacquire (); +} + #if defined (ACE_HAS_THREADS) ACE_INLINE const ACE_thread_mutex_t & diff --git a/ace/Synch_T.h b/ace/Synch_T.h index 167bf36950a..ee3ab76422e 100644 --- a/ace/Synch_T.h +++ b/ace/Synch_T.h @@ -23,6 +23,57 @@ // Forward decl class ACE_Time_Value; +template <class LOCKING_MECHANISM> +class ACE_Lock_Adapter : public ACE_Lock + // = TITLE + + // This is an adapter that allows applications to transparently + // combine the <ACE_Lock> abstract base class (which contains + // pure virtual methods) with any of the other concrete ACE + // synchronization classes (e.g., <ACE_Mutex>, <ACE_Semaphore>, + // <ACE_RW_Lock>, etc.). + // + // = DESCRIPTION + // This class uses a form of the Adapter pattern. +{ +public: + typedef LOCKING_MECHANISM LOCK; + + virtual int remove (void); + // Explicitly destroy the lock. + + virtual int acquire (void); + // Block the thread until the lock is acquired. + + virtual int tryacquire (void); + // Conditionally acquire the lock (i.e., won't block). + + virtual int release (void); + // Release the lock. + + virtual int acquire_read (void); + // Block until the thread acquires a read lock. If the locking + // mechanism doesn't support read locks then this just calls + // <acquire>. + + virtual int acquire_write (void); + // Block until the thread acquires a write lock. If the locking + // mechanism doesn't support read locks then this just calls + // <acquire>. + + virtual int tryacquire_read (void); + // Conditionally acquire a read lock. If the locking mechanism + // doesn't support read locks then this just calls <acquire>. + + virtual int tryacquire_write (void); + // Conditionally acquire a write lock. If the locking mechanism + // doesn't support read locks then this just calls <acquire>. + +private: + LOCKING_MECHANISM lock_; + // The concrete locking mechanism that all the methods delegate to. +}; + template <class LOCK, class TYPE> class ACE_Test_and_Set : public ACE_Event_Handler { diff --git a/ace/Synch_T.i b/ace/Synch_T.i index 198975ee38a..252b90633f1 100644 --- a/ace/Synch_T.i +++ b/ace/Synch_T.i @@ -199,4 +199,72 @@ ACE_TSS<TYPE>::ts_get (void) const return (TYPE *) &this->type_; } +// Explicitly destroy the lock. +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::remove (void) +{ + return this->lock_.remove (); +} + +// Block the thread until the lock is acquired. +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::acquire (void) +{ + return this->lock_.acquire (); +} + +// Conditionally acquire the lock (i.e., won't block). + +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::tryacquire (void) +{ + return this->lock_.tryacquire (); +} + +// Release the lock. + +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::release (void) +{ + return this->lock_.release (); +} + +// Block until the thread acquires a read lock. If the locking +// mechanism doesn't support read locks then this just calls +// <acquire>. + +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::acquire_read (void) +{ + return this->lock_.acquire_read (); +} + +// Block until the thread acquires a write lock. If the locking +// mechanism doesn't support read locks then this just calls +// <acquire>. + +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::acquire_write (void) +{ + return this->lock_.acquire_write (); +} + +// Conditionally acquire a read lock. If the locking mechanism +// doesn't support read locks then this just calls <acquire>. + +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::tryacquire_read (void) +{ + return this->lock_.tryacquire_read (); +} + +// Conditionally acquire a write lock. If the locking mechanism +// doesn't support read locks then this just calls <acquire>. + +template <class LOCKING_MECHANISM> int +ACE_Lock_Adapter<LOCKING_MECHANISM>::acquire_write (void) +{ + return this->lock_.acquire_write (); +} + #endif /* defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) */ |