00001
00002
00003
00004 #include "ace/SV_Semaphore_Complex.h"
00005 #include "ace/Log_Msg.h"
00006 #include "ace/OS_NS_Thread.h"
00007
00008 #if !defined (__ACE_INLINE__)
00009 #include "ace/SV_Semaphore_Complex.inl"
00010 #endif
00011
00012 ACE_RCSID(ace, SV_Semaphore_Complex, "$Id: SV_Semaphore_Complex.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00013
00014 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00015
00016 ACE_ALLOC_HOOK_DEFINE(ACE_SV_Semaphore_Complex)
00017
00018 void
00019 ACE_SV_Semaphore_Complex::dump (void) const
00020 {
00021 #if defined (ACE_HAS_DUMP)
00022 ACE_TRACE ("ACE_SV_Semaphore_Complex::dump");
00023 #endif
00024 }
00025
00026
00027 const int ACE_SV_Semaphore_Complex::BIGCOUNT_ = 10000;
00028
00029
00030 sembuf ACE_SV_Semaphore_Complex::op_lock_[2] =
00031 {
00032 {0, 0, 0},
00033 {0, 1, SEM_UNDO},
00034
00035
00036 };
00037
00038 sembuf ACE_SV_Semaphore_Complex::op_endcreate_[2] =
00039 {
00040 {1, -1, SEM_UNDO},
00041
00042
00043 {0, -1, SEM_UNDO},
00044 };
00045
00046 sembuf ACE_SV_Semaphore_Complex::op_open_[1] =
00047 {
00048 {1, -1, SEM_UNDO},
00049
00050 };
00051
00052 sembuf ACE_SV_Semaphore_Complex::op_close_[3] =
00053 {
00054 {0, 0, 0},
00055 {0, 1, SEM_UNDO},
00056 {1, 1, SEM_UNDO},
00057 };
00058
00059 sembuf ACE_SV_Semaphore_Complex::op_unlock_[1] =
00060 {
00061 {0, -1, SEM_UNDO},
00062 };
00063
00064
00065
00066 int
00067 ACE_SV_Semaphore_Complex::open (key_t k,
00068 short create,
00069 int initial_value,
00070 u_short nsems,
00071 mode_t perms)
00072 {
00073 ACE_TRACE ("ACE_SV_Semaphore_Complex::open");
00074 if (k == IPC_PRIVATE)
00075 return -1;
00076
00077 this->key_ = k;
00078
00079
00080
00081 this->sem_number_ = nsems + 2;
00082
00083 if (create == ACE_SV_Semaphore_Complex::ACE_CREATE)
00084 {
00085 int result;
00086
00087 do
00088 {
00089 this->internal_id_ = ACE_OS::semget
00090 (this->key_,
00091 (u_short) 2 + nsems,
00092 perms | ACE_SV_Semaphore_Complex::ACE_CREATE);
00093
00094 if (this->internal_id_ == -1)
00095 return -1;
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 result = ACE_OS::semop (this->internal_id_,
00110 &ACE_SV_Semaphore_Complex::op_lock_[0],
00111 2);
00112 }
00113 while (result == -1 && (errno == EINVAL || errno == EIDRM));
00114
00115 if (result == -1)
00116 return -1;
00117
00118
00119
00120
00121 int semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1);
00122
00123 if (semval == -1)
00124 return this->init ();
00125 else if (semval == 0)
00126 {
00127
00128
00129
00130
00131
00132 if (ACE_SV_Semaphore_Simple::control (SETVAL,
00133 ACE_SV_Semaphore_Complex::BIGCOUNT_,
00134 1) == -1)
00135 return -1;
00136 else
00137 for (u_short i = 0; i < nsems; i++)
00138 if (this->control (SETVAL, initial_value, i) == -1)
00139 return -1;
00140 }
00141
00142
00143 return ACE_OS::semop (this->internal_id_,
00144 &ACE_SV_Semaphore_Complex::op_endcreate_[0],
00145 2);
00146 }
00147 else
00148 {
00149 this->internal_id_ = ACE_OS::semget (this->key_, 2 + nsems, 0);
00150 if (this->internal_id_ == -1)
00151 return -1;
00152
00153
00154 if (ACE_OS::semop (this->internal_id_,
00155 &ACE_SV_Semaphore_Complex::op_open_[0], 1) < 0)
00156 return this->init ();
00157 return 0;
00158 }
00159 }
00160
00161 int
00162 ACE_SV_Semaphore_Complex::open (const char *name,
00163 short flags,
00164 int initial_value,
00165 u_short nsems,
00166 mode_t perms)
00167 {
00168 ACE_TRACE ("ACE_SV_Semaphore_Complex::open");
00169 return this->open (ACE_SV_Semaphore_Simple::name_2_key (name),
00170 flags, initial_value, nsems, perms);
00171 }
00172
00173
00174
00175
00176
00177
00178
00179 int
00180 ACE_SV_Semaphore_Complex::close (void)
00181 {
00182 ACE_TRACE ("ACE_SV_Semaphore_Complex::close");
00183 int semval;
00184
00185 if (this->key_ == (key_t) - 1 || this->internal_id_ == -1)
00186 return -1;
00187
00188
00189
00190
00191 if (ACE_OS::semop (this->internal_id_,
00192 &ACE_SV_Semaphore_Complex::op_close_[0],
00193 3) == -1)
00194 return -1;
00195
00196
00197
00198
00199
00200 if ((semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1)) == -1)
00201 return -1;
00202
00203 if (semval > ACE_SV_Semaphore_Complex::BIGCOUNT_)
00204 return -1;
00205 else if (semval == ACE_SV_Semaphore_Complex::BIGCOUNT_)
00206 return this->remove ();
00207 else
00208 {
00209 int result = ACE_OS::semop (this->internal_id_,
00210 &ACE_SV_Semaphore_Complex::op_unlock_[0], 1);
00211 this->init ();
00212 return result;
00213 }
00214 }
00215
00216 ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (key_t k,
00217 short flags,
00218 int initial_value,
00219 u_short nsems,
00220 mode_t perms)
00221 {
00222 ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex");
00223 if (this->open (k, flags, initial_value, nsems, perms) == -1)
00224 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_SV_Semaphore_Complex")));
00225 }
00226
00227 ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (const char *name,
00228 short flags,
00229 int initial_value,
00230 u_short nsems,
00231 mode_t perms)
00232 {
00233 ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex");
00234
00235 key_t key;
00236
00237 if (name == 0)
00238 key = ACE_DEFAULT_SEM_KEY;
00239 else
00240 key = this->name_2_key (name);
00241
00242 if (this->open (key, flags, initial_value, nsems, perms) == -1)
00243 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_SV_Semaphore_Complex")));
00244 }
00245
00246 ACE_SV_Semaphore_Complex::~ACE_SV_Semaphore_Complex (void)
00247 {
00248 ACE_TRACE ("ACE_SV_Semaphore_Complex::~ACE_SV_Semaphore_Complex");
00249 if (this->internal_id_ >= 0)
00250 this->close ();
00251 }
00252
00253 ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (void)
00254 {
00255 ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex");
00256 this->init ();
00257 }
00258
00259 ACE_END_VERSIONED_NAMESPACE_DECL