/usr/include/assa-3.5/assa/Semaphore.h is in libassa-3.5-5-dev 3.5.1-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | // -*- c++ -*-
//------------------------------------------------------------------------------
// $Id: Semaphore.h,v 1.5 2012/05/20 04:12:18 vlg Exp $
//------------------------------------------------------------------------------
// Semaphore.h
//------------------------------------------------------------------------------
// Copyright (c) 2000 by Vladislav Grinchenko
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#if !defined(WIN32)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "assa/Assure.h" // trace() & Assert family
namespace ASSA {
/** @file Semaphore.h
Semaphore class provides a simpler and easier interface to System V
semaphore system calls.
The very typical situation for the test programs is when the parent process
forks a child and then sends a signal to it to start some simulation process.
Depending on the system load and other external factors, it can take a
variable amount of time for the child process to initialize its internal
structures and install the appropriate signal handler. Semaphore is used
sychronize the parent and child processes, by letting them complete their
initialization sections.
Implementation Details:
We create and use a 3-member set for the requested semaphore.
The first member, [0], is the actual semaphore value, and the second
member, [1], is a counter used to know when all processes have finished
with the semaphore. The counter is initialized to a large number,
decremented on every Semaphore::create () or Semaphore::open (),
and incremented on every Semaphore::close ().
This way we can use "adjust" feature provided by System V so that
any process that exit's without calling Semaphore::close () is accounted
for. It doesn't help us if the last process does this (as we have
no way of getting control to remove the semaphore) but it will work if any
process other than the last does an exit (intentional or unintentional).
The third member, [2], of the semaphore set is used as a lock
variable to avoid any race conditions in the Semaphore::create () and
Semaphore::close () functions.
Note:
This class is a port to C++, inspired by: W. Richard Stevens from his
wonderful book, "Advanced programming in the UNIX Environment"
(Prentice Hall, 1992, ISBN 0-201-56317-7).
*/
class Semaphore
{
public:
/// Constructor.
Semaphore ();
/// Destructor.
virtual ~Semaphore ();
/** Create a semaphore with a specified initial value.
If the semaphore already exists, we don't initialize it (of course).
@param key_ Semaphore's key
@param initval_ Initiali value (default : 1)
@return The semaphore ID if all OK, else -1
*/
int create (key_t key_, int initval_ = 1);
/** 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.
@param key_ Semaphore's key
@return The semaphore id if OK, else -1.
*/
int open (key_t key_);
/** 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.
*/
void close ();
/** 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.
*/
void remove ();
/** Wait until a semaphore's value is greater then 0, then
decrement it by 1 and return. Tanenbaum's DOWN operation.
*/
void wait ();
/** Increment a semaphore by 1.
Tanenbaum's UP operation.
*/
void signal ();
/** General semaphore operation.
Increment or decrement by a user-specified amount
(positive or negative; amount can't be zero!).
*/
void op (int val_);
/// Get key.
key_t key () const { return m_key; }
/// Get id.
int id () const { return m_id; }
/** Dump the objects state along with the state of the semaphore
(if connected) to the log file.
*/
void dump (void) const;
protected:
/** Initalize by invalidating data members.
*/
void init ();
protected:
/// Semaphore's key
key_t m_key;
/// Semaphore's id
int m_id;
protected:
static const int BIGCOUNT;
/** Wait for lock to equal 0, then increment lock to 1 - this locks it.
*/
static sembuf m_op_lock [2];
/** Decrement process counter with undo on exit, then decrement
lock back to 0.
*/
static sembuf m_op_endcreate [2];
/** Decrement process counter with undo on exit.
*/
static sembuf m_op_open [2];
/** Wait for lock to equal 0, then increment lock to 1 (lock it),
then increment process counter.
*/
static sembuf m_op_close [3];
/** Decremetn lock back to 0.
*/
static sembuf m_op_unlock [1];
/** Decrement or increment semaphore with undo on exit. The 99
is set to the actual amount to add or substract (positive or
negative).
*/
static sembuf m_op_op [1];
};
inline
Semaphore::
Semaphore ()
{
trace_with_mask("Semaphore::Semaphore", SEM);
init ();
}
inline
Semaphore::
~Semaphore ()
{
trace_with_mask("Semaphore::~Semaphore", SEM);
if (m_id > 0) {
this->close ();
}
}
inline void
Semaphore::
init ()
{
m_key = (key_t) -1;
m_id = -1;
}
inline void
Semaphore::
wait ()
{
trace_with_mask("Semaphore::wait", SEM);
op (-1);
}
inline void
Semaphore::
signal ()
{
trace_with_mask("Semaphore::signal", SEM);
op (1);
}
} // end namespace ASSA
#endif /* !defined(WIN32) */
#endif /* SEMAPHORE_H */
|