From 060ec9240134bc759d3966360a79825743e3de16 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 12 Jan 2015 08:27:41 +0000 Subject: POSIX_MQ#autoclose= propagates to IO If a corresponding IO object exists or is created later, propagate autoclose to the corresponding IO object to avoid simplify autoclose handling for the user. This hopefully avoids nasty surprises in case users disable autoclose but want to keep the IO object around. --- ext/posix_mq/posix_mq.c | 17 ++++++++++++++++- test/test_posix_mq.rb | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ext/posix_mq/posix_mq.c b/ext/posix_mq/posix_mq.c index 78544c8..5e1b3b8 100644 --- a/ext/posix_mq/posix_mq.c +++ b/ext/posix_mq/posix_mq.c @@ -34,6 +34,7 @@ # define MQ_IO_SET(mq,val) ((void)(0)) # define MQ_IO_CLOSE(mq) ((int)(0)) # define MQ_IO_NIL_P(mq) ((int)(1)) +# define MQ_IO_SET_AUTOCLOSE(mq, boolean) for(;0;) #endif struct posix_mq { @@ -48,9 +49,17 @@ struct posix_mq { }; #ifdef MQD_TO_FD +static ID id_setautoclose; # define MQ_IO_MARK(mq) rb_gc_mark((mq)->io) # define MQ_IO_SET(mq,val) do { (mq)->io = (val); } while (0) # define MQ_IO_NIL_P(mq) NIL_P((mq)->io) + +static void MQ_IO_SET_AUTOCLOSE(struct posix_mq *mq, VALUE boolean) +{ + if (!NIL_P(mq->io)) + rb_funcall(mq->io, id_setautoclose, 1, boolean); +} + static int MQ_IO_CLOSE(struct posix_mq *mq) { if (NIL_P(mq->io)) @@ -654,9 +663,13 @@ static VALUE to_io(VALUE self) struct posix_mq *mq = get(self, 1); int fd = MQD_TO_FD(mq->des); - if (NIL_P(mq->io)) + if (NIL_P(mq->io)) { mq->io = rb_funcall(rb_cIO, id_new, 1, INT2NUM(fd)); + if (!mq->autoclose) + rb_funcall(mq->io, id_setautoclose, 1, Qfalse); + } + return mq->io; } #endif @@ -1078,6 +1091,7 @@ static VALUE setautoclose(VALUE self, VALUE autoclose) { struct posix_mq *mq = get(self, 1); + MQ_IO_SET_AUTOCLOSE(mq, autoclose); mq->autoclose = RTEST(autoclose) ? 1 : 0; return autoclose; } @@ -1195,6 +1209,7 @@ void Init_posix_mq_ext(void) #ifdef FD_TO_MQD rb_define_module_function(cPOSIX_MQ, "for_fd", for_fd, 1); + id_setautoclose = rb_intern("autoclose="); #endif id_new = rb_intern("new"); diff --git a/test/test_posix_mq.rb b/test/test_posix_mq.rb index a4fc407..35967e8 100644 --- a/test/test_posix_mq.rb +++ b/test/test_posix_mq.rb @@ -258,6 +258,14 @@ class Test_POSIX_MQ < Test::Unit::TestCase end end if POSIX_MQ.respond_to?(:for_fd) && POSIX_MQ.method_defined?(:to_io) + def test_autoclose_propagates_to_io + @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666 + @mq.autoclose = false + assert_equal false, @mq.to_io.autoclose? + @mq.autoclose = true + assert_equal true, @mq.to_io.autoclose? + end if POSIX_MQ.method_defined?(:to_io) + def test_notify rd, wr = IO.pipe orig = trap(:USR1) { wr.syswrite('.') } -- cgit v1.2.3-24-ge0c7