make methods that should be private, private
[ruby_posix_mq.git] / lib / posix_mq.rb
blob60c63b6e4b5fcb50b01d8028fbc3bf52e60094e2
1 # -*- encoding: binary -*-
3 # This class represents an POSIX message queue descriptor (mqd_t)
4 # object.  It matches the C API for POSIX messages queues closely.
6 # See the link:README for examples on how to use it.
7 class POSIX_MQ
9   # An analogous Struct to "struct mq_attr" in C.
10   # This may be used in arguments for POSIX_MQ.new and
11   # POSIX_MQ#attr=.  POSIX_MQ#attr returns an instance
12   # of this class.
13   #
14   # See the mq_getattr(3) manpage for more information on the values.
15   Attr = Struct.new(:flags, :maxmsg, :msgsize, :curmsgs)
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 self.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
30   # Executes the given block upon reception of the next message in an
31   # empty queue.  If the message queue is not empty, then this block
32   # will only be fired after the queue is emptied and repopulated with
33   # one message.
34   #
35   # This block will only be executed upon the arrival of the
36   # first message and must be reset/reenabled for subsequent
37   # notifications.  This block will execute in a separate Ruby
38   # Thread (and thus will safely have the GVL by default).
39   #
40   # This method is only supported on platforms that implement
41   # SIGEV_THREAD functionality in mq_notify(3).  So far we only
42   # know of glibc + Linux supporting this.  Please let us
43   # know if your platform can support this functionality and
44   # are willing to test for us <ruby.posix.mq@librelist.com>
45   #
46   # As far as we can tell, this method is not very useful
47   # nor efficient.  You would be better served using signals or
48   # just blocking.  On Linux and FreeBSD, you can use POSIX_MQ
49   # with I/O multiplexing (IO.select, EventMachine), too.
50   def notify(&block)
51     block.arity == 1 or
52       raise ArgumentError, "arity of notify block must be 1"
53     r, w = IO.pipe
54     notify_exec(w, Thread.new(block) do |blk|
55       begin
56         begin
57           r.read(1) or raise Errno::EINTR
58         rescue Errno::EINTR, Errno::EAGAIN
59           retry
60         end
61         blk.call(self)
62       ensure
63         notify_cleanup
64         r.close rescue nil
65         w.close rescue nil
66       end
67     end)
68     nil
69   end if RUBY_PLATFORM =~ /linux/
71   # There's no point in ever duping a POSIX_MQ object.
72   # All send/receive operations are atomic and only one
73   # native thread may be notified at a time
74   def dup
75     self
76   end
78   # There's no point in ever cloning a POSIX_MQ object.
79   # All send/receive operations are atomic and only one
80   # native thread may be notified at a time
81   alias clone dup
83 end
85 require 'posix_mq_ext'