SV_Semaphore_Simple.cpp

Go to the documentation of this file.
00001 #include "ace/SV_Semaphore_Simple.h"
00002 #include "ace/Log_Msg.h"
00003 #include "ace/ACE.h"
00004 #include "ace/os_include/sys/os_sem.h"
00005 
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/SV_Semaphore_Simple.inl"
00008 #endif /* !__ACE_INLINE__ */
00009 
00010 ACE_RCSID (ace,
00011            SV_Semaphore_Simple,
00012            "SV_Semaphore_Simple.cpp,v 4.29 2006/03/14 21:15:49 sjiang Exp")
00013 
00014 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00015 
00016 ACE_ALLOC_HOOK_DEFINE (ACE_SV_Semaphore_Simple)
00017 
00018 void
00019 ACE_SV_Semaphore_Simple::dump (void) const
00020 {
00021 #if defined (ACE_HAS_DUMP)
00022   ACE_TRACE ("ACE_SV_Semaphore_Simple::dump");
00023 #endif /* ACE_HAS_DUMP */
00024 }
00025 
00026 int
00027 ACE_SV_Semaphore_Simple::control (int cmd,
00028                                   int value,
00029                                   u_short semnum) const
00030 {
00031   ACE_TRACE ("ACE_SV_Semaphore_Simple::control");
00032   if (this->internal_id_ == -1)
00033     return -1;
00034   else
00035     {
00036       semun semctl_arg;
00037 
00038       semctl_arg.val = value;
00039       return ACE_OS::semctl (this->internal_id_,
00040                              semnum,
00041                              cmd,
00042                              semctl_arg);
00043     }
00044 }
00045 
00046 int
00047 ACE_SV_Semaphore_Simple::init (key_t k, int i)
00048 {
00049   ACE_TRACE ("ACE_SV_Semaphore_Simple::init");
00050   this->key_ = k;
00051   this->internal_id_ = i;
00052   return 0;
00053 }
00054 
00055 // General ACE_SV_Semaphore operation. Increment or decrement by a
00056 // specific amount (positive or negative; amount can`t be zero).
00057 
00058 int
00059 ACE_SV_Semaphore_Simple::op (short val, u_short n, short flags) const
00060 {
00061   ACE_TRACE ("ACE_SV_Semaphore_Simple::op");
00062   sembuf op_op;
00063 
00064   op_op.sem_num = n;
00065   op_op.sem_flg = flags;
00066 
00067   if (this->internal_id_ == -1)
00068     return -1;
00069   else if ((op_op.sem_op = val) == 0)
00070     return -1;
00071   else
00072     return ACE_OS::semop (this->internal_id_, &op_op, 1);
00073 }
00074 
00075 // Open or create one or more SV_Semaphores.  We return 0 if all is
00076 // OK, else -1.
00077 
00078 int
00079 ACE_SV_Semaphore_Simple::open (key_t k,
00080                                short flags,
00081                                int initial_value,
00082                                u_short n,
00083                                mode_t perms)
00084 {
00085   ACE_TRACE ("ACE_SV_Semaphore_Simple::open");
00086   union semun ivalue;
00087 
00088   if (k == IPC_PRIVATE || k == static_cast<key_t> (ACE_INVALID_SEM_KEY))
00089     return -1;
00090 
00091   ivalue.val = initial_value;
00092   this->key_ = k;
00093   this->sem_number_ = n;
00094 
00095   this->internal_id_ = ACE_OS::semget (this->key_, n, perms | flags);
00096 
00097   if (this->internal_id_ == -1)
00098     return -1;
00099 
00100   if (ACE_BIT_ENABLED (flags, IPC_CREAT))
00101     for (int i = 0; i < n; i++)
00102       if (ACE_OS::semctl (this->internal_id_, i, SETVAL, ivalue) == -1)
00103         return -1;
00104 
00105   return 0;
00106 }
00107 
00108 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (key_t k,
00109                                                   short flags,
00110                                                   int initial_value,
00111                                                   u_short n,
00112                                                   mode_t perms)
00113   : key_ (k)
00114 {
00115   ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
00116   if (this->open (k, flags, initial_value, n, perms) == -1)
00117     ACE_ERROR ((LM_ERROR,  ACE_LIB_TEXT ("%p\n"),  ACE_LIB_TEXT ("ACE_SV_Semaphore::ACE_SV_Semaphore")));
00118 }
00119 
00120 // Convert name to key.  This function is used internally to create keys
00121 // for the semaphores.
00122 //
00123 // The method for generating names is a 32 bit CRC, but still we
00124 // measured close to collition ratio of nearly 0.1% for
00125 // ACE::unique_name()-like strings.
00126 
00127 key_t
00128 ACE_SV_Semaphore_Simple::name_2_key (const char *name)
00129 {
00130   ACE_TRACE ("ACE_SV_Semaphore_Simple::name_2_key");
00131 
00132   if (name == 0)
00133     {
00134       errno = EINVAL;
00135       return static_cast<key_t> (ACE_INVALID_SEM_KEY);
00136     }
00137 
00138   // Basically "hash" the values in the <name>.  This won't
00139   // necessarily guarantee uniqueness of all keys.
00140   // But (IMHO) CRC32 is good enough for most purposes (Carlos)
00141 #if defined (ACE_WIN64)
00142   // The cast below is legit...
00143 #  pragma warning(push)
00144 #  pragma warning(disable : 4312)
00145 #endif /* ACE_WIN64 */
00146   return (key_t) ACE::crc32 (name);
00147 #if defined (ACE_WIN64)
00148 #  pragma warning(pop)
00149 #endif /* ACE_WIN64 */
00150 }
00151 
00152 // Open or create a ACE_SV_Semaphore.  We return 1 if all is OK, else
00153 // 0.
00154 
00155 int
00156 ACE_SV_Semaphore_Simple::open (const char *name,
00157                                short flags,
00158                                int initial_value,
00159                                u_short n,
00160                                mode_t perms)
00161 {
00162   ACE_TRACE ("ACE_SV_Semaphore_Simple::open");
00163 
00164   key_t key;
00165 
00166   if (name == 0)
00167     key = ACE_DEFAULT_SEM_KEY;
00168   else
00169     key = this->name_2_key (name);
00170 
00171   return this->open (key, flags, initial_value, n, perms);
00172 }
00173 
00174 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const char *name,
00175                                                   short flags,
00176                                                   int initial_value,
00177                                                   u_short n,
00178                                                   mode_t perms)
00179 {
00180   ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
00181   if (this->open (name,
00182                   flags,
00183                   initial_value,
00184                   n,
00185                   perms) == -1)
00186     ACE_ERROR ((LM_ERROR,
00187                 ACE_LIB_TEXT ("%p\n"),
00188                 ACE_LIB_TEXT ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple")));
00189 }
00190 
00191 #if defined (ACE_HAS_WCHAR)
00192 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const wchar_t *name,
00193                                                   short flags,
00194                                                   int initial_value,
00195                                                   u_short nsems,
00196                                                   mode_t perms)
00197 {
00198   ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple(wchar_t)");
00199   if (this->open (ACE_Wide_To_Ascii (name).char_rep (),
00200                   flags,
00201                   initial_value,
00202                   nsems,
00203                   perms) == -1)
00204     ACE_ERROR ((LM_ERROR,
00205                 ACE_LIB_TEXT ("%p\n"),
00206                 ACE_LIB_TEXT ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple")));
00207 }
00208 #endif /* ACE_HAS_WCHAR */
00209 
00210 ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple (void)
00211 {
00212   ACE_TRACE ("ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple");
00213   this->close ();
00214 }
00215 
00216 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (void)
00217 {
00218   ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
00219   this->init ();
00220 }
00221 
00222 // Remove all SV_Semaphores associated with a particular key.  This
00223 // call is intended to be called from a server, for example, when it
00224 // is being shut down, as we do an IPC_RMID on the ACE_SV_Semaphore,
00225 // regardless of whether other processes may be using it or not.  Most
00226 // other processes should use close() below.
00227 
00228 int
00229 ACE_SV_Semaphore_Simple::remove (void) const
00230 {
00231   ACE_TRACE ("ACE_SV_Semaphore_Simple::remove");
00232   int result = this->control (IPC_RMID);
00233   ((ACE_SV_Semaphore_Simple *) this)->init ();
00234   return result;
00235 }
00236 
00237 ACE_END_VERSIONED_NAMESPACE_DECL

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