psem 0.0.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/ext/psem/psem.c +90 -84
  3. metadata +4 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cc49a5c2fb863dab11ff27cfc82f6cdbd4522f77438c0a072b166c32baf08dd
4
- data.tar.gz: c34963bdefe3a9024520602c4c7f417c9c5df14f2a653519980f530fb60eb458
3
+ metadata.gz: fb05a39b349b2b3112dd9ab2e60c22e703e5899fe68abb2d4dd9cf7bf4654b29
4
+ data.tar.gz: 22b83d7fc76a14a4f5a4ff19905cc2f6c29e7e8643213bf71421498a39e5ab55
5
5
  SHA512:
6
- metadata.gz: 0def52627a77ed1eddea9e58a9a14907de17465f999a92930f3ff3b00735f9372a7b0cd28bae00beb37000c681f4bb5d2356e70da95640fe217191d68ba09ae4
7
- data.tar.gz: 38cd4cbb971fd574cb8fa66295c6250b233a120f66b04a46a5e22cc50ee8839d0466128d9a06ea3facdf162b5b8b324c0a14d7c52c4e862a99503919204b9ce9
6
+ metadata.gz: ab2c2bb09068189156f862ab56441a2f9cab4e4c91f3d7d0771fce57dd6fe425e2f1e2bb7cc336cba6665591637f9270744342b05ac51a775627a1c99175c120
7
+ data.tar.gz: d6294aecb54955fa5ca3bcdaccf72d500981e1c1305b00ef7b2df05b7b160cd51db92e702fd5eaec9f93b9cb78f07f6593a94ed0d3116bcbfb148396f72d4a3a
@@ -5,17 +5,65 @@
5
5
  #include <errno.h>
6
6
  #include <time.h>
7
7
 
8
- static inline sem_t* get_current_semaphore(VALUE self)
9
- {
10
- sem_t* sem = (sem_t*)rb_ivar_get(self, rb_intern("inner"));
11
- if (sem == NULL) {
12
- rb_raise(rb_eRuntimeError, "inner semaphore is not initialized");
13
- }
14
- return sem;
8
+ static inline sem_t* get_current_semaphore(VALUE self) {
9
+ sem_t* sem = (sem_t*)rb_ivar_get(self, rb_intern("inner"));
10
+ if (sem == NULL) {
11
+ rb_raise(rb_eRuntimeError, "inner semaphore is not initialized");
12
+ }
13
+ return sem;
14
+ }
15
+
16
+ #ifdef _WIN32
17
+ #error Windows not supported
18
+ #elif __APPLE__
19
+ // OSX has this deprecated and removed
20
+ VALUE psem_waitmillis(VALUE self, VALUE rbNum_timeoutMillis) {
21
+ rb_raise(rb_eRuntimeError, "sem_timedwait() is deprecated on OSX");
22
+ }
23
+ // they also broke sem_getvalue to return 0 no matter what on a path
24
+ // to deprecation
25
+ VALUE psem_get_value(VALUE self) {
26
+ rb_raise(rb_eRuntimeError, "sem_getvalue() is deprecated on OSX");
27
+ }
28
+ #else
29
+ VALUE psem_waitmillis(VALUE self, VALUE rbNum_timeoutMillis) {
30
+ Check_Type(rbNum_timeoutMillis, T_FIXNUM);
31
+
32
+ int ms = FIX2INT(rbNum_timeoutMillis);
33
+ struct timespec ts;
34
+ ts.tv_sec = ms / 1000;
35
+ ts.tv_nsec = (ms % 1000) * 1000000;
36
+
37
+ sem_t* sem = get_current_semaphore(self);
38
+ if (sem_timedwait(sem, &ts) == -1) {
39
+ int err = errno;
40
+ switch (err) {
41
+ case ETIMEDOUT:
42
+ return Qfalse;
43
+ case EINTR:
44
+ rb_raise(rb_eRuntimeError, "got interrupted by a signal handler (EINTR)");
45
+ break;
46
+ case EINVAL:
47
+ rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore (EINVAL)");
48
+ break;
49
+ default:
50
+ rb_raise(rb_eRuntimeError, "unknown errno: %d", err);
51
+ }
52
+ }
53
+ return Qtrue;
15
54
  }
16
55
 
17
- VALUE psem_unlink(VALUE self, VALUE rbStr_semName)
18
- {
56
+ VALUE psem_get_value(VALUE self) {
57
+ sem_t* sem = get_current_semaphore(self);
58
+ int val = 0xFFFF;
59
+ if (sem_getvalue(sem, &val) == -1) {
60
+ rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore, failed with errno: %d", errno);
61
+ }
62
+ return INT2NUM(val);
63
+ }
64
+ #endif
65
+
66
+ VALUE psem_unlink(VALUE self, VALUE rbStr_semName) {
19
67
  Check_Type(rbStr_semName, T_STRING);
20
68
 
21
69
  // Check length and format of semaphore name
@@ -46,8 +94,7 @@ VALUE psem_unlink(VALUE self, VALUE rbStr_semName)
46
94
  return Qtrue;
47
95
  }
48
96
 
49
- VALUE psem_exists(VALUE self, VALUE rbStr_semName)
50
- {
97
+ VALUE psem_exists(VALUE self, VALUE rbStr_semName) {
51
98
  Check_Type(rbStr_semName, T_STRING);
52
99
 
53
100
  // Check length and format of semaphore name
@@ -64,7 +111,8 @@ VALUE psem_exists(VALUE self, VALUE rbStr_semName)
64
111
  return Qtrue;
65
112
  }
66
113
  else {
67
- switch (errno) {
114
+ int err = errno;
115
+ switch (err) {
68
116
  case ENOENT:
69
117
  // Does not exist
70
118
  return Qfalse;
@@ -73,20 +121,19 @@ VALUE psem_exists(VALUE self, VALUE rbStr_semName)
73
121
  return Qtrue;
74
122
  break;
75
123
  case ENAMETOOLONG:
76
- rb_raise(rb_eRuntimeError, "name was too long");
124
+ rb_raise(rb_eRuntimeError, "name was too long (ENAMETOOLONG)");
77
125
  break;
78
126
  case EINVAL:
79
- rb_raise(rb_eRuntimeError, "given name consists only of / and nothing else");
127
+ rb_raise(rb_eRuntimeError, "name consists only of / and nothing else (EINVAL)");
80
128
  break;
81
129
  default:
82
- rb_raise(rb_eRuntimeError, "unknown error");
130
+ rb_raise(rb_eRuntimeError, "unknown errno: %d", err);
83
131
  }
84
132
  }
85
133
  return Qnil;
86
134
  }
87
135
 
88
- VALUE psem_initialize(VALUE self, VALUE rbStr_semName, VALUE rbNum_initialValue)
89
- {
136
+ VALUE psem_initialize(VALUE self, VALUE rbStr_semName, VALUE rbNum_initialValue) {
90
137
  Check_Type(rbStr_semName, T_STRING);
91
138
  Check_Type(rbNum_initialValue, T_FIXNUM);
92
139
 
@@ -108,9 +155,7 @@ VALUE psem_initialize(VALUE self, VALUE rbStr_semName, VALUE rbNum_initialValue)
108
155
  // Create the semaphore
109
156
  sem_t* sem = sem_open(sem_name, O_CREAT, strtol("0644", 0, 8), initialValue);
110
157
  if (sem == SEM_FAILED) {
111
- char buf[64];
112
- snprintf(buf, 64, "sem_open() failed with errno: %d", errno);
113
- rb_raise(rb_eRuntimeError, buf);
158
+ rb_raise(rb_eRuntimeError, "sem_open() failed with errno: %d", errno);
114
159
  }
115
160
 
116
161
  // Set inner
@@ -118,123 +163,84 @@ VALUE psem_initialize(VALUE self, VALUE rbStr_semName, VALUE rbNum_initialValue)
118
163
  return self;
119
164
  }
120
165
 
121
- VALUE psem_get_value(VALUE self)
122
- {
123
- sem_t* sem = get_current_semaphore(self);
124
- int val = 0xFFFF;
125
- if (sem_getvalue(sem, &val) == -1) {
126
- rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore");
127
- }
128
- return INT2NUM(val);
129
- }
130
-
131
- VALUE psem_post(VALUE self)
132
- {
166
+ VALUE psem_post(VALUE self) {
133
167
  sem_t* sem = get_current_semaphore(self);
134
168
  if (sem_post(sem) == -1) {
135
- switch (errno) {
169
+ int err = errno;
170
+ switch (err) {
136
171
  case EINVAL:
137
- rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore");
172
+ rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore (EINVAL)");
138
173
  break;
139
174
  case EOVERFLOW:
140
- rb_raise(rb_eRuntimeError, "maximum allowable value for a semaphore would be exceeded");
175
+ rb_raise(rb_eRuntimeError, "maximum allowable value for a semaphore would be exceeded (EOVERFLOW)");
141
176
  break;
142
177
  default:
143
- rb_raise(rb_eRuntimeError, "unknown error");
178
+ rb_raise(rb_eRuntimeError, "unknown errno: %d", err);
144
179
  }
145
180
  }
146
181
  return Qnil;
147
182
  }
148
183
 
149
- VALUE psem_wait(VALUE self)
150
- {
184
+ VALUE psem_wait(VALUE self) {
151
185
  sem_t* sem = get_current_semaphore(self);
152
186
  if (sem_wait(sem) == -1) {
153
- switch (errno) {
187
+ int err = errno;
188
+ switch (err) {
154
189
  case EINTR:
155
- rb_raise(rb_eRuntimeError, "got interrupted by a signal handler");
190
+ rb_raise(rb_eRuntimeError, "got interrupted by a signal handler (EINTR)");
156
191
  break;
157
192
  case EINVAL:
158
- rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore");
193
+ rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore (EINVAL)");
159
194
  break;
160
195
  default:
161
- rb_raise(rb_eRuntimeError, "unknown error");
196
+ rb_raise(rb_eRuntimeError, "unknown errno: %d", err);
162
197
  }
163
198
  }
164
199
  return Qtrue;
165
200
  }
166
201
 
167
- VALUE psem_trywait(VALUE self)
168
- {
202
+ VALUE psem_trywait(VALUE self) {
169
203
  sem_t* sem = get_current_semaphore(self);
170
204
  if (sem_trywait(sem) == -1) {
171
- switch (errno) {
205
+ int err = errno;
206
+ switch (err) {
172
207
  case EAGAIN:
173
208
  return Qfalse;
174
209
  case EINTR:
175
- rb_raise(rb_eRuntimeError, "got interrupted by a signal handler");
176
- break;
177
- case EINVAL:
178
- rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore");
179
- break;
180
- default:
181
- rb_raise(rb_eRuntimeError, "unknown error");
182
- }
183
- }
184
- return Qtrue;
185
- }
186
-
187
- VALUE psem_waitmillis(VALUE self, VALUE rbNum_timeoutMillis)
188
- {
189
- Check_Type(rbNum_timeoutMillis, T_FIXNUM);
190
-
191
- int ms = FIX2INT(rbNum_timeoutMillis);
192
- struct timespec ts;
193
- ts.tv_sec = ms / 1000;
194
- ts.tv_nsec = (ms % 1000) * 1000000;
195
-
196
- sem_t* sem = get_current_semaphore(self);
197
- if (sem_timedwait(sem, &ts) == -1) {
198
- switch (errno) {
199
- case ETIMEDOUT:
200
- return Qfalse;
201
- case EINTR:
202
- rb_raise(rb_eRuntimeError, "got interrupted by a signal handler");
210
+ rb_raise(rb_eRuntimeError, "got interrupted by a signal handler (EINTR)");
203
211
  break;
204
212
  case EINVAL:
205
- rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore");
213
+ rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore (EINVAL)");
206
214
  break;
207
215
  default:
208
- rb_raise(rb_eRuntimeError, "unknown error");
216
+ rb_raise(rb_eRuntimeError, "unknown errno: %d", err);
209
217
  }
210
218
  }
211
219
  return Qtrue;
212
220
  }
213
221
 
214
- VALUE psem_close(VALUE self)
215
- {
222
+ VALUE psem_close(VALUE self) {
216
223
  sem_t* sem = get_current_semaphore(self);
217
224
  if (sem_close(sem) == -1) {
218
- switch (errno) {
225
+ int err = errno;
226
+ switch (err) {
219
227
  case EINVAL:
220
- rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore");
228
+ rb_raise(rb_eRuntimeError, "inner semaphore is not a valid semaphore (EINVAL)");
221
229
  break;
222
230
  default:
223
- rb_raise(rb_eRuntimeError, "unknown error");
231
+ rb_raise(rb_eRuntimeError, "unknown errno: %d", err);
224
232
  }
225
233
  }
226
234
  return Qnil;
227
235
  }
228
236
 
229
- VALUE psem_get_inner(VALUE self)
230
- {
237
+ VALUE psem_get_inner(VALUE self) {
231
238
  // Get inner as size_t type. Primarily for debugging purposes.
232
239
  size_t cast = (size_t)rb_ivar_get(self, rb_intern("inner"));
233
240
  return INT2NUM(cast);
234
241
  }
235
242
 
236
- void Init_psem()
237
- {
243
+ void Init_psem() {
238
244
  VALUE psemClass = rb_define_class("PSem", rb_cObject);
239
245
 
240
246
  // Initialize (does not change the value of the semaphore if it already exists
metadata CHANGED
@@ -1,19 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: psem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Can Selcik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-22 00:00:00.000000000 Z
11
+ date: 2019-02-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |
14
- A named semaphore is identified by a name of the form /somename; that is, a null-terminated string of up to 251 characters consisting of an initial slash, followed by one or more characters, none of which are slashes. Two processes can operate on the same named semaphore by passing the same name to sem_open.
15
-
16
- The sem_open function creates a new named semaphore or opens an existing named semaphore. After the semaphore has been opened, it can be operated on using sem_post and sem_wait. When a process has finished using the semaphore, it can use sem_close to close the semaphore. When all processes have finished using the semaphore, it can be removed from the system using sem_unlink.
13
+ description: Supports named semaphores both on Linux and OSX. "get_value" and "timedwait"
14
+ is deprecated on OSX but everything else is functional and safe.
17
15
  email: selcik.can@gmail.com
18
16
  executables: []
19
17
  extensions: