posix-semaphore 0.5

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.
data/README ADDED
@@ -0,0 +1,11 @@
1
+ .. /\
2
+ ||/ /
3
+ | /
4
+ | /
5
+ ___ ___ ___ _____ ___ _ ___ _
6
+ | _ \/ _ \/ __|_ _\ \/ (_|_) __| ___ _ __ __ _ _ __| |_ ___ _ _ ___
7
+ | _/ (_) \__ \| | > < _ _\__ \/ -_) ' \/ _` | '_ \ ' \/ _ \ '_/ -_)
8
+ |_| \___/|___/___/_/\_(_|_)___/\___|_|_|_\__,_| .__/_||_\___/_| \___|
9
+ |_|
10
+
11
+ Currently only named semaphores are supported.
@@ -0,0 +1,11 @@
1
+ # Loads mkmf which is used to make makefiles for Ruby extensions
2
+ require 'mkmf'
3
+
4
+ # Give it a name
5
+ extension_name = 'posix_semaphore_ext'
6
+
7
+ # The destination
8
+ dir_config(extension_name)
9
+
10
+ # Do the work
11
+ create_makefile(extension_name)
@@ -0,0 +1,128 @@
1
+
2
+ #include "ruby.h"
3
+ #include <semaphore.h>
4
+ #include <time.h>
5
+ #include <errno.h>
6
+
7
+ VALUE mPOSIX = Qnil;
8
+
9
+ void Init_posix_semaphore_ext();
10
+ VALUE method_sem_open(int argc, VALUE* argv, VALUE self);
11
+ VALUE method_sem_wait(VALUE self, VALUE semid);
12
+ VALUE method_sem_trywait(VALUE self, VALUE semid);
13
+ VALUE method_sem_timedwait(VALUE self, VALUE semid, VALUE timeout);
14
+ VALUE method_sem_post(VALUE self, VALUE semid);
15
+ VALUE method_sem_close(VALUE self, VALUE semid);
16
+ // VALUE method_sem_getvalue(VALUE self, VALUE semid);
17
+ VALUE method_sem_unlink(VALUE self, VALUE semid);
18
+
19
+ void Init_posix_semaphore_ext() {
20
+ mPOSIX = rb_define_module("POSIX");
21
+ rb_define_singleton_method(mPOSIX, "sem_open", method_sem_open, -1);
22
+ rb_define_singleton_method(mPOSIX, "sem_wait", method_sem_wait, 1);
23
+ rb_define_singleton_method(mPOSIX, "sem_trywait", method_sem_trywait, 1);
24
+ rb_define_singleton_method(mPOSIX, "sem_timedwait", method_sem_timedwait, 2);
25
+ rb_define_singleton_method(mPOSIX, "sem_post", method_sem_post, 1);
26
+ rb_define_singleton_method(mPOSIX, "sem_close", method_sem_close, 1);
27
+ // rb_define_singleton_method(mPOSIX, "sem_getvalue", method_sem_getvalue, 1);
28
+ rb_define_singleton_method(mPOSIX, "sem_unlink", method_sem_unlink, 1);
29
+ }
30
+
31
+ VALUE method_sem_open(int argc, VALUE *argv, VALUE self) {
32
+ if (argc < 2 || argc > 4) {
33
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..4)", argc);
34
+ }
35
+ VALUE name = argv[0];
36
+ VALUE oflag = argv[1];
37
+ Check_Type(name, T_STRING);
38
+ Check_Type(oflag, T_FIXNUM);
39
+ sem_t* semaphore;
40
+
41
+ if (argc == 2) {
42
+ semaphore = sem_open(StringValueCStr(name), FIX2INT(oflag));
43
+ } else {
44
+ VALUE mode = argv[2];
45
+ VALUE value;
46
+ if (argc == 4) {
47
+ value = argv[3];
48
+ } else {
49
+ value = INT2FIX(1);
50
+ }
51
+ Check_Type(mode, T_FIXNUM);
52
+ Check_Type(value, T_FIXNUM);
53
+ semaphore = sem_open(StringValueCStr(name), FIX2INT(oflag), FIX2INT(mode), FIX2INT(value));
54
+ }
55
+
56
+ if (semaphore == SEM_FAILED) {
57
+ rb_sys_fail(0);
58
+ }
59
+
60
+ return INT2FIX(semaphore);
61
+ }
62
+
63
+ VALUE method_sem_wait(VALUE self, VALUE semid) {
64
+ Check_Type(semid, T_FIXNUM);
65
+
66
+ int result = sem_wait((sem_t*) FIX2LONG(semid));
67
+ if (result < 0) rb_sys_fail(0);
68
+
69
+ return INT2FIX(result);
70
+ }
71
+
72
+ VALUE method_sem_trywait(VALUE self, VALUE semid) {
73
+ Check_Type(semid, T_FIXNUM);
74
+
75
+ int result = sem_trywait((sem_t*) FIX2LONG(semid));
76
+ if (result < 0) rb_sys_fail(0);
77
+
78
+ return INT2FIX(result);
79
+ }
80
+
81
+ VALUE method_sem_timedwait(VALUE self, VALUE semid, VALUE timeout) {
82
+ Check_Type(semid, T_FIXNUM);
83
+
84
+ struct timespec ts = rb_time_timespec(timeout);
85
+
86
+ int result = sem_timedwait((sem_t*) FIX2LONG(semid), &ts);
87
+ if (result < 0) rb_sys_fail(0);
88
+
89
+ return INT2FIX(result);
90
+ }
91
+
92
+ VALUE method_sem_post(VALUE self, VALUE semid) {
93
+ Check_Type(semid, T_FIXNUM);
94
+
95
+ int result = sem_post((sem_t*) FIX2LONG(semid));
96
+ if (result < 0) rb_sys_fail(0);
97
+
98
+ return INT2FIX(result);
99
+ }
100
+
101
+ VALUE method_sem_close(VALUE self, VALUE semid) {
102
+ Check_Type(semid, T_FIXNUM);
103
+
104
+ int result = sem_close((sem_t*) FIX2LONG(semid));
105
+ if (result < 0) rb_sys_fail(0);
106
+
107
+ return INT2FIX(result);
108
+ }
109
+
110
+ // diked out, too buggy
111
+ // VALUE method_sem_getvalue(VALUE self, VALUE semid) {
112
+ // Check_Type(semid, T_FIXNUM);
113
+ // int sval;
114
+ //
115
+ // int result = sem_getvalue((sem_t*) FIX2LONG(semid), &sval);
116
+ // if (result < 0) rb_sys_fail(0);
117
+ //
118
+ // return INT2FIX(sval);
119
+ // }
120
+
121
+ VALUE method_sem_unlink(VALUE self, VALUE name) {
122
+ Check_Type(name, T_STRING);
123
+
124
+ int result = sem_unlink(StringValueCStr(name));
125
+ if (result < 0) rb_sys_fail(0);
126
+
127
+ return INT2FIX(result);
128
+ }
@@ -0,0 +1,3 @@
1
+
2
+ require 'posix/semaphore'
3
+
@@ -0,0 +1,66 @@
1
+
2
+ require 'posix_semaphore_ext'
3
+ require 'posix/semaphore/mutex'
4
+
5
+ module POSIX
6
+ class Semaphore
7
+ attr_reader :id, :name
8
+
9
+ def initialize name, mode=File::CREAT, perms=0611, value=1
10
+ @id = POSIX.sem_open name, mode, perms, value
11
+ @name = name
12
+ end
13
+
14
+ def wait timeout=nil
15
+ if timeout.nil?
16
+ POSIX.sem_wait @id
17
+ true
18
+ else
19
+ begin
20
+ if timeout.is_a? Numeric
21
+ timeout = Time.now + timeout
22
+ elsif defined? DateTime and timeout.is_a? DateTime
23
+ timeout = timeout.to_time
24
+ end
25
+ POSIX.sem_timedwait @id, timeout
26
+ rescue Errno::ETIMEDOUT
27
+ return false
28
+ rescue
29
+ end
30
+ end
31
+ end
32
+ def wait_nonblock
33
+ POSIX.sem_trywait @id
34
+ end
35
+
36
+ def post
37
+ POSIX.sem_post @id
38
+ end
39
+
40
+ def close
41
+ POSIX.sem_close @id
42
+ end
43
+ def unlink
44
+ self.class.unlink @name
45
+ end
46
+
47
+ def self.unlink name
48
+ POSIX.sem_unlink name
49
+ end
50
+
51
+ def zero?
52
+ begin
53
+ wait_nonblock
54
+ rescue Errno::EAGAIN
55
+ return true
56
+ end
57
+ post
58
+ return false
59
+ end
60
+ alias locked? zero?
61
+
62
+ def inspect
63
+ "#<#{self.class.name}:#@id name:#{@name.inspect}>"
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module POSIX
3
+ class Semaphore
4
+ # Mutex provides a simple wrapper to provide a POSIX-based version
5
+ # of Ruby's built-in Mutex class.
6
+ #
7
+ # All you need to do to switch from using Ruby's Mutex to using this
8
+ # is change Mutex.new to POSIX::Semaphore::Mutex.new, providing
9
+ # options that are the same as those to POSIX::Semaphore.new.
10
+ class Mutex
11
+ def initialize *args
12
+ @semaphore = Semaphore.new *args
13
+ @have_lock = false
14
+ end
15
+
16
+ def lock *a
17
+ raise ThreadError, 'this mutex is already locked to us' if @have_lock
18
+ @semaphore.wait *a
19
+ @have_lock = true
20
+ end
21
+ def locked?
22
+ @have_lock or @semaphore.locked?
23
+ end
24
+
25
+ def synchronize *a
26
+ lock *a
27
+ begin
28
+ yield
29
+ ensure
30
+ unlock
31
+ end
32
+ end
33
+
34
+ def try_lock
35
+ raise ThreadError, 'this mutex is already locked to us' if @have_lock
36
+ begin
37
+ @semaphore.wait_nonblock
38
+ rescue Errno::EAGAIN
39
+ return false
40
+ end
41
+ return (@have_lock = true)
42
+ end
43
+
44
+ def unlock
45
+ @semaphore.post
46
+ @have_lock = false
47
+ end
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,29 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.name = 'posix-semaphore'
4
+ s.version = '0.5'
5
+
6
+ s.summary = 'Access to the POSIX semaphore APIs in Ruby'
7
+ s.description = 'Cross-thread, cross-process synchronisation made tolerably easy'
8
+
9
+ s.homepage = 'http://github.com/dpkendal/posix-semaphore'
10
+
11
+ s.authors = ['David Kendal']
12
+
13
+ s.extensions = ['ext/extconf.rb']
14
+ s.require_paths = ['lib']
15
+
16
+ s.files = %w{
17
+ ext
18
+ ext/extconf.rb
19
+ ext/posix-semaphore.c
20
+ lib
21
+ lib/posix
22
+ lib/posix/semaphore
23
+ lib/posix/semaphore/mutex.rb
24
+ lib/posix/semaphore.rb
25
+ lib/posix-semaphore.rb
26
+ posix-semaphore.gemspec
27
+ README
28
+ }
29
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: posix-semaphore
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.5'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - David Kendal
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Cross-thread, cross-process synchronisation made tolerably easy
15
+ email:
16
+ executables: []
17
+ extensions:
18
+ - ext/extconf.rb
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ext/extconf.rb
22
+ - ext/posix-semaphore.c
23
+ - lib/posix/semaphore/mutex.rb
24
+ - lib/posix/semaphore.rb
25
+ - lib/posix-semaphore.rb
26
+ - posix-semaphore.gemspec
27
+ - README
28
+ homepage: http://github.com/dpkendal/posix-semaphore
29
+ licenses: []
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.6
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: Access to the POSIX semaphore APIs in Ruby
52
+ test_files: []