semian 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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