libassa 3.5.1
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
ASSA::Semaphore Class Reference

#include <Semaphore.h>

Public Member Functions

 Semaphore ()
 Constructor.
 
virtual ~Semaphore ()
 Destructor.
 
int create (key_t key_, int initval_=1)
 Create a semaphore with a specified initial value.
 
int open (key_t key_)
 Open a semaphore that must already exist.
 
void close ()
 Close a semaphore.
 
void remove ()
 Remove a semaphore.
 
void wait ()
 Wait until a semaphore's value is greater then 0, then decrement it by 1 and return.
 
void signal ()
 Increment a semaphore by 1.
 
void op (int val_)
 General semaphore operation.
 
key_t key () const
 Get key.
 
int id () const
 Get id.
 
void dump (void) const
 Dump the objects state along with the state of the semaphore (if connected) to the log file.
 

Protected Member Functions

void init ()
 Initalize by invalidating data members.
 

Protected Attributes

key_t m_key
 Semaphore's key.
 
int m_id
 Semaphore's id.
 

Static Protected Attributes

static const int BIGCOUNT = 10000
 
static sembuf m_op_lock [2]
 Wait for lock to equal 0, then increment lock to 1 - this locks it.
 
static sembuf m_op_endcreate [2]
 Decrement process counter with undo on exit, then decrement lock back to 0.
 
static sembuf m_op_open [2]
 Decrement process counter with undo on exit.
 
static sembuf m_op_close [3]
 Wait for lock to equal 0, then increment lock to 1 (lock it), then increment process counter.
 
static sembuf m_op_unlock [1]
 Decremetn lock back to 0.
 
static sembuf m_op_op [1]
 Decrement or increment semaphore with undo on exit.
 

Detailed Description

Definition at line 67 of file Semaphore.h.

Constructor & Destructor Documentation

◆ Semaphore()

ASSA::Semaphore::Semaphore ( )
inline

Constructor.

Definition at line 190 of file Semaphore.h.

192{
193 trace_with_mask("Semaphore::Semaphore", SEM);
194
195 init ();
196}
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition Logger.h:437
void init()
Initalize by invalidating data members.
Definition Semaphore.h:211
@ SEM
Class Semaphore messages
Definition LogMask.h:37

References init(), ASSA::SEM, and trace_with_mask.

◆ ~Semaphore()

ASSA::Semaphore::~Semaphore ( )
inlinevirtual

Destructor.

Definition at line 199 of file Semaphore.h.

201{
202 trace_with_mask("Semaphore::~Semaphore", SEM);
203
204 if (m_id > 0) {
205 this->close ();
206 }
207}
int m_id
Semaphore's id.
Definition Semaphore.h:154
void close()
Close a semaphore.

References close(), m_id, ASSA::SEM, and trace_with_mask.

Member Function Documentation

◆ close()

void Semaphore::close ( )

Close a semaphore.

Unlike the Semaphore::remove () function, this function is for a process to call before it exits, when it is done with the semaphore. We decrement the counter of processes using the semaphore, and if this was the last one, Semaphore::remove () is called to remove the semaphore. Calling this method also invalidates object for subsequent operations.

Definition at line 218 of file Semaphore.cpp.

220{
221 trace_with_mask("Semaphore::close", SEM);
222
223 register int semval;
224
225 if (m_id < 0) return;
226
227 /*
228 First get the lock on semaphore, then increment process counter.
229 */
230 if (semop (m_id, &m_op_close[0], 3) < 0) {
231 EL((ASSAERR,"Can't semop(2)\n"));
232 Assure_exit(false);
233 }
234 /*
235 Now that we have a lock, read the value of the process counter
236 to see if this is the last reference to the semaphore.
237 There is a race condition here (same as in Semaphore::create()).
238 */
239 if ((semval = semctl (m_id, 1, GETVAL, 0)) < 0) {
240 EL((ASSAERR,"Can't GETVAL\n"));
241 Assure_exit(false);
242 }
243
244 if (semval > BIGCOUNT) {
245 EL((ASSAERR,"sem[1] > BIGCOUNT\n"));
246 Assure_exit(false);
247 }
248 else if (semval == BIGCOUNT) {
249 remove ();
250 }
251 else if (semop (m_id, &m_op_unlock[0], 1) < 0) {
252 EL((ASSAERR,"Can't unlock\n"));
253 Assure_exit(false);
254 }
255 /*--- Invalidate ---*/
256 init ();
257}
#define Assure_exit(exp_)
Macro that makes program exit if assert fails.
Definition Assure.h:39
#define EL(X)
A macro for writing error message to the Logger.
Definition Logger.h:285
A wrapper class to provide AutoPtr with reference semantics.
Definition AutoPtr.h:32
void remove()
Remove a semaphore.
static sembuf m_op_unlock[1]
Decremetn lock back to 0.
Definition Semaphore.h:180
static sembuf m_op_close[3]
Wait for lock to equal 0, then increment lock to 1 (lock it), then increment process counter.
Definition Semaphore.h:176
static const int BIGCOUNT
Definition Semaphore.h:157
@ ASSAERR
ASSA and system errors
Definition LogMask.h:34

References ASSA::ASSAERR, Assure_exit, BIGCOUNT, EL, init(), m_id, m_op_close, m_op_unlock, remove(), ASSA::SEM, and trace_with_mask.

Referenced by ~Semaphore().

◆ create()

int Semaphore::create ( key_t  key_,
int  initval_ = 1 
)

Create a semaphore with a specified initial value.

If the semaphore already exists, we don't initialize it (of course).

Parameters
key_Semaphore's key
initval_Initiali value (default : 1)
Returns
The semaphore ID if all OK, else -1

Definition at line 73 of file Semaphore.cpp.

75{
76 trace_with_mask("Semaphore::create", SEM);
77
78 register int semval;
79
80 union semnum {
81 int val;
82 struct semid_ds* buf;
85
86 if (IPC_PRIVATE == key_) {
87 EL((ASSAERR,"Not intended for private semaphores\n"));
88 return (-1);
89 }
90 else if (key_ == (key_t) -1) {
91 EL((ASSAERR,"Probably an ftok() error by caller\n"));
92 return (-1);
93 }
94
95 m_key = key_;
96 bool done = false;
97
98 while (!done) {
99 if ( (m_id = semget (m_key, 3, 0666 | IPC_CREAT)) < 0) {
100 EL((ASSAERR,"Permission problem or kernel tables full\n"));
101 return (-1);
102 }
103 /*
104 When the semaphore is created, we know that the value of
105 all 3 set members is 0.
106
107 Get a lock on the semaphore by waiting for [2] to equal 0,
108 then increment it.
109
110 There is a race condition here. There is a possibility
111 that between the semget(2) and semop(2) below, another
112 process can cal Semaphore:::close () member function
113 which can remove a semaphore if that process is the last
114 one using it.
115
116 Therefore, we handle the error condition of an invalid
117 semaphore ID specially below, and if it does happen, we
118 just go back and create it again.
119 */
120
121 if (semop (m_id, &m_op_lock[0], 2) < 0) {
122 if (errno == EINVAL) {
123 continue;
124 }
125 EL((ASSAERR,"Can't lock semaphore\n"));
126 Assure_exit (false);
127 }
128 done = true;
129 } // while (!done)
130
131 /*
132 Get the value of the process counter. If it equals 0,
133 then no one has initialized the semaphore yet.
134 */
135 if ((semval = semctl (m_id, 1, GETVAL, 0)) < 0) {
136 EL((ASSAERR,"Can't GETVAL\n"));
137 Assure_exit (false);
138 }
139
140 if (semval == 0) {
141 /*
142 We could initalize by doing a SETALL, but that
143 would clear the adjust value that we set when
144 we locked the semaphore above. Instead, we'll do
145 two system calls to initialize semaphore value [0]
146 and process counter [1].
147 */
148 semctrl_arg.val = initval_;
149
150 if (semctl (m_id, 0, SETVAL, semctrl_arg) < 0) {
151 EL((ASSAERR,"Can't SETVAL[0]\n"));
152 Assure_exit (false);
153 }
154
155 semctrl_arg.val = BIGCOUNT;
156
157 if (semctl (m_id, 1, SETVAL, semctrl_arg) < 0) {
158 EL((ASSAERR,"Can't SETVAL[1]\n"));
159 Assure_exit (false);
160 }
161 } // if (semval == 0)
162
163 /*--- Decrement the process counter and then release the lock. ---*/
164
165 if (semop (m_id, &m_op_endcreate[0], 2) < 0) {
166 EL((ASSAERR,"Error on semop (ndcreate)\n"));
167 Assure_exit (false);
168 }
169 return (m_id);
170}
key_t m_key
Semaphore's key.
Definition Semaphore.h:151
static sembuf m_op_lock[2]
Wait for lock to equal 0, then increment lock to 1 - this locks it.
Definition Semaphore.h:161
static sembuf m_op_endcreate[2]
Decrement process counter with undo on exit, then decrement lock back to 0.
Definition Semaphore.h:166

References ASSA::ASSAERR, Assure_exit, BIGCOUNT, EL, m_id, m_key, m_op_endcreate, m_op_lock, ASSA::SEM, and trace_with_mask.

◆ dump()

void Semaphore::dump ( void  ) const

Dump the objects state along with the state of the semaphore (if connected) to the log file.

Definition at line 292 of file Semaphore.cpp.

294{
295 trace_with_mask("Semaphore::dump", SEM);
296
297 std::ostringstream msg;
298 msg << "\n\n\tKey.....: ";
299
300 if (m_key == (key_t) -1) {
301 msg << m_key;
302 }
303 else {
304 msg << "0x" << std::hex << m_key << std::dec;
305 }
306
307 msg << "\n\tID......: " << m_id << "\n\n";
308
309 if (m_id >= 0 && m_key >= (key_t) -1) {
310 msg << "\tsemval [0]\tproc counter[1]\tlock [2]\n"
311 << "\t----------\t---------------\t--------\n";
312
313 /*--- Get value of element in semaphore set ---*/
314 msg << "\t " << semctl (m_id, 0, GETVAL)
315 << "\t\t " << semctl (m_id, 1, GETVAL)
316 << "\t\t " << semctl (m_id, 2, GETVAL);
317 }
318 else {
319 msg << "Semaphore id = -1. No info is available.";
320 }
321 msg << std::ends;
322 DL((SEM,"%s\n\n", msg.str ().c_str ()));
323}
#define DL(X)
A macro for writing debug message to the Logger.
Definition Logger.h:273

References DL, m_id, m_key, ASSA::SEM, and trace_with_mask.

Referenced by op().

◆ id()

int ASSA::Semaphore::id ( ) const
inline

Get id.

Definition at line 137 of file Semaphore.h.

137{ return m_id; }

References m_id.

◆ init()

void ASSA::Semaphore::init ( )
inlineprotected

Initalize by invalidating data members.

Definition at line 210 of file Semaphore.h.

212{
213 m_key = (key_t) -1;
214 m_id = -1;
215}

References m_id, and m_key.

Referenced by close(), remove(), and Semaphore().

◆ key()

key_t ASSA::Semaphore::key ( ) const
inline

Get key.

Definition at line 134 of file Semaphore.h.

134{ return m_key; }

References m_key.

◆ op()

void Semaphore::op ( int  val_)

General semaphore operation.

Increment or decrement by a user-specified amount (positive or negative; amount can't be zero!).

Definition at line 261 of file Semaphore.cpp.

263{
264 /* Test if m_id is still valid. If it fails, then
265 * next operation is failing because of it. If not,
266 * then something else happens here.
267 */
268 trace_with_mask("Semaphore::op", SEM);
269
270 int semval = 0;
271 dump ();
272
273 if ((semval = semctl (m_id, 1, GETVAL, 0)) < 0) {
274 EL((ASSAERR,"Can't GETVAL\n"));
275 Assure_exit (false);
276 }
277
278 /* This will fail on Solaris? */
279
280 if ((m_op_op[0].sem_op = value_) == 0) {
281 EL((ASSAERR,"Can't have value_ == 0\n"));
282 Assure_exit(false);
283 }
284
285 if (semop (m_id, &m_op_op[0], 1) < 0) {
286 EL((ASSAERR,"sem_op error\n"));
287 Assure_exit(false);
288 }
289}
static sembuf m_op_op[1]
Decrement or increment semaphore with undo on exit.
Definition Semaphore.h:186
void dump(void) const
Dump the objects state along with the state of the semaphore (if connected) to the log file.

References ASSA::ASSAERR, Assure_exit, dump(), EL, m_id, m_op_op, ASSA::SEM, and trace_with_mask.

Referenced by signal(), and wait().

◆ open()

int Semaphore::open ( key_t  key_)

Open a semaphore that must already exist.

This function should be used, instead of Semaphore::create (), if the caller knows that the semaphore must already exist. For example, a client from a client-server pair would use this, if its server's responsibility to create the semaphore.

Parameters
key_Semaphore's key
Returns
The semaphore id if OK, else -1.

Definition at line 173 of file Semaphore.cpp.

175{
176 trace_with_mask("Semaphore::open", SEM);
177
178 if (IPC_PRIVATE == key_) {
179 EL((ASSAERR,"Not intended for private semaphores\n"));
180 return (-1);
181 }
182 else if (key_ == (key_t) -1) {
183 EL((ASSAERR,"Probably an ftok() error by caller\n"));
184 return (-1);
185 }
186
187 m_key = key_;
188
189 if ((m_id = semget (m_key, 3, 0)) < 0) {
190 EL((ASSAERR,"Error on semget(3)"));
191 return (-1);
192 }
193 /*--- Decrement the process counter. No need for lock ---*/
194
195 if (semop (m_id, &m_op_open[0], 1) < 0) {
196 EL((ASSAERR,"Error on semget(open)\n"));
197 Assure_exit(false);
198 }
199 return (m_id);
200}
static sembuf m_op_open[2]
Decrement process counter with undo on exit.
Definition Semaphore.h:171

References ASSA::ASSAERR, Assure_exit, EL, m_id, m_key, m_op_open, ASSA::SEM, and trace_with_mask.

◆ remove()

void Semaphore::remove ( )

Remove a semaphore.

This call is intended to be called by a server, for example, when it is being shut down, as we do an IPC_RMID on the semaphore, regardless whether other processes may be using it or not. Most other processes should use Semaphore::close () instead. Calling this method also invalidates object for subsequent operations.

Definition at line 203 of file Semaphore.cpp.

205{
206 trace_with_mask("Semaphore::remove", SEM);
207
208 if (m_id < 0 || m_key == ((key_t) -1) ) return;
209
210 if (semctl (m_id, 0, IPC_RMID, 0) < 0) {
211 EL((ASSAERR,"Can't IPC_RMID\n"));
212 Assure_exit(false);
213 }
214 init ();
215}

References ASSA::ASSAERR, Assure_exit, EL, init(), m_id, m_key, ASSA::SEM, and trace_with_mask.

Referenced by close().

◆ signal()

void ASSA::Semaphore::signal ( )
inline

Increment a semaphore by 1.

Tanenbaum's UP operation.

Definition at line 226 of file Semaphore.h.

228{
229 trace_with_mask("Semaphore::signal", SEM);
230 op (1);
231}
void op(int val_)
General semaphore operation.

References op(), ASSA::SEM, and trace_with_mask.

◆ wait()

void ASSA::Semaphore::wait ( )
inline

Wait until a semaphore's value is greater then 0, then decrement it by 1 and return.

Tanenbaum's DOWN operation.

Definition at line 218 of file Semaphore.h.

220{
221 trace_with_mask("Semaphore::wait", SEM);
222 op (-1);
223}

References op(), ASSA::SEM, and trace_with_mask.

Member Data Documentation

◆ BIGCOUNT

const int ASSA::Semaphore::BIGCOUNT = 10000
staticprotected

Definition at line 157 of file Semaphore.h.

Referenced by close(), and create().

◆ m_id

int ASSA::Semaphore::m_id
protected

Semaphore's id.

Definition at line 154 of file Semaphore.h.

Referenced by close(), create(), dump(), id(), init(), op(), open(), remove(), and ~Semaphore().

◆ m_key

key_t ASSA::Semaphore::m_key
protected

Semaphore's key.

Definition at line 151 of file Semaphore.h.

Referenced by create(), dump(), init(), key(), open(), and remove().

◆ m_op_close

sembuf Semaphore::m_op_close
staticprotected
Initial value:
=
{
{2, 0, 0},
{2, 1, SEM_UNDO},
{1, 1, SEM_UNDO}
}

Wait for lock to equal 0, then increment lock to 1 (lock it), then increment process counter.

Definition at line 176 of file Semaphore.h.

Referenced by close().

◆ m_op_endcreate

sembuf Semaphore::m_op_endcreate
staticprotected
Initial value:
=
{
{1, -1, SEM_UNDO},
{2, -1, SEM_UNDO}
}

Decrement process counter with undo on exit, then decrement lock back to 0.

Definition at line 166 of file Semaphore.h.

Referenced by create().

◆ m_op_lock

sembuf Semaphore::m_op_lock
staticprotected
Initial value:
=
{
{2, 0, 0},
{2, 1, SEM_UNDO}
}

Wait for lock to equal 0, then increment lock to 1 - this locks it.

Definition at line 161 of file Semaphore.h.

Referenced by create().

◆ m_op_op

sembuf Semaphore::m_op_op
staticprotected
Initial value:
=
{
{0, 99, SEM_UNDO}
}

Decrement or increment semaphore with undo on exit.

The 99 is set to the actual amount to add or substract (positive or negative).

Definition at line 186 of file Semaphore.h.

Referenced by op().

◆ m_op_open

sembuf Semaphore::m_op_open
staticprotected
Initial value:
=
{
{1, -1, SEM_UNDO},
}

Decrement process counter with undo on exit.

Definition at line 171 of file Semaphore.h.

Referenced by open().

◆ m_op_unlock

sembuf Semaphore::m_op_unlock
staticprotected
Initial value:
=
{
{2, -1, SEM_UNDO}
}

Decremetn lock back to 0.

Definition at line 180 of file Semaphore.h.

Referenced by close().


The documentation for this class was generated from the following files: