SV_Semaphore_Complex.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   SV_Semaphore_Complex.h
00006  *
00007  *  SV_Semaphore_Complex.h,v 4.22 2006/03/14 21:15:49 sjiang Exp
00008  *
00009  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef ACE_SV_SEMAPHORE_COMPLEX_H
00014 #define ACE_SV_SEMAPHORE_COMPLEX_H
00015 #include /**/ "ace/pre.h"
00016 
00017 #include "ace/SV_Semaphore_Simple.h"
00018 
00019 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00020 # pragma once
00021 #endif /* ACE_LACKS_PRAGMA_ONCE */
00022 
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 /**
00026  * @class ACE_SV_Semaphore_Complex
00027  *
00028  * @brief This is a more complex semaphore wrapper that handles race
00029  * conditions for initialization correctly...
00030  *
00031  * This code is a port to C++, inspired by: W. Richard Stevens
00032  * from his book: UNIX Network Programming (Prentice Hall, ISBN
00033  * 0-13-949876-1 - 1990).  We provide a simpler and easier to
00034  * understand interface to the System V Semaphore system calls.
00035  * We create and use a 2 + n-member set for the requested
00036  * <ACE_SV_Semaphore_Complex>. The first member, [0], is a
00037  * counter used to know when all processes have finished with
00038  * the <ACE_SV_Semaphore_Complex>.  The counter is initialized
00039  * to a large number, decremented on every create or open and
00040  * incremented on every close. This way we can use the "adjust"
00041  * feature provided by System V so that any process that exit's
00042  * without calling <close> is accounted for. It doesn't help us
00043  * if the last process does this (as we have no way of getting
00044  * control to remove the <ACE_SV_Semaphore_Complex>) but it
00045  * will work if any process other than the last does an exit
00046  * (intentional or unintentional).
00047  * The second member, [1], of the semaphore is used as a lock
00048  * variable to avoid any race conditions in the <create> and
00049  * <close> functions.
00050  * The members beyond [1] are actual semaphore values in the
00051  * array of semaphores, which may be sized by the user in the
00052  * constructor.
00053  */
00054 class ACE_Export ACE_SV_Semaphore_Complex : private ACE_SV_Semaphore_Simple
00055 {
00056 public:
00057   enum
00058   {
00059     ACE_CREATE = IPC_CREAT,
00060     ACE_OPEN   = 0
00061   };
00062 
00063   // = Initialization and termination methods.
00064   ACE_SV_Semaphore_Complex (void);
00065   ACE_SV_Semaphore_Complex (key_t key,
00066                             short create = ACE_SV_Semaphore_Complex::ACE_CREATE,
00067                             int initial_value = 1,
00068                             u_short nsems = 1,
00069                             mode_t perms = ACE_DEFAULT_FILE_PERMS);
00070   ACE_SV_Semaphore_Complex (const char *name,
00071                             short create = ACE_SV_Semaphore_Complex::ACE_CREATE,
00072                             int initial_value = 1,
00073                             u_short nsems = 1,
00074                             mode_t perms = ACE_DEFAULT_FILE_PERMS);
00075   ~ACE_SV_Semaphore_Complex (void);
00076 
00077   /// Open or create an array of SV_Semaphores.  We return 0 if all is
00078   /// OK, else -1.
00079   int open (const char *name,
00080             short flags = ACE_SV_Semaphore_Simple::ACE_CREATE,
00081             int initial_value = 1,
00082             u_short nsems = 1,
00083             mode_t perms = ACE_DEFAULT_FILE_PERMS);
00084 
00085   /// Open or create an array of SV_Semaphores.  We return 0 if all is
00086   /// OK, else -1.
00087   int open (key_t key,
00088             short flags = ACE_SV_Semaphore_Simple::ACE_CREATE,
00089             int initial_value = 1,
00090             u_short nsems = 1,
00091             mode_t perms = ACE_DEFAULT_FILE_PERMS);
00092 
00093   /**
00094    * Close an ACE_SV_Semaphore. Unlike the <remove> method, this
00095    * method is for a process to call before it exits, when it is done
00096    * with the ACE_SV_Semaphore. We "decrement" the counter of
00097    * processes using the ACE_SV_Semaphore, and if this was the last
00098    * one, we can remove the ACE_SV_Semaphore.
00099    */
00100   int close (void);
00101 
00102   // = Semaphore acquire and release methods.
00103 
00104   /// Acquire the semaphore.
00105   int acquire (u_short n = 0, short flags = 0) const;
00106 
00107   /// Acquire a semaphore for reading.
00108   int acquire_read (u_short n = 0, short flags = 0) const;
00109 
00110   /// Acquire a semaphore for writing
00111   int acquire_write (u_short n = 0, short flags = 0) const;
00112 
00113   /// Try to acquire the semaphore.
00114   int tryacquire (u_short n = 0, short flags = 0) const;
00115 
00116   /// Try to acquire the semaphore for reading.
00117   int tryacquire_read (u_short n = 0, short flags = 0) const;
00118 
00119   /// Try to acquire the semaphore for writing.
00120   int tryacquire_write (u_short n = 0, short flags = 0) const;
00121 
00122   /// Release the semaphore.
00123   int release (u_short n = 0, short flags = 0) const;
00124 
00125   // = Semaphore operation methods.
00126   int op (short val, u_short n = 0, short flags = 0) const;
00127   int op (sembuf op_vec[], u_short n) const;
00128 
00129   // = Semaphore control methods.
00130   int control (int cmd, semun arg, u_short n = 0) const;
00131   int control (int cmd, int value = 0, u_short n = 0) const;
00132 
00133   // = Upgrade access control...
00134   using ACE_SV_Semaphore_Simple::get_id;
00135   using ACE_SV_Semaphore_Simple::remove;
00136 
00137   /// Dump the state of an object.
00138   void dump (void) const;
00139 
00140   /// Declare the dynamic allocation hooks.
00141   ACE_ALLOC_HOOK_DECLARE;
00142 
00143 private:
00144   static const int BIGCOUNT_;
00145   static sembuf op_lock_[2];
00146   static sembuf op_endcreate_[2];
00147   static sembuf op_open_[1];
00148   static sembuf op_close_[3];
00149   static sembuf op_unlock_[1];
00150 };
00151 
00152 ACE_END_VERSIONED_NAMESPACE_DECL
00153 
00154 #if defined (__ACE_INLINE__)
00155 #include "ace/SV_Semaphore_Complex.inl"
00156 #endif /* __ACE_INLINE__ */
00157 
00158 #include /**/ "ace/post.h"
00159 #endif /* ACE_SV_SEMAPHORE_COMPLEX_H */

Generated on Thu Nov 9 09:42:05 2006 for ACE by doxygen 1.3.6