From 3a8a20d685dbfb500187099d76e56e848ad347ed Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 22 Feb 2011 16:46:26 -0800 Subject: attempt to support systems w/o mq_timedsend/mq_timedreceive Some ancient systems don't support mq_timedsend and mq_timedreceive but somehow manage to support other POSIX mq_* functions. --- ext/posix_mq/extconf.rb | 3 +++ ext/posix_mq/posix_mq.c | 31 +++++++++++++++++++++++++++++++ test/test_posix_mq.rb | 27 ++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/ext/posix_mq/extconf.rb b/ext/posix_mq/extconf.rb index ed119a3..310de3d 100644 --- a/ext/posix_mq/extconf.rb +++ b/ext/posix_mq/extconf.rb @@ -10,4 +10,7 @@ have_func('rb_thread_blocking_region') have_library("m") have_library("rt") have_library("pthread") + +have_func("mq_timedsend") +have_func("mq_timedreceive") create_makefile("posix_mq_ext") diff --git a/ext/posix_mq/posix_mq.c b/ext/posix_mq/posix_mq.c index 01b5dbd..d59cd30 100644 --- a/ext/posix_mq/posix_mq.c +++ b/ext/posix_mq/posix_mq.c @@ -133,6 +133,30 @@ struct rw_args { struct timespec *timeout; }; +#ifndef HAVE_MQ_TIMEDSEND +static mqd_t +not_timedsend(mqd_t mqdes, const char *msg_ptr, + size_t msg_len, unsigned msg_prio, + const struct timespec *abs_timeout) +{ + rb_bug("mq_timedsend workaround failed"); + return (mqd_t)-1; +} +# define mq_timedsend not_timedsend +#endif +#ifndef HAVE_MQ_TIMEDRECEIVE +static ssize_t +not_timedreceive(mqd_t mqdes, char *msg_ptr, + size_t msg_len, unsigned *msg_prio, + const struct timespec *abs_timeout) +{ + rb_bug("mq_timedreceive workaround failed"); + return (mqd_t)-1; +} +# define mq_timedreceive not_timedreceive +#endif + +#if defined(HAVE_MQ_TIMEDRECEIVE) && defined(HAVE_MQ_TIMEDSEND) static void num2timespec(struct timespec *ts, VALUE t) { switch (TYPE(t)) { @@ -174,6 +198,13 @@ static void num2timespec(struct timespec *ts, VALUE t) } } } +#else +static void num2timespec(struct timespec *ts, VALUE t) +{ + rb_raise(rb_eNotImpError, + "mq_timedsend and/or mq_timedreceive missing"); +} +#endif static struct timespec *convert_timeout(struct timespec *dest, VALUE t) { diff --git a/test/test_posix_mq.rb b/test/test_posix_mq.rb index f7dec3c..8febb04 100644 --- a/test/test_posix_mq.rb +++ b/test/test_posix_mq.rb @@ -62,7 +62,7 @@ class Test_POSIX_MQ < Test::Unit::TestCase @mq = POSIX_MQ.new(@path, :rw) assert ! @mq.nonblock? t0 = Time.now - assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval } + maybe_timeout { @mq.receive "", interval } or return elapsed = Time.now - t0 assert elapsed > interval, elapsed.inspect assert elapsed < 0.02, elapsed.inspect @@ -76,7 +76,7 @@ class Test_POSIX_MQ < Test::Unit::TestCase @mq = POSIX_MQ.new(@path, :rw) assert ! @mq.nonblock? t0 = Time.now - assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval } + maybe_timeout { @mq.receive "", interval } or return elapsed = Time.now - t0 assert elapsed >= 0.01, elapsed.inspect assert elapsed <= 0.02, elapsed.inspect @@ -87,7 +87,7 @@ class Test_POSIX_MQ < Test::Unit::TestCase @mq = POSIX_MQ.new(@path, :rw) assert ! @mq.nonblock? t0 = Time.now - assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval } + maybe_timeout { @mq.receive "", interval } or return elapsed = Time.now - t0 assert elapsed >= interval, elapsed.inspect assert elapsed < 1.10, elapsed.inspect @@ -97,9 +97,15 @@ class Test_POSIX_MQ < Test::Unit::TestCase interval = 0.01 @mq = POSIX_MQ.new(@path, :rw, 0666, POSIX_MQ::Attr[0, 1, 1, 0]) assert ! @mq.nonblock? - assert_nothing_raised { @mq.send "A", 1, interval } + assert_nothing_raised { + begin + @mq.send "A", 1, interval + rescue NotImplementedError + return + end + } t0 = Time.now - assert_raises(Errno::ETIMEDOUT) { @mq.send "B", 1, interval } + maybe_timeout { @mq.send "B", 1, interval } or return elapsed = Time.now - t0 assert elapsed > interval end @@ -344,4 +350,15 @@ class Test_POSIX_MQ < Test::Unit::TestCase assert_raises(TypeError) { @mq.attr = {} } assert_raises(TypeError) { @mq.attr = Struct.new(:a,:b,:c,:d).new } end + + def maybe_timeout + yield + assert_raises(exc) { } # FAIL + return true + rescue Errno::ETIMEDOUT => e + return true + rescue NotImplementedError => e + warn "E: #{e}" + return false + end end -- cgit v1.2.3-24-ge0c7