Belle II Software  release-05-01-25
SemaphoreLocker.cc
1 #include <framework/pcore/SemaphoreLocker.h>
2 #include <framework/logging/Logger.h>
3 
4 #include <sys/ipc.h>
5 #include <sys/sem.h>
6 
7 #include <cerrno>
8 #include <cstring>
9 
10 using namespace Belle2;
11 
12 int SemaphoreLocker::create(key_t semkey)
13 {
14  int semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | 0600);
15  if (semid >= 0) {
16  // POSIX doesn't guarantee any particular state of our fresh semaphore
17  int semval = 1; //unlocked state
18  if (semctl(semid, 0, SETVAL, semval) == -1) { //set 0th semaphore to semval
19  B2ERROR("Initializing semaphore with semctl() failed.");
20  }
21  } else if (errno == EEXIST) {
22  semid = semget(semkey, 1, 0600);
23  }
24  if (semid < 0) {
25  B2ERROR("Couldn't create semaphore with semget()! Maybe you have too many semaphores from aborted processes lying around, you can clean those up by running 'clear_basf2_ipc'.");
26  return semid;
27  }
28 
29  return semid;
30 }
31 
32 void SemaphoreLocker::destroy(int semId)
33 {
34  if (semctl(semId, 1, IPC_RMID) == -1) { //semnum=1 has no meaning, ignored
35  B2ERROR("Error in SemaphoreLocker::destroy(), semaphore " << semId << ", error: " << strerror(errno));
36  }
37 }
38 
40 {
41  int ignored = 0;
42  int val = semctl(semId, 0, GETVAL, ignored);
43  return (val == 0); //0: locked, 1: unlocked
44 
45 }
46 
47 namespace {
48  void doSemOp(int semID, int op)
49  {
50  struct sembuf sb;
51  sb.sem_num = 0;
52  sb.sem_op = op;
53  sb.sem_flg = 0;
54  while (semop(semID, &sb, 1) == -1) {
55  if (errno == EINTR) {
56  //interrupted by signal (e.g. window size changed), try again
57  continue;
58  } else {
59  B2FATAL("Another process was aborted, please check previous output for reasons. (" <<
60  strerror(errno) << " for semaphore " << semID << ")");
61  }
62  }
63  }
64 }
66 {
67  doSemOp(m_id, -1);
68 }
69 
71 {
72  doSemOp(m_id, 1);
73 }
74 
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::SemaphoreLocker::m_id
int m_id
semaphore id, see semget(2).
Definition: SemaphoreLocker.h:45
Belle2::SemaphoreLocker::unlock
void unlock()
Unlock the semaphore.
Definition: SemaphoreLocker.cc:70
Belle2::SemaphoreLocker::lock
void lock()
Lock the semaphore.
Definition: SemaphoreLocker.cc:65
Belle2::SemaphoreLocker::isLocked
static bool isLocked(int semId)
Return true if the given semaphore is locked.
Definition: SemaphoreLocker.cc:39
Belle2::SemaphoreLocker::create
static int create(key_t semkey)
Create a new semaphore and initialize it.
Definition: SemaphoreLocker.cc:12
Belle2::SemaphoreLocker::destroy
static void destroy(int semId)
Destroy the given semaphore.
Definition: SemaphoreLocker.cc:32