about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-02-23 20:11:18 +0000
committerEric Wong <normalperson@yhbt.net>2011-02-23 20:11:18 +0000
commitb6d82cdeff1ea2822c2911adf61d6a00538ecba8 (patch)
tree10df01d912ad14b064d8201c22407701a86c723f
parent634a6f450f0a145f6248d5918c4eb3d0ded6f6dc (diff)
downloadruby_posix_mq-b6d82cdeff1ea2822c2911adf61d6a00538ecba8.tar.gz
Some systems without mq_timedsend/mq_timedreceive need to
use alarm() or similar (setitimer()) to interrupt timed-out
mq_send/mq_receive calls, so we need to handle EINTR properly.
-rw-r--r--test/test_posix_mq.rb28
1 files changed, 28 insertions, 0 deletions
diff --git a/test/test_posix_mq.rb b/test/test_posix_mq.rb
index e58a212..3dcaa90 100644
--- a/test/test_posix_mq.rb
+++ b/test/test_posix_mq.rb
@@ -96,6 +96,34 @@ class Test_POSIX_MQ < Test::Unit::TestCase
     assert elapsed < 1.10, elapsed.inspect
   end
 
+  def test_alarm_signal_safe
+    alarm = nil
+    libcs = %w(/lib/libc-2.7.so /usr/lib/libc.sl)
+    libcs.each do |libc|
+      if File.readable?(libc)
+        require "dl"
+        libc = DL.dlopen libc
+        alarm = libc["alarm", "II"]
+        break
+      end
+    end
+    alarm or return warn "alarm() not found in #{libcs.inspect}"
+    alarms = 0
+    trap("ALRM") { alarms += 1 }
+    interval = 1
+    alarm[interval]
+    @mq = POSIX_MQ.new(@path, :rw)
+    assert ! @mq.nonblock?
+    t0 = Time.now
+    a = nil
+    assert_raises(Errno::EINTR) { a = @mq.receive }
+    elapsed = Time.now - t0
+    assert_nil a
+    assert elapsed >= interval, elapsed.inspect
+    assert elapsed < 1.10, elapsed.inspect
+    assert_equal 1, alarms
+  end
+
   def test_timed_send
     interval = 0.01
     @mq = POSIX_MQ.new(@path, :rw, 0666, POSIX_MQ::Attr[0, 1, 1, 0])