posix_mq 0.1.0 → 0.2.0
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/ChangeLog +54 -0
- data/Documentation/posix-mq.rb.1.txt +7 -0
- data/GIT-VERSION-FILE +1 -1
- data/NEWS +10 -0
- data/README +39 -3
- data/ext/posix_mq/extconf.rb +3 -0
- data/ext/posix_mq/posix_mq.c +34 -13
- data/lib/posix_mq.rb +1 -1
- data/man/man1/posix-mq.rb.1 +9 -0
- data/test/test_posix_mq.rb +17 -1
- metadata +2 -2
data/ChangeLog
CHANGED
@@ -1,5 +1,59 @@
|
|
1
1
|
ChangeLog from git://git.bogomips.org/ruby_posix_mq.git ()
|
2
2
|
|
3
|
+
commit fd2fcdeee6b44f7854255cb7e01c81db3cd2d99c
|
4
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
5
|
+
Date: Sun Jan 3 05:46:45 2010 +0000
|
6
|
+
|
7
|
+
posix_mq 0.2.0
|
8
|
+
|
9
|
+
This release fixes notification (un)registration and should be
|
10
|
+
fully-supported on modern FreeBSD (7.2+) releases.
|
11
|
+
|
12
|
+
POSIX_MQ#notify=nil correctly unregister notification requests.
|
13
|
+
POSIX_MQ#notify=false now provids the no-op SIGEV_NONE
|
14
|
+
functionality. Under FreeBSD, using IO.select on POSIX_MQ
|
15
|
+
objects is now possible as it has always been under Linux.
|
16
|
+
|
17
|
+
commit 350bfc831938d84cc2d478f2cf88583863cb64fb
|
18
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
19
|
+
Date: Sun Jan 3 05:35:50 2010 +0000
|
20
|
+
|
21
|
+
support POSIX_MQ#to_io under FreeBSD
|
22
|
+
|
23
|
+
FreeBSD implements an __mq_oshandle(mqd_t mqd) function
|
24
|
+
to convert mqd_t to integer file descriptors.
|
25
|
+
|
26
|
+
commit 26015d39e9c848a536b4ea44802f858a4e6e74f7
|
27
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
28
|
+
Date: Sun Jan 3 04:17:56 2010 +0000
|
29
|
+
|
30
|
+
fix build under FreeBSD 7.2
|
31
|
+
|
32
|
+
FreeBSD seems to need some files explicitly included.
|
33
|
+
|
34
|
+
commit e7ac70686b3c09953f6c41966dbd77f77368a9ec
|
35
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
36
|
+
Date: Sat Jan 2 21:19:58 2010 -0800
|
37
|
+
|
38
|
+
doc: FreeBSD-specific notes + example code
|
39
|
+
|
40
|
+
commit 6f24b5626f89fbb6445c0943ba71f56c8945e18f
|
41
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
42
|
+
Date: Sat Jan 2 20:41:39 2010 -0800
|
43
|
+
|
44
|
+
Fix mq.notify = nil to unregister notifications
|
45
|
+
|
46
|
+
"mq.notify = false" also works now, doing what
|
47
|
+
"mq.notify = nil" used to do (using SIGEV_NONE).
|
48
|
+
|
49
|
+
I was confused by SIGEV_NONE usage vs using a NULL pointer for
|
50
|
+
the notification passed mq_notify(3). SIGEV_NONE does not
|
51
|
+
actually unregister, it registers a no-op notification which
|
52
|
+
prevents other processes from taking us.
|
53
|
+
|
54
|
+
This also fixes the test case to pass under both Linux and
|
55
|
+
FreeBSD.
|
56
|
+
|
3
57
|
commit 522d4d1472c216bd95a16ca5b118bc14693aad64
|
4
58
|
Author: Eric Wong <normalperson@yhbt.net>
|
5
59
|
Date: Sat Jan 2 02:33:23 2010 -0800
|
@@ -146,8 +146,15 @@ portability.
|
|
146
146
|
Exit status is normally 0. Exit status is 2 if a timeout occurs, 1 for
|
147
147
|
all other errors.
|
148
148
|
|
149
|
+
Under FreeBSD, the mq_* system calls are not available unless you load
|
150
|
+
the mqueuefs(5) kernel module:
|
151
|
+
|
152
|
+
kldload mqueuefs
|
153
|
+
|
149
154
|
# SEE ALSO
|
150
155
|
|
151
156
|
* [mq_overview(7)][1]
|
157
|
+
* [mqueuefs(5)][2]
|
152
158
|
|
153
159
|
[1]: http://kernel.org/doc/man-pages/online/pages/man7/mq_overview.7.html
|
160
|
+
[2]: http://freebsd.org/cgi/man.cgi?query=mqueuefs
|
data/GIT-VERSION-FILE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GIT_VERSION = 0.
|
1
|
+
GIT_VERSION = 0.2.0
|
data/NEWS
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 0.2.0 / 2010-01-03 05:52 UTC
|
2
|
+
|
3
|
+
This release fixes notification (un)registration and should be
|
4
|
+
fully-supported on modern FreeBSD (7.2+) releases.
|
5
|
+
|
6
|
+
POSIX_MQ#notify=nil correctly unregister notification requests.
|
7
|
+
POSIX_MQ#notify=false now provids the no-op SIGEV_NONE
|
8
|
+
functionality. Under FreeBSD, using IO.select on POSIX_MQ
|
9
|
+
objects is now possible as it has always been under Linux.
|
10
|
+
|
1
11
|
=== 0.1.0 / 2010-01-02 11:01 UTC
|
2
12
|
|
3
13
|
initial
|
data/README
CHANGED
@@ -13,9 +13,9 @@ network-aware message queue implementations.
|
|
13
13
|
|
14
14
|
* Supports message notifications via signals.
|
15
15
|
|
16
|
-
* Supports portable non-blocking operation. Under Linux 2.6.6+
|
17
|
-
POSIX_MQ objects may even be used with event
|
18
|
-
such as IO.select.
|
16
|
+
* Supports portable non-blocking operation. Under Linux 2.6.6+ and
|
17
|
+
FreeBSD 7.2+, POSIX_MQ objects may even be used with event
|
18
|
+
notification mechanisms such as IO.select.
|
19
19
|
|
20
20
|
* Optional timeouts may be applied to send and receive operations.
|
21
21
|
|
@@ -42,6 +42,42 @@ Unpack it, and run "ruby setup.rb"
|
|
42
42
|
|
43
43
|
Otherwise, via RubyGems: gem install posix_mq
|
44
44
|
|
45
|
+
== Usage
|
46
|
+
|
47
|
+
The Linux mq_overview(7)
|
48
|
+
{manpage}[http://kernel.org/doc/man-pages/online/pages/man7/mq_overview.7.html]
|
49
|
+
provides a good overview of programming with POSIX message queues.
|
50
|
+
|
51
|
+
Under FreeBSD, you must load the
|
52
|
+
{mqueuefs(5)}[http://freebsd.org/cgi/man.cgi?query=mqueuefs]
|
53
|
+
kernel module before attempting to use POSIX message queues:
|
54
|
+
|
55
|
+
kldload mqueuefs
|
56
|
+
|
57
|
+
Our API matches the C api closely, see the RDoc for full API
|
58
|
+
documentation. Here is an example of a process communicating
|
59
|
+
with itself. In practice, processes that send will be different
|
60
|
+
from processes that receive.
|
61
|
+
|
62
|
+
require 'posix_mq'
|
63
|
+
mq = POSIX_MQ.new("/foo", :rw)
|
64
|
+
|
65
|
+
# hello world
|
66
|
+
mq << "hello world"
|
67
|
+
puts mq.receive.first # => should print "hello world"
|
68
|
+
|
69
|
+
# non-blocking operation
|
70
|
+
mq.nonblock = true
|
71
|
+
begin
|
72
|
+
mq.receive
|
73
|
+
rescue Errno::EAGAIN
|
74
|
+
end
|
75
|
+
|
76
|
+
trap(:USR1) { puts mq.receive.first }
|
77
|
+
mq.notify = :USR1
|
78
|
+
mq.send "fire USR1 handler"
|
79
|
+
# "fire USR1 handler" should be printed now
|
80
|
+
|
45
81
|
== Development
|
46
82
|
|
47
83
|
You can get the latest source via git from the following locations:
|
data/ext/posix_mq/extconf.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require "mkmf"
|
2
2
|
|
3
|
+
have_header("sys/select.h")
|
4
|
+
have_header("signal.h")
|
3
5
|
have_header("mqueue.h") or abort "mqueue.h header missing"
|
6
|
+
have_func("__mq_oshandle")
|
4
7
|
have_func("rb_str_set_len")
|
5
8
|
have_func("rb_struct_alloc_noinit")
|
6
9
|
have_func('rb_thread_blocking_region')
|
data/ext/posix_mq/posix_mq.c
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
#define _XOPEN_SOURCE 600
|
2
|
+
#ifdef HAVE_SYS_SELECT_H
|
3
|
+
# include <sys/select.h>
|
4
|
+
#endif
|
5
|
+
#ifdef HAVE_SIGNAL_H
|
6
|
+
# include <signal.h>
|
7
|
+
#endif
|
2
8
|
#include <ruby.h>
|
3
9
|
|
4
10
|
#include <time.h>
|
@@ -10,21 +16,25 @@
|
|
10
16
|
#include <unistd.h>
|
11
17
|
|
12
18
|
#if defined(__linux__)
|
13
|
-
# define
|
14
|
-
#
|
15
|
-
# define
|
19
|
+
# define MQD_TO_FD(mqd) (int)(mqd)
|
20
|
+
#elif defined(HAVE___MQ_OSHANDLE) /* FreeBSD */
|
21
|
+
# define MQD_TO_FD(mqd) __mq_oshandle(mqd)
|
16
22
|
#else
|
17
23
|
# warning mqd_t is not select()-able on your OS
|
18
|
-
# define MQD_IS_FD 0
|
19
24
|
# define MQ_IO_MARK(mq) ((void)(0))
|
20
25
|
# define MQ_IO_SET(mq,val) ((void)(0))
|
21
|
-
#endif
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#ifdef MQD_TO_FD
|
29
|
+
# define MQ_IO_MARK(mq) rb_gc_mark((mq)->io)
|
30
|
+
# define MQ_IO_SET(mq,val) do { (mq)->io = (val); } while (0)
|
31
|
+
#endif
|
22
32
|
|
23
33
|
struct posix_mq {
|
24
34
|
mqd_t des;
|
25
35
|
long msgsize;
|
26
36
|
VALUE name;
|
27
|
-
#
|
37
|
+
#ifdef MQD_TO_FD
|
28
38
|
VALUE io;
|
29
39
|
#endif
|
30
40
|
};
|
@@ -463,7 +473,7 @@ static VALUE send0(VALUE self, VALUE buffer)
|
|
463
473
|
return self;
|
464
474
|
}
|
465
475
|
|
466
|
-
#
|
476
|
+
#ifdef MQD_TO_FD
|
467
477
|
/*
|
468
478
|
* call-seq:
|
469
479
|
* mq.to_io => IO
|
@@ -474,9 +484,10 @@ static VALUE send0(VALUE self, VALUE buffer)
|
|
474
484
|
static VALUE to_io(VALUE self)
|
475
485
|
{
|
476
486
|
struct posix_mq *mq = get(self, 1);
|
487
|
+
int fd = MQD_TO_FD(mq->des);
|
477
488
|
|
478
489
|
if (NIL_P(mq->io))
|
479
|
-
mq->io = rb_funcall(rb_cIO, id_new, 1, INT2NUM(
|
490
|
+
mq->io = rb_funcall(rb_cIO, id_new, 1, INT2NUM(fd));
|
480
491
|
|
481
492
|
return mq->io;
|
482
493
|
}
|
@@ -680,19 +691,32 @@ static int lookup_sig(VALUE sig)
|
|
680
691
|
* to the current process when message is received.
|
681
692
|
* If +signal+ is +nil+, it will unregister and disable the notification
|
682
693
|
* request to allow other processes to register a request.
|
694
|
+
* If +signal+ is +false+, it will register a no-op notification request
|
695
|
+
* which will prevent other processes from registering a notification.
|
683
696
|
* Only one process may have a notification request for a queue
|
684
697
|
* at a time, Errno::EBUSY will be raised if there is already
|
685
698
|
* a notification request registration for the queue.
|
699
|
+
*
|
700
|
+
* For readers of the mq_notify(3) manpage, passing +false+
|
701
|
+
* is equivalent to SIGEV_NONE, and passing +nil+ is equivalent
|
702
|
+
* of passing a NULL notification pointer to mq_notify(3).
|
686
703
|
*/
|
687
704
|
static VALUE setnotify(VALUE self, VALUE arg)
|
688
705
|
{
|
689
706
|
struct posix_mq *mq = get(self, 1);
|
690
707
|
struct sigevent not;
|
708
|
+
struct sigevent * notification = ¬
|
691
709
|
VALUE rv = arg;
|
692
710
|
|
693
711
|
not.sigev_notify = SIGEV_SIGNAL;
|
694
712
|
|
695
713
|
switch (TYPE(arg)) {
|
714
|
+
case T_FALSE:
|
715
|
+
not.sigev_notify = SIGEV_NONE;
|
716
|
+
break;
|
717
|
+
case T_NIL:
|
718
|
+
notification = NULL;
|
719
|
+
break;
|
696
720
|
case T_FIXNUM:
|
697
721
|
not.sigev_signo = NUM2INT(arg);
|
698
722
|
break;
|
@@ -701,15 +725,12 @@ static VALUE setnotify(VALUE self, VALUE arg)
|
|
701
725
|
not.sigev_signo = lookup_sig(arg);
|
702
726
|
rv = INT2NUM(not.sigev_signo);
|
703
727
|
break;
|
704
|
-
case T_NIL:
|
705
|
-
not.sigev_notify = SIGEV_NONE;
|
706
|
-
break;
|
707
728
|
default:
|
708
729
|
/* maybe support Proc+thread via sigev_notify_function.. */
|
709
730
|
rb_raise(rb_eArgError, "must be a signal or nil");
|
710
731
|
}
|
711
732
|
|
712
|
-
if (mq_notify(mq->des,
|
733
|
+
if (mq_notify(mq->des, notification) == MQD_INVALID)
|
713
734
|
rb_sys_fail("mq_notify");
|
714
735
|
|
715
736
|
return rv;
|
@@ -802,7 +823,7 @@ void Init_posix_mq_ext(void)
|
|
802
823
|
rb_define_method(cPOSIX_MQ, "notify=", setnotify, 1);
|
803
824
|
rb_define_method(cPOSIX_MQ, "nonblock=", setnonblock, 1);
|
804
825
|
rb_define_method(cPOSIX_MQ, "nonblock?", getnonblock, 0);
|
805
|
-
#
|
826
|
+
#ifdef MQD_TO_FD
|
806
827
|
rb_define_method(cPOSIX_MQ, "to_io", to_io, 0);
|
807
828
|
#endif
|
808
829
|
|
data/lib/posix_mq.rb
CHANGED
data/man/man1/posix-mq.rb.1
CHANGED
@@ -180,8 +180,17 @@ The value of MQUEUE should always be prefixed with a slash
|
|
180
180
|
.PP
|
181
181
|
Exit status is normally 0.
|
182
182
|
Exit status is 2 if a timeout occurs, 1 for all other errors.
|
183
|
+
.PP
|
184
|
+
Under FreeBSD, the mq_* system calls are not available unless you
|
185
|
+
load the mqueuefs(5) kernel module:
|
186
|
+
.PP
|
187
|
+
\f[CR]
|
188
|
+
\ \ \ \ kldload\ mqueuefs
|
189
|
+
\f[]
|
183
190
|
.SH SEE ALSO
|
184
191
|
.IP \[bu] 2
|
185
192
|
mq_overview(7) (http://kernel.org/doc/man-pages/online/pages/man7/mq_overview.7.html)
|
193
|
+
.IP \[bu] 2
|
194
|
+
mqueuefs(5) (http://freebsd.org/cgi/man.cgi?query=mqueuefs)
|
186
195
|
.SH AUTHOR
|
187
196
|
Ruby POSIX MQ hackers <ruby.posix.mq@librelist.com>
|
data/test/test_posix_mq.rb
CHANGED
@@ -136,11 +136,27 @@ class Test_POSIX_MQ < Test::Unit::TestCase
|
|
136
136
|
assert_nil(@mq.notify = nil)
|
137
137
|
assert_nothing_raised { @mq.send("hello", 0) }
|
138
138
|
assert_nil IO.select([rd], nil, nil, 0.1)
|
139
|
-
assert_raises(Errno::EBUSY) { @mq.notify = :USR1 }
|
140
139
|
ensure
|
141
140
|
trap(:USR1, orig)
|
142
141
|
end
|
143
142
|
|
143
|
+
def test_notify_none
|
144
|
+
@mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
|
145
|
+
assert_nothing_raised { @mq.notify = false }
|
146
|
+
pid = fork do
|
147
|
+
begin
|
148
|
+
@mq.notify = :USR1
|
149
|
+
rescue Errno::EBUSY
|
150
|
+
exit 0
|
151
|
+
rescue => e
|
152
|
+
p e
|
153
|
+
end
|
154
|
+
exit! 1
|
155
|
+
end
|
156
|
+
_, status = Process.waitpid2(pid)
|
157
|
+
assert status.success?, status.inspect
|
158
|
+
end
|
159
|
+
|
144
160
|
def test_setattr
|
145
161
|
@mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
|
146
162
|
mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: posix_mq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruby POSIX MQ hackers
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-03 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|