posix_mq 0.7.0 → 0.8.0pre

Sign up to get free protection for your applications and to get access to all the features.
data/.wrongdoc.yml CHANGED
@@ -4,4 +4,4 @@ cgit_url: http://bogomips.org/ruby_posix_mq.git
4
4
  git_url: git://bogomips.org/ruby_posix_mq.git
5
5
  changelog_since: 0.4.0
6
6
  merge_html:
7
- posix-mq-rb_1: Documentation/posix-mq.rb.1.html
7
+ posix-mq-rb_1: Documentation/posix-mq-rb.1.html
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.7.0.GIT
4
+ DEF_VER=v0.8.0pre.GIT
5
5
 
6
6
  LF='
7
7
  '
@@ -62,10 +62,13 @@ static int MQ_IO_CLOSE(struct posix_mq *mq)
62
62
  }
63
63
  #endif
64
64
 
65
- static VALUE cPOSIX_MQ, cAttr;
65
+ # define PMQ_WANTARRAY (1<<0)
66
+ # define PMQ_TRY (1<<1)
67
+
68
+ static VALUE cAttr;
66
69
  static ID id_new, id_kill, id_fileno, id_mul, id_divmod;
67
70
  static ID id_flags, id_maxmsg, id_msgsize, id_curmsgs;
68
- static ID sym_r, sym_w, sym_rw;
71
+ static VALUE sym_r, sym_w, sym_rw;
69
72
  static const mqd_t MQD_INVALID = (mqd_t)-1;
70
73
 
71
74
  /* Ruby 1.8.6+ macros (for compatibility with Ruby 1.9) */
@@ -438,7 +441,11 @@ static VALUE init(int argc, VALUE *argv, VALUE self)
438
441
 
439
442
  mq->des = (mqd_t)xopen(&x);
440
443
  if (mq->des == MQD_INVALID) {
441
- if (errno == ENOMEM || errno == EMFILE || errno == ENFILE) {
444
+ switch (errno) {
445
+ case ENOMEM:
446
+ case EMFILE:
447
+ case ENFILE:
448
+ case ENOSPC:
442
449
  rb_gc();
443
450
  mq->des = (mqd_t)xopen(&x);
444
451
  }
@@ -501,6 +508,7 @@ static void setup_send_buffer(struct rw_args *x, VALUE buffer)
501
508
  x->msg_len = (size_t)RSTRING_LEN(buffer);
502
509
  }
503
510
 
511
+ static VALUE _send(int sflags, int argc, VALUE *argv, VALUE self);
504
512
  /*
505
513
  * call-seq:
506
514
  * mq.send(string [,priority[, timeout]]) => nil
@@ -514,7 +522,12 @@ static void setup_send_buffer(struct rw_args *x, VALUE buffer)
514
522
  * On some older systems, the +timeout+ argument is not currently
515
523
  * supported and may raise NotImplementedError if +timeout+ is used.
516
524
  */
517
- static VALUE _send(int argc, VALUE *argv, VALUE self)
525
+ static VALUE my_send(int argc, VALUE *argv, VALUE self)
526
+ {
527
+ _send(0, argc, argv, self);
528
+ }
529
+
530
+ static VALUE _send(int sflags, int argc, VALUE *argv, VALUE self)
518
531
  {
519
532
  struct posix_mq *mq = get(self, 1);
520
533
  struct rw_args x;
@@ -529,15 +542,14 @@ static VALUE _send(int argc, VALUE *argv, VALUE self)
529
542
  x.timeout = convert_timeout(&expire, timeout);
530
543
  x.msg_prio = NIL_P(prio) ? 0 : NUM2UINT(prio);
531
544
 
532
- if (mq->attr.mq_flags & O_NONBLOCK)
533
- rv = (mqd_t)xsend(&x);
534
- else
535
- rv = (mqd_t)rb_thread_blocking_region(xsend, &x,
536
- RUBY_UBF_IO, 0);
537
- if (rv == MQD_INVALID)
545
+ rv = (mqd_t)rb_thread_blocking_region(xsend, &x, RUBY_UBF_IO, 0);
546
+ if (rv == MQD_INVALID) {
547
+ if (errno == EAGAIN && (sflags & PMQ_TRY))
548
+ return Qfalse;
538
549
  rb_sys_fail("mq_send");
550
+ }
539
551
 
540
- return Qnil;
552
+ return (sflags & PMQ_TRY) ? Qtrue : Qnil;
541
553
  }
542
554
 
543
555
  /*
@@ -558,12 +570,7 @@ static VALUE send0(VALUE self, VALUE buffer)
558
570
  x.timeout = NULL;
559
571
  x.msg_prio = 0;
560
572
 
561
- if (mq->attr.mq_flags & O_NONBLOCK)
562
- rv = (mqd_t)xsend(&x);
563
- else
564
- rv = (mqd_t)rb_thread_blocking_region(xsend, &x,
565
- RUBY_UBF_IO, 0);
566
-
573
+ rv = (mqd_t)rb_thread_blocking_region(xsend, &x, RUBY_UBF_IO, 0);
567
574
  if (rv == MQD_INVALID)
568
575
  rb_sys_fail("mq_send");
569
576
 
@@ -590,7 +597,7 @@ static VALUE to_io(VALUE self)
590
597
  }
591
598
  #endif
592
599
 
593
- static VALUE _receive(int wantarray, int argc, VALUE *argv, VALUE self);
600
+ static VALUE _receive(int rflags, int argc, VALUE *argv, VALUE self);
594
601
 
595
602
  /*
596
603
  * call-seq:
@@ -613,7 +620,7 @@ static VALUE _receive(int wantarray, int argc, VALUE *argv, VALUE self);
613
620
  */
614
621
  static VALUE receive(int argc, VALUE *argv, VALUE self)
615
622
  {
616
- return _receive(1, argc, argv, self);
623
+ return _receive(PMQ_WANTARRAY, argc, argv, self);
617
624
  }
618
625
 
619
626
  /*
@@ -639,7 +646,7 @@ static VALUE shift(int argc, VALUE *argv, VALUE self)
639
646
  return _receive(0, argc, argv, self);
640
647
  }
641
648
 
642
- static VALUE _receive(int wantarray, int argc, VALUE *argv, VALUE self)
649
+ static VALUE _receive(int rflags, int argc, VALUE *argv, VALUE self)
643
650
  {
644
651
  struct posix_mq *mq = get(self, 1);
645
652
  struct rw_args x;
@@ -667,18 +674,16 @@ static VALUE _receive(int wantarray, int argc, VALUE *argv, VALUE self)
667
674
  x.msg_len = (size_t)mq->attr.mq_msgsize;
668
675
  x.des = mq->des;
669
676
 
670
- if (mq->attr.mq_flags & O_NONBLOCK) {
671
- r = (ssize_t)xrecv(&x);
672
- } else {
673
- r = (ssize_t)rb_thread_blocking_region(xrecv, &x,
674
- RUBY_UBF_IO, 0);
675
- }
676
- if (r < 0)
677
+ r = (ssize_t)rb_thread_blocking_region(xrecv, &x, RUBY_UBF_IO, 0);
678
+ if (r < 0) {
679
+ if (errno == EAGAIN && (rflags & PMQ_TRY))
680
+ return Qnil;
677
681
  rb_sys_fail("mq_receive");
682
+ }
678
683
 
679
684
  rb_str_set_len(buffer, r);
680
685
 
681
- if (wantarray)
686
+ if (rflags & PMQ_WANTARRAY)
682
687
  return rb_ary_new3(2, buffer, UINT2NUM(x.msg_prio));
683
688
  return buffer;
684
689
  }
@@ -940,10 +945,12 @@ static VALUE setnotify(VALUE self, VALUE arg)
940
945
  *
941
946
  * Returns the current non-blocking state of the message queue descriptor.
942
947
  */
943
- static VALUE getnonblock(VALUE self)
948
+ static VALUE nonblock_p(VALUE self)
944
949
  {
945
950
  struct posix_mq *mq = get(self, 1);
946
951
 
952
+ if (mq_getattr(mq->des, &mq->attr) < 0)
953
+ rb_sys_fail("mq_getattr");
947
954
  return mq->attr.mq_flags & O_NONBLOCK ? Qtrue : Qfalse;
948
955
  }
949
956
 
@@ -976,9 +983,62 @@ static VALUE setnonblock(VALUE self, VALUE nb)
976
983
  return nb;
977
984
  }
978
985
 
986
+ static VALUE tryinit(int argc, VALUE *argv, VALUE self)
987
+ {
988
+ init(argc, argv, self);
989
+ setnonblock(self, Qtrue);
990
+
991
+ return self;
992
+ }
993
+
994
+ /*
995
+ * call-seq:
996
+ * mq.trysend(string [,priority[, timeout]]) => +true+ or +false+
997
+ *
998
+ * Exactly like POSIX_MQ#send, except it returns +false+ instead of raising
999
+ * +Errno::EAGAIN+ when non-blocking operation is desired and returns +true+
1000
+ * on success instead of +nil+.
1001
+ * This does not guarantee non-blocking behavior, the message queue must
1002
+ * be made non-blocking before calling this method.
1003
+ */
1004
+ static VALUE trysend(int argc, VALUE *argv, VALUE self)
1005
+ {
1006
+ _send(PMQ_TRY, argc, argv, self);
1007
+ }
1008
+
1009
+ /*
1010
+ * call-seq:
1011
+ * mq.tryshift([buffer [, timeout]]) => message or nil
1012
+ *
1013
+ * Exactly like POSIX_MQ#shift, except it returns +nil+ instead of raising
1014
+ * +Errno::EAGAIN+ when non-blocking operation is desired.
1015
+ *
1016
+ * This does not guarantee non-blocking behavior, the message queue must
1017
+ * be made non-blocking before calling this method.
1018
+ */
1019
+ static VALUE tryshift(int argc, VALUE *argv, VALUE self)
1020
+ {
1021
+ return _receive(PMQ_TRY, argc, argv, self);
1022
+ }
1023
+
1024
+ /*
1025
+ * call-seq:
1026
+ * mq.tryreceive([buffer [, timeout]]) => [ message, priority ] or nil
1027
+ *
1028
+ * Exactly like POSIX_MQ#receive, except it returns +nil+ instead of raising
1029
+ * +Errno::EAGAIN+ when non-blocking operation is desired.
1030
+ *
1031
+ * This does not guarantee non-blocking behavior, the message queue must
1032
+ * be made non-blocking before calling this method.
1033
+ */
1034
+ static VALUE tryreceive(int argc, VALUE *argv, VALUE self)
1035
+ {
1036
+ return _receive(PMQ_WANTARRAY|PMQ_TRY, argc, argv, self);
1037
+ }
1038
+
979
1039
  void Init_posix_mq_ext(void)
980
1040
  {
981
- cPOSIX_MQ = rb_define_class("POSIX_MQ", rb_cObject);
1041
+ VALUE cPOSIX_MQ = rb_define_class("POSIX_MQ", rb_cObject);
982
1042
  rb_define_alloc_func(cPOSIX_MQ, alloc);
983
1043
  cAttr = rb_const_get(cPOSIX_MQ, rb_intern("Attr"));
984
1044
 
@@ -1003,10 +1063,13 @@ void Init_posix_mq_ext(void)
1003
1063
  rb_define_singleton_method(cPOSIX_MQ, "unlink", s_unlink, 1);
1004
1064
 
1005
1065
  rb_define_method(cPOSIX_MQ, "initialize", init, -1);
1006
- rb_define_method(cPOSIX_MQ, "send", _send, -1);
1066
+ rb_define_method(cPOSIX_MQ, "send", my_send, -1);
1007
1067
  rb_define_method(cPOSIX_MQ, "<<", send0, 1);
1068
+ rb_define_method(cPOSIX_MQ, "trysend", trysend, -1);
1008
1069
  rb_define_method(cPOSIX_MQ, "receive", receive, -1);
1070
+ rb_define_method(cPOSIX_MQ, "tryreceive", tryreceive, -1);
1009
1071
  rb_define_method(cPOSIX_MQ, "shift", shift, -1);
1072
+ rb_define_method(cPOSIX_MQ, "tryshift", tryshift, -1);
1010
1073
  rb_define_method(cPOSIX_MQ, "attr", getattr, 0);
1011
1074
  rb_define_method(cPOSIX_MQ, "attr=", setattr, 1);
1012
1075
  rb_define_method(cPOSIX_MQ, "close", _close, 0);
@@ -1017,7 +1080,7 @@ void Init_posix_mq_ext(void)
1017
1080
  rb_define_method(cPOSIX_MQ, "nonblock=", setnonblock, 1);
1018
1081
  rb_define_method(cPOSIX_MQ, "notify_exec", setnotify_exec, 2);
1019
1082
  rb_define_method(cPOSIX_MQ, "notify_cleanup", notify_cleanup, 0);
1020
- rb_define_method(cPOSIX_MQ, "nonblock?", getnonblock, 0);
1083
+ rb_define_method(cPOSIX_MQ, "nonblock?", nonblock_p, 0);
1021
1084
  #ifdef MQD_TO_FD
1022
1085
  rb_define_method(cPOSIX_MQ, "to_io", to_io, 0);
1023
1086
  #endif
data/lib/posix_mq.rb CHANGED
@@ -6,11 +6,6 @@
6
6
  # See the link:README for examples on how to use it.
7
7
  class POSIX_MQ
8
8
 
9
- # version of POSIX_MQ, currently 0.7.0
10
- # This constant is deprecated and will be removed in the next
11
- # release. Use +respond_to?+ instead to test for features.
12
- VERSION = "0.7.0"
13
-
14
9
  # An analogous Struct to "struct mq_attr" in C.
15
10
  # This may be used in arguments for POSIX_MQ.new and
16
11
  # POSIX_MQ#attr=. POSIX_MQ#attr returns an instance
@@ -4,6 +4,11 @@ require 'posix_mq'
4
4
  require 'thread'
5
5
  require 'fcntl'
6
6
  $stderr.sync = $stdout.sync = true
7
+ require "dl"
8
+ begin
9
+ require "dl/func"
10
+ rescue LoadError
11
+ end
7
12
 
8
13
  class Test_POSIX_MQ < Test::Unit::TestCase
9
14
 
@@ -97,21 +102,24 @@ class Test_POSIX_MQ < Test::Unit::TestCase
97
102
  end
98
103
 
99
104
  def test_alarm_signal_safe
100
- alarm = nil
101
- libcs = %w(/lib/libc-2.7.so /usr/lib/libc.sl)
102
- libcs.each do |libc|
103
- if File.readable?(libc)
104
- require "dl"
105
- libc = DL.dlopen libc
105
+ libc = alarm = nil
106
+ libcs = %w(libc.so.6 /usr/lib/libc.sl)
107
+ libcs.each do |name|
108
+ libc = DL::Handle.new(name) rescue next
109
+ if defined?(DL::Function)
110
+ alarm = libc["alarm"]
111
+ alarm = DL::CFunc.new(alarm, DL::TYPE_INT, "alarm")
112
+ alarm = DL::Function.new(alarm, [DL::TYPE_INT], DL::TYPE_INT)
113
+ else
106
114
  alarm = libc["alarm", "II"]
107
- break
108
115
  end
116
+ break
109
117
  end
110
118
  alarm or return warn "alarm() not found in #{libcs.inspect}"
111
119
  alarms = 0
112
120
  trap("ALRM") { alarms += 1 }
113
121
  interval = 1
114
- alarm[interval]
122
+ alarm.call interval
115
123
  @mq = POSIX_MQ.new(@path, :rw)
116
124
  assert ! @mq.nonblock?
117
125
  t0 = Time.now
@@ -277,6 +285,17 @@ class Test_POSIX_MQ < Test::Unit::TestCase
277
285
  assert_equal 0, @mq.attr.flags
278
286
  end
279
287
 
288
+ def test_setattr_fork
289
+ @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
290
+ mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK)
291
+ @mq.attr = mq_attr
292
+ assert @mq.nonblock?
293
+
294
+ pid = fork { @mq.nonblock = false }
295
+ assert Process.waitpid2(pid)[1].success?
296
+ assert ! @mq.nonblock?
297
+ end
298
+
280
299
  def test_new_nonblocking
281
300
  @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY|IO::NONBLOCK, 0666
282
301
  assert @mq.nonblock?
@@ -337,6 +356,20 @@ class Test_POSIX_MQ < Test::Unit::TestCase
337
356
  assert_raises(Errno::EAGAIN) { @mq << '.' }
338
357
  end
339
358
 
359
+ def test_try
360
+ mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK, 1, 1, 0)
361
+ @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666, mq_attr
362
+
363
+ assert_nil @mq.tryreceive
364
+ assert_nil @mq.tryshift
365
+ assert_equal true, @mq.trysend("a")
366
+ assert_equal [ "a", 0 ], @mq.tryreceive
367
+ assert_equal true, @mq.trysend("b")
368
+ assert_equal "b", @mq.tryshift
369
+ assert_equal true, @mq.trysend("c")
370
+ assert_equal false, @mq.trysend("d")
371
+ end
372
+
340
373
  def test_prio_max
341
374
  min_posix_mq_prio_max = 31 # defined by POSIX
342
375
  assert POSIX_MQ::PRIO_MAX >= min_posix_mq_prio_max
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: posix_mq
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
5
- prerelease:
4
+ hash: 961915908
5
+ prerelease: 5
6
6
  segments:
7
7
  - 0
8
- - 7
8
+ - 8
9
9
  - 0
10
- version: 0.7.0
10
+ - pre
11
+ version: 0.8.0pre
11
12
  platform: ruby
12
13
  authors:
13
14
  - Ruby POSIX MQ hackers
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-02-24 00:00:00 +00:00
19
+ date: 2011-02-27 00:00:00 +00:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -102,12 +103,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
103
  required_rubygems_version: !ruby/object:Gem::Requirement
103
104
  none: false
104
105
  requirements:
105
- - - ">="
106
+ - - ">"
106
107
  - !ruby/object:Gem::Version
107
- hash: 3
108
+ hash: 25
108
109
  segments:
109
- - 0
110
- version: "0"
110
+ - 1
111
+ - 3
112
+ - 1
113
+ version: 1.3.1
111
114
  requirements: []
112
115
 
113
116
  rubyforge_project: qrp