posix_mq 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.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+ only,
17
- POSIX_MQ objects may even be used with event notification mechanisms
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:
@@ -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')
@@ -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 MQD_IS_FD 1
14
- # define MQ_IO_MARK(mq) rb_gc_mark((mq)->io)
15
- # define MQ_IO_SET(mq,val) do { (mq)->io = (val); } while (0)
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 /* non-Linux */
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
- #if MQD_IS_FD
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
- #if MQD_IS_FD
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(mq->des));
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 = &not;
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, &not) == MQD_INVALID)
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
- #if MQD_IS_FD
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
@@ -2,7 +2,7 @@
2
2
  class POSIX_MQ
3
3
 
4
4
  # version of POSIX_MQ, currently 0.1.0
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
 
7
7
  # An analogous Struct to "struct mq_attr" in C.
8
8
  # This may be used in arguments for POSIX_MQ.new and
@@ -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>
@@ -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.1.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-02 00:00:00 -08:00
12
+ date: 2010-01-03 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies: []
15
15