posix_mq 0.5.1
[ruby_posix_mq.git] / lib / posix_mq.rb
blob690e475c4ce795d55cd8c97b7cce2f0c71e1627b
1 # -*- encoding: binary -*-
2 class POSIX_MQ
4   # version of POSIX_MQ, currently 0.5.1
5   VERSION = '0.5.1'
7   # An analogous Struct to "struct mq_attr" in C.
8   # This may be used in arguments for POSIX_MQ.new and
9   # POSIX_MQ#attr=.  POSIX_MQ#attr returns an instance
10   # of this class.
11   #
12   # See the mq_getattr(3) manpage for more information on the values.
13   Attr = Struct.new(:flags, :maxmsg, :msgsize, :curmsgs)
15   class << self
17     # Opens a POSIX message queue and performs operations on the
18     # given block, closing the message queue at exit.
19     # All all arguments are passed to POSIX_MQ.new.
20     def open(*args)
21       mq = new(*args)
22       block_given? or return mq
23       begin
24         yield mq
25       ensure
26         mq.close unless mq.closed?
27       end
28     end
29   end
31   # Executes the given block upon reception of the next message in an
32   # empty queue.  If the message queue is not empty, then this block
33   # will only be fired after the queue is emptied and repopulated with
34   # one message.
35   #
36   # This block will only be executed upon the arrival of the
37   # first message and must be reset/reenabled for subsequent
38   # notifications.  This block will execute in a separate Ruby
39   # Thread (and thus will safely have the GVL by default).
40   #
41   # This method is only supported on platforms that implement
42   # SIGEV_THREAD functionality in mq_notify(3).  So far we only
43   # know of glibc + Linux supporting this.  Please let us
44   # know if your platform can support this functionality and
45   # are willing to test for us <ruby.posix.mq@librelist.com>
46   def notify(&block)
47     block.arity == 1 or
48       raise ArgumentError, "arity of notify block must be 1"
49     r, w = IO.pipe
50     self.notify_exec(w, Thread.new(r, w, self) do |r, w, mq|
51       begin
52         begin
53           r.read(1) or raise Errno::EINTR
54         rescue Errno::EINTR, Errno::EAGAIN
55           retry
56         end
57         block.call(mq)
58       ensure
59         mq.notify_cleanup
60         r.close rescue nil
61         w.close rescue nil
62       end
63     end)
64     nil
65   end if RUBY_PLATFORM =~ /linux/
67   # There's no point in ever duping a POSIX_MQ object.
68   # All send/receive operations are atomic and only one
69   # native thread may be notified at a time
70   def dup
71     self
72   end
74   # There's no point in ever cloning a POSIX_MQ object.
75   # All send/receive operations are atomic and only one
76   # native thread may be notified at a time
77   alias clone dup
79 end
81 require 'posix_mq_ext'