semian 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 569ed1de876236ee7b8aee71e9325fd609f6a65c
4
- data.tar.gz: 1308dfeea5b5f554d97397a5eb79bfca484d6854
3
+ metadata.gz: 85e7688d4e7394755e61fe1223f33646a9245f69
4
+ data.tar.gz: fc55fda5e5799267fc81f3fed586117f62762dc0
5
5
  SHA512:
6
- metadata.gz: 1e4e89901bc8654a0003e2a097984520508cf4143735d2d8dd35c0c9112ad292d0ca044f7471e54947a2ec974d07322719174d15226e7ce147140c63cac597c7
7
- data.tar.gz: ecf5a1656a9bc1f51111eb9274ebb73844e40161e67894f1abe57dfbd59364e2007d7b5c5b6c5de652b6063d597741f372895b6251fef95316d790c4560022ca
6
+ metadata.gz: f04b5bc23920ab15e8fb1a73890a66a7ce4719e8286eff31170506460680853dfc302cfc4683eeb33c03cf168b72f7ef9f235a16a66ace28456026ddd60e00bb
7
+ data.tar.gz: 2eed26a9736cd3114b172bce7ecbd7cfa77d6ef8601acd78ba18ea7c166c6b2fa7103e2cd78b74d9f30b2c75a3229934a198dbf8881529b452ba6b03e10cb75a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- semian (0.0.1)
4
+ semian (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/ext/semian/semian.c CHANGED
@@ -23,7 +23,7 @@ typedef VALUE (*my_blocking_fn_t)(void*);
23
23
  #endif
24
24
 
25
25
  static ID id_timeout;
26
- static VALUE eTimeout;
26
+ static VALUE eSyscall, eTimeout;
27
27
 
28
28
  typedef struct {
29
29
  int sem_id;
@@ -48,6 +48,12 @@ ms_to_timespec(long ms, struct timespec *ts)
48
48
  ts->tv_nsec = (ms % 1000) * 1000000;
49
49
  }
50
50
 
51
+ static void
52
+ raise_semian_syscall_error(const char *syscall, int error_num)
53
+ {
54
+ rb_raise(eSyscall, "%s failed, errno: %d (%s)", syscall, error_num, strerror(error_num));
55
+ }
56
+
51
57
  static void
52
58
  semian_resource_mark(void *ptr)
53
59
  {
@@ -128,12 +134,12 @@ semian_resource_initialize(VALUE self, VALUE id, VALUE tickets, VALUE default_ti
128
134
 
129
135
  res->sem_id = semget(key, 1, flags);
130
136
  if (res->sem_id == -1) {
131
- rb_sys_fail("semget");
137
+ raise_semian_syscall_error("semget()", errno);
132
138
  }
133
139
 
134
140
  if (FIX2LONG(tickets) != 0
135
141
  && semctl(res->sem_id, 0, SETVAL, FIX2LONG(tickets)) == -1) {
136
- rb_sys_fail("semctl");
142
+ raise_semian_syscall_error("semctl()", errno);
137
143
  }
138
144
 
139
145
  return self;
@@ -144,7 +150,7 @@ cleanup_semian_resource_acquire(VALUE self)
144
150
  {
145
151
  semian_resource_t *res = NULL;
146
152
  TypedData_Get_Struct(self, semian_resource_t, &semian_resource_type, res);
147
- struct sembuf buf = { 0, 1, 0 };
153
+ struct sembuf buf = { 0, 1, SEM_UNDO };
148
154
  if (semop(res->sem_id, &buf, 1) == -1) {
149
155
  res->error = errno;
150
156
  }
@@ -195,7 +201,7 @@ semian_resource_acquire(int argc, VALUE *argv, VALUE self)
195
201
  if (res.error == EAGAIN) {
196
202
  rb_raise(eTimeout, "timed out waiting for resource '%s'", res.name);
197
203
  } else {
198
- rb_raise(rb_eRuntimeError, "semop() error: %s (%d)", strerror(res.error), res.error);
204
+ raise_semian_syscall_error("semop()", res.error);
199
205
  }
200
206
  }
201
207
 
@@ -209,7 +215,7 @@ semian_resource_destroy(VALUE self)
209
215
 
210
216
  TypedData_Get_Struct(self, semian_resource_t, &semian_resource_type, res);
211
217
  if (semctl(res->sem_id, 0, IPC_RMID) == -1) {
212
- rb_sys_fail("semctl");
218
+ raise_semian_syscall_error("semctl()", errno);
213
219
  }
214
220
 
215
221
  return Qtrue;
@@ -224,7 +230,7 @@ semian_resource_count(VALUE self)
224
230
  TypedData_Get_Struct(self, semian_resource_t, &semian_resource_type, res);
225
231
  ret = semctl(res->sem_id, 0, GETVAL);
226
232
  if (ret == -1) {
227
- rb_raise(rb_eRuntimeError, "semctl() error: %s (%d)", strerror(errno), errno);
233
+ raise_semian_syscall_error("semctl()", errno);
228
234
  }
229
235
 
230
236
  return LONG2FIX(ret);
@@ -232,11 +238,13 @@ semian_resource_count(VALUE self)
232
238
 
233
239
  void Init_semian()
234
240
  {
235
- VALUE cSemian, cResource;
241
+ VALUE cSemian, cResource, eBaseError;
236
242
 
237
243
  cSemian = rb_define_class("Semian", rb_cObject);
238
244
  cResource = rb_define_class("Resource", cSemian);
239
- eTimeout = rb_define_class_under(cSemian, "Timeout", rb_eStandardError);
245
+ eBaseError = rb_define_class_under(cSemian, "BaseError", rb_eStandardError);
246
+ eSyscall = rb_define_class_under(cSemian, "SyscallError", eBaseError);
247
+ eTimeout = rb_define_class_under(cSemian, "TimeoutError", eBaseError);
240
248
 
241
249
  rb_define_alloc_func(cResource, semian_resource_alloc);
242
250
  rb_define_method(cResource, "initialize", semian_resource_initialize, 3);
data/lib/semian.rb CHANGED
@@ -16,3 +16,5 @@ class Semian
16
16
  end
17
17
  end
18
18
  end
19
+
20
+ require 'semian/version'
@@ -0,0 +1,3 @@
1
+ class Semian
2
+ VERSION = '0.0.2'
3
+ end
data/semian.gemspec CHANGED
@@ -1,6 +1,10 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+
3
+ require 'semian/version'
4
+
1
5
  Gem::Specification.new do |s|
2
6
  s.name = 'semian'
3
- s.version = '0.0.1'
7
+ s.version = Semian::VERSION
4
8
  s.summary = 'SysV semaphore based library for shared resource control'
5
9
  s.description = <<-DOC
6
10
  A Ruby C extention that is used to control access to shared resources
data/test/test_semian.rb CHANGED
@@ -5,7 +5,7 @@ require 'fileutils'
5
5
 
6
6
  class TestSemian < Test::Unit::TestCase
7
7
  def setup
8
- Semian[:testing].destroy rescue RuntimeError
8
+ Semian[:testing].destroy rescue Semian::BaseError
9
9
  end
10
10
 
11
11
  def test_register_invalid_args
@@ -22,7 +22,7 @@ class TestSemian < Test::Unit::TestCase
22
22
  end
23
23
 
24
24
  def test_register_with_no_tickets_raises
25
- assert_raises Errno::ENOENT do
25
+ assert_raises Semian::SyscallError do
26
26
  Semian.register :testing
27
27
  end
28
28
  end
@@ -50,7 +50,7 @@ class TestSemian < Test::Unit::TestCase
50
50
  t = Thread.start do
51
51
  m.synchronize do
52
52
  cond.wait_until { acquired }
53
- assert_raises Semian::Timeout do
53
+ assert_raises Semian::TimeoutError do
54
54
  Semian[:testing].acquire { refute true }
55
55
  end
56
56
  end
@@ -101,7 +101,7 @@ class TestSemian < Test::Unit::TestCase
101
101
  pid = fork do
102
102
  Semian.register :testing, timeout: 0.5
103
103
  Semian[:testing].acquire do
104
- assert_raises Semian::Timeout do
104
+ assert_raises Semian::TimeoutError do
105
105
  Semian[:testing].acquire { }
106
106
  end
107
107
  end
@@ -129,7 +129,7 @@ class TestSemian < Test::Unit::TestCase
129
129
  end
130
130
 
131
131
  sleep 0.1 until File.exists?(path)
132
- assert_raises Semian::Timeout do
132
+ assert_raises Semian::TimeoutError do
133
133
  Semian[:testing].acquire {}
134
134
  end
135
135
 
@@ -155,10 +155,24 @@ class TestSemian < Test::Unit::TestCase
155
155
  assert acquired
156
156
  end
157
157
 
158
+ def test_sem_undo
159
+ Semian.register :testing, tickets: 1
160
+
161
+ # Ensure we don't hit ERANGE errors caused by lack of SEM_UNDO on semop* calls
162
+ # by doing an acquire > SEMVMX (32767) times:
163
+ #
164
+ # See: http://lxr.free-electrons.com/source/ipc/sem.c?v=3.8#L419
165
+ (1 << 16).times do # do an acquire 64k times
166
+ Semian[:testing].acquire do
167
+ 1
168
+ end
169
+ end
170
+ end
171
+
158
172
  def test_destroy
159
173
  Semian.register :testing, tickets: 1
160
174
  Semian[:testing].destroy
161
- assert_raises RuntimeError do
175
+ assert_raises Semian::SyscallError do
162
176
  Semian[:testing].acquire { }
163
177
  end
164
178
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Francis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-26 00:00:00.000000000 Z
11
+ date: 2014-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -43,6 +43,7 @@ files:
43
43
  - ext/semian/extconf.rb
44
44
  - ext/semian/semian.c
45
45
  - lib/semian.rb
46
+ - lib/semian/version.rb
46
47
  - semian.gemspec
47
48
  - test/test_semian.rb
48
49
  homepage: https://github.com/csfrancis/semian