From f14356733e83e5af35ec5c9f2346bf9607fc3a16 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 2 Feb 2016 22:14:16 +0000 Subject: support idempotent POSIX_MQ#close IO#close under Ruby 2.3 is idempotent, we shall follow suit with POSIX_MQ#close --- ext/posix_mq/extconf.rb | 11 +++++++++++ ext/posix_mq/posix_mq.c | 10 +++++++++- test/test_posix_mq.rb | 16 +++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/ext/posix_mq/extconf.rb b/ext/posix_mq/extconf.rb index eb799b2..d433d1d 100644 --- a/ext/posix_mq/extconf.rb +++ b/ext/posix_mq/extconf.rb @@ -14,4 +14,15 @@ have_library("pthread") have_func("__mq_oshandle") have_func("mq_timedsend") have_func("mq_timedreceive") + +r, w = IO.pipe +r.close +w.close +begin + r.close + $CPPFLAGS += ' -DIDEMPOTENT_IO_CLOSE=1' +rescue IOError + $CPPFLAGS += ' -DIDEMPOTENT_IO_CLOSE=0' +end + create_makefile("posix_mq_ext") diff --git a/ext/posix_mq/posix_mq.c b/ext/posix_mq/posix_mq.c index 5e1b3b8..0567676 100644 --- a/ext/posix_mq/posix_mq.c +++ b/ext/posix_mq/posix_mq.c @@ -824,7 +824,15 @@ static VALUE setattr(VALUE self, VALUE astruct) */ static VALUE _close(VALUE self) { - struct posix_mq *mq = get(self, 1); + struct posix_mq *mq; + + if (IDEMPOTENT_IO_CLOSE) { /* defined in extconf.rb */ + mq = get(self, 0); + if (!mq || (mq->des == MQD_INVALID)) + return Qnil; + } else { + mq = get(self, 1); + } if (! MQ_IO_CLOSE(mq)) { if (mq_close(mq->des) < 0) diff --git a/test/test_posix_mq.rb b/test/test_posix_mq.rb index d726d36..e831012 100644 --- a/test/test_posix_mq.rb +++ b/test/test_posix_mq.rb @@ -152,7 +152,21 @@ class Test_POSIX_MQ < Test::Unit::TestCase assert_equal true, mq.send("HI", 0) assert_equal 1, mq.attr.curmsgs assert_nil mq.close - assert_raises(IOError) { mq.close } + + r, w = IO.pipe + w.close + r.close + idempotent_close = begin + r.close + true + rescue IOError + false + end + if idempotent_close + 2.times { assert_nil mq.close } + else + assert_raises(IOError) { mq.close } + end end assert @mq.closed? @mq = nil -- cgit v1.2.3-24-ge0c7