summaryrefslogtreecommitdiff
path: root/lib/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common.h')
-rw-r--r--lib/common.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/common.h b/lib/common.h
index 5aa4819..e757e3d 100644
--- a/lib/common.h
+++ b/lib/common.h
@@ -11,6 +11,7 @@
#include <stdint.h> // uint_64_t
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <string>
#include <openssl/md5.h> // MD5_*
@@ -281,4 +282,146 @@ class LogDuration
};
//***************************************************************************
+// Semaphore
+//***************************************************************************
+
+#include <sys/sem.h>
+
+class Sem
+{
+ public:
+
+ Sem(key_t aKey)
+ {
+ locked = no;
+ key = aKey;
+
+ if ((id = semget(key, 1, 0666 | IPC_CREAT)) == -1)
+ tell(0, "Error: Can't get semaphore, errno (%d) '%s'",
+ errno, strerror(errno));
+ }
+
+ ~Sem()
+ {
+ if (locked)
+ v();
+ }
+
+ // ----------------------
+ // get lock
+
+ int p()
+ {
+ sembuf sops[2];
+
+ sops[0].sem_num = 0;
+ sops[0].sem_op = 0; // wait for lock
+ sops[0].sem_flg = SEM_UNDO;
+
+ sops[1].sem_num = 0;
+ sops[1].sem_op = 1; // increment
+ sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, sops, 2) == -1)
+ {
+ tell(0, "Error: Can't lock semaphore, errno (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ locked = yes;
+
+ return success;
+ }
+
+ // ----------------------
+ // increment
+
+ int inc()
+ {
+ sembuf sops[1];
+
+ sops[0].sem_num = 0;
+ sops[0].sem_op = 1; // increment
+ sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, sops, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ locked = yes;
+
+ return success;
+ }
+
+ // ----------------------
+ // decrement
+
+ int dec()
+ {
+ return v();
+ }
+
+ // ----------------------
+ // check
+
+ int check()
+ {
+ sembuf sops[1];
+
+ sops[0].sem_num = 0;
+ sops[0].sem_op = 0;
+ sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, sops, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ return success;
+ }
+
+ // ----------------------
+ // release lock
+
+ int v()
+ {
+ sembuf sops;
+
+ sops.sem_num = 0;
+ sops.sem_op = -1; // release control
+ sops.sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, &sops, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ tell(0, "Error: Can't unlock semaphore, errno (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ locked = no;
+
+ return success;
+ }
+
+ private:
+
+ key_t key;
+ int id;
+ int locked;
+};
+
+//***************************************************************************
#endif //___COMMON_H