posix-semaphore 0.5

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