Date | Commit message (Collapse) |
|
Small bugfixes and small API changes to avoid potential
issues/misuse are the focus of this release.
For non-blocking operation, the GVL is no longer bounced. This
reduces synchronization/scheduling overhead when used in
non-blocking applications.
Small cleanups and documentation improvements, too.
* make POSIX_MQ#dup and POSIX_MQ#clone no-op
* do not release GVL for non-blocking operations
* do not release GVL when unlinking/opening
* POSIX_MQ#<< does not release GVL when non-blocking
* avoid shadow warnings
* README: add mailing list archives info
* POSIX_MQ#to_io works under FreeBSD, too
* fix potential race with notify(&block)
* add TODO item for using netlink under Linux
* remove non-portable #warning CPP directive
* ensure POSIX_MQ#name is clobber-proof
|
|
We don't want folks to accidentally clobber the value for
others, so allocate a new string object for it (don't worry,
rb_str_dup() is cheap in 1.9).
|
|
There's a good chance they're not using GCC if they're on some
weird platform that we'd emit a warning for.
|
|
|
|
We need to assign the notify_thread before assigning the
notification. Otherwise, there's a chance the notification
could fire and the notify_thread is not properly assigned for
the POSIX_MQ object when the pipe becomes readable.
|
|
|
|
|
|
|
|
Missed this with the other change
|
|
Since the message queue is not actually on a (slow) block
device, it's unlikely to block in a way where other tasks may be
scheduled by the kernel. So avoid complicating things and
unnecessary task switching and assume mq_open/mq_unlink can
be executed as fast as the CPU/memory subsystems allows.
|
|
There's no point in wasting cycles releasing and reacquiring
a lock when we know we won't block. Since most non-blocking
users are expected to be single/few-threaded processes, this
will likely help them.
|
|
It'll cause problems for the automatic mq_close() during GC
otherwise, as dup(2) on an mqd_t isn't portable.
Of course there's no point in cloning or duping, either, as
mq_send/mq_receive operations are always atomic at the kernel
level and only one thread can have a notification registered
for it.
|
|
This fixes a misuse of the Ruby API leading to memory leaks in
cases where message queues are continually opened and closed
throughout the lifetime of the application.
Fortunately applications have little reason to repeatedly open
and close message queue descriptors: they are
multi-thread/multi-process-safe in every way imaginable and also
capable of non-blocking operation.
|
|
We still need to explicitly free the pointer we're given, and
not just close the associated file descriptor. Fortunately most
people to not spend all day opening/closing message queue
descriptors so this leak may not be noticeable.
|
|
|
|
|
|
This release adds a few new API methods, fixes MRI 1.8.6
support. We should now have full feature parity with
underlying POSIX message queue C API.
* POSIX_MQ#notify(&block)
RDoc: http://bogomips.org/ruby_posix_mq/POSIX_MQ.html#M000001
This is only supported on platforms that implement
SIGEV_THREAD with mq_notify(3) (tested with glibc + Linux).
Other platforms will have to continue to rely on signal
notifications via POSIX#notify=signal, or IO notifications
in FreeBSD (and Linux).
* POSIX_MQ#shift([buffer [,timeout]])
Shorthand for the common "POSIX_MQ#receive.first"
when you do not care for priority of the received message.
Rev, EventMachine and Reactor support are planned for
Linux, FreeBSD and possibly any other platforms where POSIX
message queues are implemented with a file descriptor.
|
|
It's Rubinius-specific and we use rb_str_resize
there anyways...
|
|
It's not needed since the native thread will retry in the
unlikely case of EINTR/EAGAIN. And writing one byte to a pipe
that's guaranteed by POSIX to be at least 512 bytes is highly
unlikely.
It's also bad because F_SETFL takes the big kernel lock under
Linux (and possibly other systems), and doing it unnecessarily
is a waste of system cycles.
|
|
Most used open modes are well under INT_MAX, however
|
|
This acts like POSIX_MQ#receive but only returns the message
without the priority.
|
|
SIGEV_THREAD is not easy to implement, so many platforms
do not implement it.
|
|
This is implementation uses both a short-lived POSIX thread and
a pre-spawned Ruby Thread in a manner that works properly under
both Ruby 1.8 (green threads) and 1.9 (where Ruby Threads are
POSIX threads).
The short-lived POSIX thread will write a single "\0" byte to
a pipe the Ruby Thread waits on. This operation is atomic
on all platforms. Once the Ruby Thread is woken up from the
pipe, it will execute th block given to it.
This dual-thread implementation is inspired by the way glibc
implements mq_notify(3) + SIGEV_THREAD under Linux where the
kernel itself cannot directly spawn POSIX threads.
|
|
The POSIX manpages specify the return values of all
mq_* functions besides mq_open(3) to be "int", not "mqd_t".
|
|
Shouldn't affect most people since they should just
take code from git...
|
|
This release fixes notification (un)registration and should be
fully-supported on modern FreeBSD (7.2+) releases.
POSIX_MQ#notify=nil correctly unregister notification requests.
POSIX_MQ#notify=false now provids the no-op SIGEV_NONE
functionality. Under FreeBSD, using IO.select on POSIX_MQ
objects is now possible as it has always been under Linux.
|
|
FreeBSD implements an __mq_oshandle(mqd_t mqd) function
to convert mqd_t to integer file descriptors.
|
|
FreeBSD seems to need some files explicitly included.
|
|
|
|
"mq.notify = false" also works now, doing what
"mq.notify = nil" used to do (using SIGEV_NONE).
I was confused by SIGEV_NONE usage vs using a NULL pointer for
the notification passed mq_notify(3). SIGEV_NONE does not
actually unregister, it registers a no-op notification which
prevents other processes from taking us.
This also fixes the test case to pass under both Linux and
FreeBSD.
|
|
|