posix_mq 0.7.0 → 0.8.0pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.wrongdoc.yml +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/ext/posix_mq/posix_mq.c +95 -32
- data/lib/posix_mq.rb +0 -5
- data/test/test_posix_mq.rb +41 -8
- metadata +12 -9
data/.wrongdoc.yml
CHANGED
data/GIT-VERSION-GEN
CHANGED
data/ext/posix_mq/posix_mq.c
CHANGED
@@ -62,10 +62,13 @@ static int MQ_IO_CLOSE(struct posix_mq *mq)
|
|
62
62
|
}
|
63
63
|
#endif
|
64
64
|
|
65
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
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
|
-
|
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
|
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(
|
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
|
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
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
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 (
|
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
|
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",
|
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?",
|
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
|
data/test/test_posix_mq.rb
CHANGED
@@ -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(
|
102
|
-
libcs.each do |
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 961915908
|
5
|
+
prerelease: 5
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 8
|
9
9
|
- 0
|
10
|
-
|
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-
|
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:
|
108
|
+
hash: 25
|
108
109
|
segments:
|
109
|
-
-
|
110
|
-
|
110
|
+
- 1
|
111
|
+
- 3
|
112
|
+
- 1
|
113
|
+
version: 1.3.1
|
111
114
|
requirements: []
|
112
115
|
|
113
116
|
rubyforge_project: qrp
|