ACE_Mutex Class Reference

ACE_Mutex wrapper (valid in same process or across processes (depending on TYPE flag)). More...

#include <Mutex.h>

List of all members.

Public Member Functions

 ACE_Mutex (int type=USYNC_THREAD, const ACE_TCHAR *name=0, ACE_mutexattr_t *arg=0, mode_t mode=ACE_DEFAULT_FILE_PERMS)
 Initialize the mutex.

 ~ACE_Mutex (void)
 Implicitly destroy the mutex.

int remove (void)
 Explicitly destroy the mutex.

int acquire (void)
 Acquire lock ownership (wait on queue if necessary).

int acquire (ACE_Time_Value &tv)
int acquire (ACE_Time_Value *tv)
int tryacquire (void)
 Conditionally acquire lock (i.e., don't wait on queue).

int release (void)
 Release lock and unblock a thread at head of queue.

int acquire_read (void)
 Acquire mutex ownership.

int acquire_write (void)
 Acquire mutex ownership.

int tryacquire_read (void)
 Conditionally acquire mutex (i.e., won't block).

int tryacquire_write (void)
 Conditionally acquire mutex (i.e., won't block).

int tryacquire_write_upgrade (void)
const ACE_mutex_t & lock (void) const
 Return the underlying mutex.

void dump (void) const
 Dump the state of an object.


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

ACE_mutex_t lock_
 Mutex type supported by the OS.

int removed_

Private Member Functions

void operator= (const ACE_Mutex &)
 ACE_Mutex (const ACE_Mutex &)


Detailed Description

ACE_Mutex wrapper (valid in same process or across processes (depending on TYPE flag)).

Definition at line 48 of file Mutex.h.


Constructor & Destructor Documentation

ACE_Mutex::ACE_Mutex int  type = USYNC_THREAD,
const ACE_TCHAR name = 0,
ACE_mutexattr_t *  arg = 0,
mode_t  mode = ACE_DEFAULT_FILE_PERMS
 

Initialize the mutex.

Definition at line 36 of file Mutex.cpp.

References ACE_ERROR, ACE_LIB_TEXT, ACE_TCHAR, ACE_OS::close(), ACE_OS::ftruncate(), LM_ERROR, MAP_FAILED, MAP_SHARED, ACE_OS::mmap(), mode_t, ACE_OS::mutex_init(), PROT_RDWR, ACE_OS::shm_open(), and ACE_OS::strdup().

00038   :
00039 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00040     process_lock_ (0),
00041     lockname_ (0),
00042 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00043     removed_ (0)
00044 {
00045   // ACE_TRACE ("ACE_Mutex::ACE_Mutex");
00046 
00047   // These platforms need process-wide mutex to be in shared memory.
00048 #if defined(ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS)
00049   if (type == USYNC_PROCESS)
00050     {
00051       // Let's see if the shared memory entity already exists.
00052       ACE_HANDLE fd = ACE_OS::shm_open (name, O_RDWR | O_CREAT | O_EXCL, mode);
00053       if (fd == ACE_INVALID_HANDLE)
00054         {
00055           if (errno == EEXIST)
00056             fd = ACE_OS::shm_open (name, O_RDWR | O_CREAT, mode);
00057           else
00058             return;
00059         }
00060       else
00061         {
00062           // We own this shared memory object!  Let's set its size.
00063           if (ACE_OS::ftruncate (fd,
00064                                  sizeof (ACE_mutex_t)) == -1)
00065             {
00066               ACE_OS::close (fd);
00067               return;
00068             }
00069           this->lockname_ = ACE_OS::strdup (name);
00070           if (this->lockname_ == 0)
00071             {
00072               ACE_OS::close (fd);
00073               return;
00074             }
00075         }
00076 
00077       this->process_lock_ =
00078         (ACE_mutex_t *) ACE_OS::mmap (0,
00079                                       sizeof (ACE_mutex_t),
00080                                       PROT_RDWR,
00081                                       MAP_SHARED,
00082                                       fd,
00083                                       0);
00084       ACE_OS::close (fd);
00085       if (this->process_lock_ == MAP_FAILED)
00086         return;
00087 
00088       if (this->lockname_
00089           && ACE_OS::mutex_init (this->process_lock_,
00090                                  type,
00091                                  name,
00092                                  arg) != 0)
00093         {
00094           ACE_ERROR ((LM_ERROR,
00095                       ACE_LIB_TEXT ("%p\n"),
00096                       ACE_LIB_TEXT ("ACE_Mutex::ACE_Mutex")));
00097           return;
00098         }
00099     }
00100   else
00101     {
00102       // local mutex init if USYNC_PROCESS flag is not enabled.
00103 #else
00104       ACE_UNUSED_ARG (mode);
00105 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00106 
00107       if (ACE_OS::mutex_init (&this->lock_,
00108                               type,
00109                               name,
00110                               arg) != 0)
00111         ACE_ERROR ((LM_ERROR,
00112                     ACE_LIB_TEXT ("%p\n"),
00113                     ACE_LIB_TEXT ("ACE_Mutex::ACE_Mutex")));
00114 #if defined(ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS)
00115     }
00116 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00117 }

ACE_Mutex::~ACE_Mutex void   ) 
 

Implicitly destroy the mutex.

Definition at line 119 of file Mutex.cpp.

References remove().

00120 {
00121 // ACE_TRACE ("ACE_Mutex::~ACE_Mutex");
00122   this->remove ();
00123 }

ACE_Mutex::ACE_Mutex const ACE_Mutex  )  [private]
 


Member Function Documentation

ACE_INLINE int ACE_Mutex::acquire ACE_Time_Value tv  ) 
 

If tv == 0 then call acquire() directly. Otherwise, block the thread until the mutex is acquired or tv times out, in which case -1 is returned and errno == ETIME.

Note:
*tv is assumed to be in "absolute" rather than "relative" time. The value of *tv is updated upon return to show the actual (absolute) acquisition time.

Definition at line 95 of file Mutex.inl.

References ACE_OS::mutex_lock().

00096 {
00097  #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00098    if (this->process_lock_)
00099      return ACE_OS::mutex_lock (this->process_lock_, tv);
00100 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS*/
00101   return ACE_OS::mutex_lock (&this->lock_, tv);
00102 }

ACE_INLINE int ACE_Mutex::acquire ACE_Time_Value tv  ) 
 

Note:
tv is assumed to be in "absolute" rather than " relative" time. The value of tv is updated upon return to show the actual(absolute) acquisition time.

Definition at line 84 of file Mutex.inl.

References ACE_OS::mutex_lock().

00085 {
00086   // ACE_TRACE ("ACE_Mutex::acquire");
00087  #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00088    if (this->process_lock_)
00089      return ACE_OS::mutex_lock (this->process_lock_, tv);
00090 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS*/
00091   return ACE_OS::mutex_lock (&this->lock_, tv);
00092 }

ACE_INLINE int ACE_Mutex::acquire void   ) 
 

Acquire lock ownership (wait on queue if necessary).

Definition at line 73 of file Mutex.inl.

References ACE_OS::mutex_lock().

Referenced by ACE_Process_Mutex::acquire().

00074 {
00075 // ACE_TRACE ("ACE_Mutex::acquire");
00076 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00077    if (this->process_lock_)
00078      return ACE_OS::mutex_lock (this->process_lock_);
00079 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00080   return ACE_OS::mutex_lock (&this->lock_);
00081 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE int ACE_Mutex::acquire_read void   ) 
 

Acquire mutex ownership.

This calls acquire and is only here to make the ACE_Mutex interface consistent with the other synchronization APIs.

Definition at line 11 of file Mutex.inl.

References ACE_OS::mutex_lock().

Referenced by ACE_Process_Mutex::acquire_read().

00012 {
00013 // ACE_TRACE ("ACE_Mutex::acquire_read");
00014 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00015    if (this->process_lock_)
00016      return ACE_OS::mutex_lock (this->process_lock_);
00017 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00018   return ACE_OS::mutex_lock (&this->lock_);
00019 }

ACE_INLINE int ACE_Mutex::acquire_write void   ) 
 

Acquire mutex ownership.

This calls acquire and is only here to make the ACE_Mutex interface consistent with the other synchronization APIs.

Definition at line 22 of file Mutex.inl.

References ACE_OS::mutex_lock().

Referenced by ACE_Process_Mutex::acquire_write().

00023 {
00024 // ACE_TRACE ("ACE_Mutex::acquire_write");
00025 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00026    if (this->process_lock_)
00027      return ACE_OS::mutex_lock (this->process_lock_);
00028 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00029   return ACE_OS::mutex_lock (&this->lock_);
00030 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL void ACE_Mutex::dump void   )  const
 

Dump the state of an object.

Definition at line 23 of file Mutex.cpp.

References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, and LM_DEBUG.

Referenced by ACE_Process_Mutex::dump().

00024 {
00025 // ACE_TRACE ("ACE_Mutex::dump");
00026 
00027   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00028 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00029   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("lockname_ = %s\n"), this->lockname_));
00030   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("process_lock_ = %x\n"), this->process_lock_));
00031 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00032   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
00033   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00034 }

ACE_INLINE const ACE_mutex_t & ACE_Mutex::lock void   )  const
 

Return the underlying mutex.

Definition at line 44 of file Mutex.inl.

Referenced by ACE_Process_Mutex::lock().

00045 {
00046 // ACE_TRACE ("ACE_Mutex::lock");
00047 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00048   if (this->process_lock_)
00049     return *this->process_lock_;
00050 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00051   return this->lock_;
00052 }

void ACE_Mutex::operator= const ACE_Mutex  )  [private]
 

ACE_INLINE int ACE_Mutex::release void   ) 
 

Release lock and unblock a thread at head of queue.

Definition at line 116 of file Mutex.inl.

References ACE_OS::mutex_unlock().

Referenced by ACE_Process_Mutex::release().

00117 {
00118 // ACE_TRACE ("ACE_Mutex::release");
00119 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00120    if (this->process_lock_)
00121      return ACE_OS::mutex_unlock (this->process_lock_);
00122 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00123   return ACE_OS::mutex_unlock (&this->lock_);
00124 }

ACE_INLINE int ACE_Mutex::remove void   ) 
 

Explicitly destroy the mutex.

Note:
Only one thread should call this method since it doesn't protect against race conditions.

Definition at line 127 of file Mutex.inl.

References ACE_OS::free(), ACE_OS::munmap(), ACE_OS::mutex_destroy(), and ACE_OS::shm_unlink().

Referenced by ACE_Process_Mutex::remove(), and ~ACE_Mutex().

00128 {
00129 // ACE_TRACE ("ACE_Mutex::remove");
00130   int result = 0;
00131 #if defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS)
00132   // In the case of a interprocess mutex, the owner is the first
00133   // process that created the shared memory object. In this case, the
00134   // lockname_ pointer will be non-zero (points to allocated memory
00135   // for the name).  Owner or not, the memory needs to be unmapped
00136   // from the process.  If we are the owner, the file used for
00137   // shm_open needs to be deleted as well.
00138   if (this->process_lock_)
00139     {
00140       if (this->removed_ == 0)
00141         {
00142           this->removed_ = 1;
00143           // Only destroy the lock if we're the ones who initialized
00144           // it.
00145           if (!this->lockname_)
00146             ACE_OS::munmap ((void *) this->process_lock_,
00147                             sizeof (ACE_mutex_t));
00148           else
00149             {
00150               result = ACE_OS::mutex_destroy (this->process_lock_);
00151               ACE_OS::munmap ((void *) this->process_lock_,
00152                               sizeof (ACE_mutex_t));
00153               ACE_OS::shm_unlink (this->lockname_);
00154               ACE_OS::free (
00155                 static_cast<void *> (
00156                   const_cast<ACE_TCHAR *> (this->lockname_)));
00157             }
00158         }
00159     }
00160   else
00161   {
00162 #else /* !ACE_HAS_PTHREADS && !ACE_HAS_STHREADS */
00163     if (this->removed_ == 0)
00164       {
00165         this->removed_ = 1;
00166         result = ACE_OS::mutex_destroy (&this->lock_);
00167       }
00168 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00169 #if defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS)
00170   }
00171 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00172   return result;
00173 }

ACE_INLINE int ACE_Mutex::tryacquire void   ) 
 

Conditionally acquire lock (i.e., don't wait on queue).

Returns:
-1 on failure. If we "failed" because someone else already had the lock, errno is set to EBUSY.

Definition at line 105 of file Mutex.inl.

References ACE_OS::mutex_trylock().

Referenced by ACE_Process_Mutex::tryacquire().

00106 {
00107 // ACE_TRACE ("ACE_Mutex::tryacquire");
00108 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00109    if (this->process_lock_)
00110      return ACE_OS::mutex_trylock (this->process_lock_);
00111 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00112   return ACE_OS::mutex_trylock (&this->lock_);
00113 }

ACE_INLINE int ACE_Mutex::tryacquire_read void   ) 
 

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.

Returns:
-1 on failure. If we "failed" because someone else already had the lock, errno is set to EBUSY.

Definition at line 33 of file Mutex.inl.

References ACE_OS::mutex_trylock().

Referenced by ACE_Process_Mutex::tryacquire_read().

00034 {
00035 // ACE_TRACE ("ACE_Mutex::tryacquire_read");
00036 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00037    if (this->process_lock_)
00038      return ACE_OS::mutex_trylock (this->process_lock_);
00039 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00040   return ACE_OS::mutex_trylock (&this->lock_);
00041 }

ACE_INLINE int ACE_Mutex::tryacquire_write void   ) 
 

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.

Returns:
-1 on failure. If we "failed" because someone else already had the lock, errno is set to EBUSY.

Definition at line 55 of file Mutex.inl.

References ACE_OS::mutex_trylock().

Referenced by ACE_Process_Mutex::tryacquire_write().

00056 {
00057 // ACE_TRACE ("ACE_Mutex::tryacquire_write");
00058 #if defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS)
00059    if (this->process_lock_)
00060      return ACE_OS::mutex_trylock (this->process_lock_);
00061 #endif /* ACE_HAS_PTHREADS || ACE_HAS_STHREADS */
00062   return ACE_OS::mutex_trylock (&this->lock_);
00063 }

ACE_INLINE int ACE_Mutex::tryacquire_write_upgrade void   ) 
 

This is only here for consistency with the other synchronization APIs and usability with Lock adapters. Assumes the caller already has acquired the mutex and returns 0 in all cases.

Definition at line 66 of file Mutex.inl.

00067 {
00068 // ACE_TRACE ("ACE_Mutex::tryacquire_write_upgrade");
00069   return 0;
00070 }


Member Data Documentation

ACE_Mutex::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Definition at line 150 of file Mutex.h.

ACE_mutex_t ACE_Mutex::lock_
 

Mutex type supported by the OS.

Definition at line 167 of file Mutex.h.

int ACE_Mutex::removed_
 

Keeps track of whether remove has been called yet to avoid multiple remove calls, e.g., explicitly and implicitly in the destructor. This flag isn't protected by a lock, so make sure that you don't have multiple threads simultaneously calling remove on the same object, which is a bad idea anyway.

Definition at line 174 of file Mutex.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:25:20 2006 for ACE by doxygen 1.3.6