Loading...
Searching...
No Matches
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.

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

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

## ~Semaphore()

ASSA::Semaphore::~Semaphore | ( |  | ) |

inline virtual

Destructor.

Definition at line 199 of file Semaphore.h.

{
trace_with_mask("Semaphore::~Semaphore", SEM);
if (m_id > 0) {
this->close ();
}
}
ASSA::Semaphore::m_id
int m_id
Semaphore's id.
Definition Semaphore.h:154
ASSA::Semaphore::close
void close()
Close a semaphore.
Definition Semaphore.cpp:219

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.

{
trace_with_mask("Semaphore::close", SEM);
register int semval;
if (m_id < 0) return;
/*
First get the lock on semaphore, then increment process counter.
*/
if (semop (m_id, &m_op_close[0], 3) < 0) {
EL((ASSAERR,"Can't semop(2)\n"));
Assure_exit(false);
}
/*
Now that we have a lock, read the value of the process counter
to see if this is the last reference to the semaphore.
There is a race condition here (same as in Semaphore::create()).
*/
if ((semval = semctl (m_id, 1, GETVAL, 0)) < 0) {
EL((ASSAERR,"Can't GETVAL\n"));
Assure_exit(false);
}
if (semval > BIGCOUNT) {
EL((ASSAERR,"sem[1] > BIGCOUNT\n"));
Assure_exit(false);
}
else if (semval == BIGCOUNT) {
remove ();
}
else if (semop (m_id, &m_op_unlock[0], 1) < 0) {
EL((ASSAERR,"Can't unlock\n"));
Assure_exit(false);
}
/*--- Invalidate ---*/
init ();
}
Assure_exit
#define Assure_exit(exp_)
Macro that makes program exit if assert fails.
Definition Assure.h:39
EL
#define EL(X)
A macro for writing error message to the Logger.
Definition Logger.h:285
ASSA::Semaphore::remove
void remove()
Remove a semaphore.
Definition Semaphore.cpp:204
ASSA::Semaphore::m_op_unlock
static sembuf m_op_unlock[1]
Decremetn lock back to 0.
Definition Semaphore.h:180
ASSA::Semaphore::m_op_close
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
ASSA::Semaphore::BIGCOUNT
static const int BIGCOUNT
Definition Semaphore.h:157
ASSA::ASSAERR
@ 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.

{
trace_with_mask("Semaphore::create", SEM);
register int semval;
union semnum {
int val;
struct semid_ds* buf;
ushort* array;
} semctrl_arg;
if (IPC_PRIVATE == key_) {
EL((ASSAERR,"Not intended for private semaphores\n"));
return (-1);
}
else if (key_ == (key_t) -1) {
EL((ASSAERR,"Probably an ftok() error by caller\n"));
return (-1);
}
m_key = key_;
bool done = false;
while (!done) {
if ( (m_id = semget (m_key, 3, 0666 | IPC_CREAT)) < 0) {
EL((ASSAERR,"Permission problem or kernel tables full\n"));
return (-1);
}
/*
When the semaphore is created, we know that the value of
all 3 set members is 0.
Get a lock on the semaphore by waiting for [2] to equal 0,
then increment it.
There is a race condition here. There is a possibility
that between the semget(2) and semop(2) below, another
process can cal Semaphore:::close () member function
which can remove a semaphore if that process is the last
one using it.
Therefore, we handle the error condition of an invalid
semaphore ID specially below, and if it does happen, we
just go back and create it again.
*/
if (semop (m_id, &m_op_lock[0], 2) < 0) {
if (errno == EINVAL) {
continue;
}
EL((ASSAERR,"Can't lock semaphore\n"));
Assure_exit (false);
}
done = true;
} // while (!done)
/*
Get the value of the process counter. If it equals 0,
then no one has initialized the semaphore yet.
*/
if ((semval = semctl (m_id, 1, GETVAL, 0)) < 0) {
EL((ASSAERR,"Can't GETVAL\n"));
Assure_exit (false);
}
if (semval == 0) {
/*
We could initalize by doing a SETALL, but that
would clear the adjust value that we set when
we locked the semaphore above. Instead, we'll do
two system calls to initialize semaphore value [0]
and process counter [1].
*/
semctrl_arg.val = initval_;
if (semctl (m_id, 0, SETVAL, semctrl_arg) < 0) {
EL((ASSAERR,"Can't SETVAL[0]\n"));
Assure_exit (false);
}
semctrl_arg.val = BIGCOUNT;
if (semctl (m_id, 1, SETVAL, semctrl_arg) < 0) {
EL((ASSAERR,"Can't SETVAL[1]\n"));
Assure_exit (false);
}
} // if (semval == 0)
/*--- Decrement the process counter and then release the lock. ---*/
if (semop (m_id, &m_op_endcreate[0], 2) < 0) {
EL((ASSAERR,"Error on semop (ndcreate)\n"));
Assure_exit (false);
}
return (m_id);
}
ASSA::Semaphore::m_key
key_t m_key
Semaphore's key.
Definition Semaphore.h:151
ASSA::Semaphore::m_op_lock
static sembuf m_op_lock[2]
Wait for lock to equal 0, then increment lock to 1 - this locks it.
Definition Semaphore.h:161
ASSA::Semaphore::m_op_endcreate
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.

{
trace_with_mask("Semaphore::dump", SEM);
std::ostringstream msg;
msg << "\n\n\tKey.....: ";
if (m_key == (key_t) -1) {
msg << m_key;
}
else {
msg << "0x" << std::hex << m_key << std::dec;
}
msg << "\n\tID......: " << m_id << "\n\n";
if (m_id >= 0 && m_key >= (key_t) -1) {
msg << "\tsemval [0]\tproc counter[1]\tlock [2]\n"
<< "\t----------\t---------------\t--------\n";
/*--- Get value of element in semaphore set ---*/
msg << "\t " << semctl (m_id, 0, GETVAL)
<< "\t\t " << semctl (m_id, 1, GETVAL)
<< "\t\t " << semctl (m_id, 2, GETVAL);
}
else {
msg << "Semaphore id = -1. No info is available.";
}
msg << std::ends;
DL((SEM,"%s\n\n", msg.str ().c_str ()));
}
DL
#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.

{ return m_id; }

References m_id.

## init()

void ASSA::Semaphore::init | ( |  | ) |

inline protected

Initalize by invalidating data members.

Definition at line 210 of file Semaphore.h.

{
m_key = (key_t) -1;
m_id = -1;
}

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.

{ 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.

{
/* Test if m_id is still valid. If it fails, then
* next operation is failing because of it. If not,
* then something else happens here.
*/
trace_with_mask("Semaphore::op", SEM);
int semval = 0;
dump ();
if ((semval = semctl (m_id, 1, GETVAL, 0)) < 0) {
EL((ASSAERR,"Can't GETVAL\n"));
Assure_exit (false);
}
/* This will fail on Solaris? */
if ((m_op_op[0].sem_op = value_) == 0) {
EL((ASSAERR,"Can't have value_ == 0\n"));
Assure_exit(false);
}
if (semop (m_id, &m_op_op[0], 1) < 0) {
EL((ASSAERR,"sem_op error\n"));
Assure_exit(false);
}
}
ASSA::Semaphore::m_op_op
static sembuf m_op_op[1]
Decrement or increment semaphore with undo on exit.
Definition Semaphore.h:186
ASSA::Semaphore::dump
void dump(void) const
Dump the objects state along with the state of the semaphore (if connected) to the log file.
Definition Semaphore.cpp:293

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.

{
trace_with_mask("Semaphore::open", SEM);
if (IPC_PRIVATE == key_) {
EL((ASSAERR,"Not intended for private semaphores\n"));
return (-1);
}
else if (key_ == (key_t) -1) {
EL((ASSAERR,"Probably an ftok() error by caller\n"));
return (-1);
}
m_key = key_;
if ((m_id = semget (m_key, 3, 0)) < 0) {
EL((ASSAERR,"Error on semget(3)"));
return (-1);
}
/*--- Decrement the process counter. No need for lock ---*/
if (semop (m_id, &m_op_open[0], 1) < 0) {
EL((ASSAERR,"Error on semget(open)\n"));
Assure_exit(false);
}
return (m_id);
}
ASSA::Semaphore::m_op_open
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.

{
trace_with_mask("Semaphore::remove", SEM);
if (m_id < 0 || m_key == ((key_t) -1) ) return;
if (semctl (m_id, 0, IPC_RMID, 0) < 0) {
EL((ASSAERR,"Can't IPC_RMID\n"));
Assure_exit(false);
}
init ();
}

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.

{
trace_with_mask("Semaphore::signal", SEM);
op (1);
}
ASSA::Semaphore::op
void op(int val_)
General semaphore operation.
Definition Semaphore.cpp:262

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.

{
trace_with_mask("Semaphore::wait", SEM);
op (-1);
}

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

## Member Data Documentation

## BIGCOUNT

const int ASSA::Semaphore::BIGCOUNT = 10000

static protected

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

static protected

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

static protected

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

static protected

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

static protected

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

static protected

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

static protected

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:

- Semaphore.h
- Semaphore.cpp