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