-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSemaphore.hpp
157 lines (117 loc) · 3.19 KB
/
Semaphore.hpp
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
#ifndef _SEMAPHORE_HPP_
#define _SEMAPHORE_HPP_
/*
Name
Semaphore
Authors
[ETL] Eun T. Leem ([email protected])
Description
Last Modified Date
Mar 2, 2013
Learning Resources
Semaphores Tutorial
http://beej.us/guide/bgipc/output/html/multipage/semaphores.html
semget
http://linux.die.net/man/2/semget
Copyright (c) All Rights reserved to LIFEINO.
*/
#ifdef _DEBUG
#undef _DEBUG
#endif
#define _DEBUG false
#include "Debug.hpp" //DEBUG_cout
#include <errno.h> // errno
#include <sys/types.h>
#include <sys/ipc.h> // ftok()
#include <linux/sem.h> // semun SEMMSL
#include <sys/sem.h> // semget() semctl() semop()
#include <string>
#include "Util.hpp"
namespace lio {
using std::string;
/*union semun {
int val; // used for SETVAL only
struct semid_ds *buf; used for IPC_STAT and IPC_SET
ushort *array; used for GETALL and SETALL
};
*/
class Semaphore {
public:
enum class ExceptionType {
GENERAL,
INVALID_KEY,
SEM_INIT_FAILED,
SEM_EXISTS,
SEM_ACCESS_DENIED,
SEM_GET_FAILED,
SEM_UNSET_FAILED
};
#define SEMAPHORE_EXCEPTION_MESSAGES \
"Semaphore Exception has been thrown.", \
"Invalid Keyfile path.", \
"Failed to initialize Semaphore.", \
"Semaphore already exists.", \
"Access to the semaphore is denied.", \
"Failed to get semaphore.", \
"Unset Semaphore has failed."
class Exception : public std::exception {
public:
Exception (ExceptionType exceptionType = ExceptionType::GENERAL);
virtual const char* what() const throw();
virtual const ExceptionType type() const throw();
private:
ExceptionType exceptionType_;
static const char* const exceptionMessages_[];
};
enum class Mode {
AUTO, // Try to Create, if already exists, LOAD.
CREATE, // initialize new one
LOAD // load already existing one
};
struct Config {
Config(string semKeyDir = "./",
string semKeyName = "semKey",
Mode semMode = Mode::AUTO,
int semPermission = 0666,
uint8_t semCount = 5
)
: semKeyDir(semKeyDir),
semKeyName(semKeyName),
semMode (semMode),
semPermission(semPermission),
semCount (semCount) {}
string semKeyDir;
string semKeyName;
Mode semMode;
int semPermission;
uint8_t semCount;
};
/**
* semCount: total number of semaphores to create. Multiple semaphores are created using one key. Determine how many you need. Max Number is Defined in SEMMSL
*
*/
Semaphore (Config& config);
virtual
~Semaphore();
bool Lock(int semNum = 0);
bool Release(int semNum = 0);
// When set to destroy, Semaphore will be delete when desctructor is called. (Semaphore is shared between processes and if not set to destroy, Semaphore will continue.)
void SetToDestroySemOnDelete();
// #DEPRECATED: use SetToDestroySemOnDelete
int DestroySem();
// Test Functions
void _PrintKey();
void _PrintSemId();
protected:
private:
Config config_;
key_t semKey_;
int semId_;
bool isSetToDestroySem_;
// Initiate Semaphores
int initSem();
void createSem();
void loadSem();
};
}
#endif