summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
Diffstat (limited to 'ace')
-rw-r--r--ace/Acceptor.h7
-rw-r--r--ace/Connector.cpp2
-rw-r--r--ace/Connector.h2
-rw-r--r--ace/Event_Handler.h4
-rw-r--r--ace/Log_Msg.cpp8
-rw-r--r--ace/Message_Block.cpp102
-rw-r--r--ace/Message_Block.h81
-rw-r--r--ace/Message_Block.i16
-rw-r--r--ace/Reactor.cpp8
-rw-r--r--ace/SOCK_Acceptor.h1
-rw-r--r--ace/Svc_Handler.h2
-rw-r--r--ace/Synch.h162
-rw-r--r--ace/Synch.i80
-rw-r--r--ace/Synch_T.h51
-rw-r--r--ace/Synch_T.i68
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) */