posix-mqueue 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d43379130238e323d67a9fdee4cfabd81a72661
4
- data.tar.gz: 8f61ef81dcacc70618cd4a61d6828d6321004e5f
3
+ metadata.gz: 4684343b93a70e5ade31414a548044a4bdd67180
4
+ data.tar.gz: 03463a0abb8c142b7832812a04915e98ddfdc825
5
5
  SHA512:
6
- metadata.gz: d90c99dd26fcbb147042fbfa5301eccbb71401359d2e0a7a8c621483dcab297833526fc4b89b8fd5ac26dcd4272bc5652da3ba93e6de3aa0d520c93f4e32133d
7
- data.tar.gz: 9aba8450a25e9045605c9f9effa72d5c240953b4c53b451e3b58bd5abdfe25b38b880d6e211363d702db7489762e601d004df41b034d702a7a3913d9d60131d6
6
+ metadata.gz: 4996b7a36d757fc0f47961309a6b804c927de5ead7ff204914153f69e70a409f5e0a4d81761ac4d605b27182ccea259a6f71c6cfcdbf22237e22bb602ec0e371
7
+ data.tar.gz: 2083fe220f4b7e3e9ba22a8a9f42a965546d0f8e2bc2f26ef500ca5d409980e1766775dc136ccd8079481e6c41649ccbe8e87fd03bb999c458bba46a71ca3bb8
data/.gitignore CHANGED
@@ -15,3 +15,7 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.o
19
+ *.so
20
+ Makefile
21
+ *.log
data/README.md CHANGED
@@ -1,5 +1,31 @@
1
- # Posix::Mqueue
1
+ # posix-mqueue
2
2
 
3
- Minimal wrapper around the [POSIX message queue](pmq).
3
+ Minimal wrapper around the [POSIX message queue](pmq). The POSIX message queue
4
+ offers:
5
+
6
+ * Persistence. Push messages while nothing is listening.
7
+ * Simplicity. Nothing to set up. Built into Linux.
8
+ * IPC. Blazingly fast communication between processes on the same machine.
9
+ * Blocking and non-blocking. Listeners block until a message arrives on the
10
+ queue. No polling. Sending messages doesn't block.
11
+
12
+ Add `gem 'posix-mqueue'` to your favorite Gemfile.
13
+
14
+ Still WIP. Not stable. Not everything works as promised.
15
+
16
+ ## Usage
17
+
18
+ ```ruby
19
+ m = POSIX::Mqueue.new("/whatever")
20
+ m.send "hello"
21
+ puts m.receive
22
+ # => "hello"
23
+
24
+ fork { POSIX::Mqueue.new("/whatever").send("world") }
25
+
26
+ # Blocks until the forked process pushes to the queue
27
+ m.receive
28
+ # => "world"
29
+ ```
4
30
 
5
31
  [pmq]: http://man7.org/linux/man-pages/man7/mq_overview.7.html
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.pattern = "test/**/*_test.rb"
7
+ end
@@ -1,3 +1,3 @@
1
1
  require 'mkmf'
2
2
  have_header('mqueue.h')
3
- create_makefile('mqueue')
3
+ create_makefile('posix/mqueue')
@@ -1,4 +1,5 @@
1
1
  #include <ruby.h>
2
+ #include <ruby/util.h>
2
3
 
3
4
  #include <mqueue.h>
4
5
  #include <fcntl.h>
@@ -7,20 +8,11 @@
7
8
  #include <stdlib.h>
8
9
  #include <stdio.h>
9
10
 
10
- mqd_t
11
- rb_mqueue_fd(const char *queue, const struct mq_attr *attr) {
12
- mqd_t fd = mq_open("/mqueue", O_CREAT | O_RDWR, S_IRWXU | S_IRWXO | S_IRWXG, attr);
13
-
14
- if (fd == (mqd_t)-1) {
15
- rb_sys_fail("fak rubby");
16
- }
17
-
18
- return fd;
19
- }
20
-
21
11
  typedef struct {
22
12
  mqd_t fd;
23
13
  struct mq_attr attr;
14
+ size_t queue_len;
15
+ char *queue;
24
16
  }
25
17
  mqueue_t;
26
18
 
@@ -35,13 +27,15 @@ mqueue_free(void* ptr)
35
27
  {
36
28
  mqueue_t* data = ptr;
37
29
  mq_close(data->fd);
30
+ xfree(data->queue);
38
31
  xfree(ptr);
39
32
  }
40
33
 
41
34
  static size_t
42
35
  mqueue_memsize(const void* ptr)
43
36
  {
44
- return sizeof(mqueue_t);
37
+ const mqueue_t* data = ptr;
38
+ return sizeof(mqueue_t) + sizeof(char) * data->queue_len;
45
39
  }
46
40
 
47
41
  static const rb_data_type_t
@@ -58,7 +52,26 @@ static VALUE
58
52
  posix_mqueue_alloc(VALUE klass)
59
53
  {
60
54
  mqueue_t* data;
61
- return TypedData_Make_Struct(klass, mqueue_t, &mqueue_type, data);
55
+ VALUE obj = TypedData_Make_Struct(klass, mqueue_t, &mqueue_type, data);
56
+
57
+ data->fd = -1;
58
+ data->queue = NULL;
59
+ data->queue_len = 0;
60
+
61
+ return obj;
62
+ }
63
+
64
+ VALUE posix_mqueue_unlink(VALUE self)
65
+ {
66
+ mqueue_t* data;
67
+
68
+ TypedData_Get_Struct(self, mqueue_t, &mqueue_type, data);
69
+
70
+ if (mq_unlink(data->queue) == -1) {
71
+ rb_sys_fail("Message queue unlinking failed");
72
+ }
73
+
74
+ return Qtrue;
62
75
  }
63
76
 
64
77
  VALUE posix_mqueue_send(VALUE self, VALUE message)
@@ -69,15 +82,14 @@ VALUE posix_mqueue_send(VALUE self, VALUE message)
69
82
  TypedData_Get_Struct(self, mqueue_t, &mqueue_type, data);
70
83
 
71
84
  if (!RB_TYPE_P(message, T_STRING)) {
72
- rb_raise(rb_eTypeError, "fak u rubby");
85
+ rb_raise(rb_eTypeError, "Message must be a string");
73
86
  }
74
87
 
75
- // FIXME: is rstring_len with or without \0?
76
88
  // TODO: Custom priority
77
89
  err = mq_send(data->fd, RSTRING_PTR(message), RSTRING_LEN(message), 10);
78
90
 
79
91
  if (err < 0) {
80
- rb_sys_fail("fak rubby");
92
+ rb_sys_fail("Message sending failed");
81
93
  }
82
94
 
83
95
  return Qtrue;
@@ -103,7 +115,7 @@ VALUE posix_mqueue_receive(VALUE self)
103
115
  err = mq_receive(data->fd, buf, buf_size, NULL);
104
116
 
105
117
  if (err < 0) {
106
- rb_sys_fail("fak rubby");
118
+ rb_sys_fail("Message retrieval failed");
107
119
  }
108
120
 
109
121
  str = rb_str_new(buf, err);
@@ -117,20 +129,28 @@ VALUE posix_mqueue_initialize(VALUE self, VALUE queue)
117
129
  // TODO: Modify these options from initialize arguments
118
130
  // TODO: Set nonblock and handle error in #push
119
131
  struct mq_attr attr = {
120
- .mq_flags = 0, // Flags, 0 or O_NONBLOCK
121
- .mq_maxmsg = 100, // Max messages in queue
122
- .mq_msgsize = 512, // Max message size (bytes)
123
- .mq_curmsgs = 0 // # currently in queue
132
+ .mq_flags = 0, // Flags, 0 or O_NONBLOCK
133
+ .mq_maxmsg = 10, // Max messages in queue
134
+ .mq_msgsize = 512, // Max message size (bytes)
135
+ .mq_curmsgs = 0 // # currently in queue
124
136
  };
125
137
 
126
138
  mqueue_t* data;
127
139
  TypedData_Get_Struct(self, mqueue_t, &mqueue_type, data);
128
140
 
141
+ if (data->fd != -1) {
142
+ // This would cause a memleak otherwise
143
+ rb_raise(rb_eRuntimeError, "Illegal reinitialization");
144
+ }
145
+
129
146
  data->attr = attr;
147
+ data->queue_len = RSTRING_LEN(queue);
148
+ data->queue = ruby_strdup(StringValueCStr(queue));
149
+ data->fd = mq_open(data->queue, O_CREAT | O_RDWR, S_IRWXU | S_IRWXO | S_IRWXG, &data->attr);
130
150
 
131
- // FIXME: This is probably dangerous since I don't whether the value is
132
- // actually a string.
133
- data->fd = rb_mqueue_fd(StringValueCStr(queue), &data->attr);
151
+ if (data->fd == (mqd_t)-1) {
152
+ rb_sys_fail("Failed opening the message queue");
153
+ }
134
154
 
135
155
  return self;
136
156
  }
@@ -143,5 +163,6 @@ void Init_mqueue()
143
163
  rb_define_method(mqueue, "initialize", posix_mqueue_initialize, 1);
144
164
  rb_define_method(mqueue, "send", posix_mqueue_send, 1);
145
165
  rb_define_method(mqueue, "receive", posix_mqueue_receive, 0);
166
+ rb_define_method(mqueue, "unlink", posix_mqueue_unlink, 0);
146
167
  }
147
168
 
@@ -1,5 +1,5 @@
1
1
  module POSIX
2
2
  class Mqueue
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
data/posix-mqueue.gemspec CHANGED
@@ -16,8 +16,8 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files`.split($/)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
- spec.extensions = ["ext/extconf.rb"]
19
+ spec.require_paths = ["lib", "ext"]
20
+ spec.extensions = ["ext/posix/extconf.rb"]
21
21
 
22
22
  spec.add_development_dependency "bundler", "~> 1.3"
23
23
  spec.add_development_dependency "rake"
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ class MqueueTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ @queue_name = "/test-queue"
6
+ @queue = POSIX::Mqueue.new(@queue_name)
7
+ end
8
+
9
+ def teardown
10
+ @queue.unlink
11
+ end
12
+
13
+ def test_send_and_receive_single_message
14
+ @queue.send "hello"
15
+ assert_equal "hello", @queue.receive
16
+ end
17
+
18
+ def test_send_and_receive_multiple_messages
19
+ @queue.send "hello"
20
+ @queue.send "world"
21
+
22
+ assert_equal "hello", @queue.receive
23
+ assert_equal "world", @queue.receive
24
+ end
25
+
26
+ def test_receiver_blocks
27
+ @queue.send "hello"
28
+
29
+ assert_equal "hello", @queue.receive
30
+
31
+ fork { POSIX::Mqueue.new(@queue_name).send("world") }
32
+
33
+ assert_equal "world", @queue.receive
34
+ end
35
+
36
+ def test_multiple_queues
37
+ @queue.send "hello"
38
+
39
+ other = POSIX::Mqueue.new("/other-test-queue")
40
+ other.send "world"
41
+
42
+ assert_equal "world", other.receive
43
+ assert_equal "hello", @queue.receive
44
+
45
+ other.unlink
46
+ end
47
+
48
+ # def test_send_raises_exception_instead_of_blocking
49
+ # 10.times { @queue.send "walrus" }
50
+
51
+ # assert_raises Exception do
52
+ # @queue.send "hi"
53
+ # end
54
+ # end
55
+ end
data/test/test_helper.rb CHANGED
@@ -3,4 +3,4 @@ require 'minitest/autorun'
3
3
 
4
4
  $: << File.dirname(__FILE__) + '/../ext'
5
5
 
6
- require 'mqueue.so'
6
+ require "posix/mqueue/mqueue"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: posix-mqueue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Eskildsen
@@ -43,7 +43,7 @@ email:
43
43
  - sirup@sirupsen.com
44
44
  executables: []
45
45
  extensions:
46
- - ext/extconf.rb
46
+ - ext/posix/extconf.rb
47
47
  extra_rdoc_files: []
48
48
  files:
49
49
  - .gitignore
@@ -51,13 +51,12 @@ files:
51
51
  - LICENSE.txt
52
52
  - README.md
53
53
  - Rakefile
54
- - ext/extconf.rb
55
- - ext/mqueue.c
56
- - lib/posix/mqueue.rb
54
+ - ext/posix/extconf.rb
55
+ - ext/posix/mqueue.c
57
56
  - lib/posix/mqueue/version.rb
58
57
  - posix-mqueue.gemspec
58
+ - test/mqueue_test.rb
59
59
  - test/test_helper.rb
60
- - test/test_mqueue.rb
61
60
  homepage: ''
62
61
  licenses:
63
62
  - MIT
@@ -66,6 +65,7 @@ post_install_message:
66
65
  rdoc_options: []
67
66
  require_paths:
68
67
  - lib
68
+ - ext
69
69
  required_ruby_version: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - '>='
@@ -83,5 +83,5 @@ signing_key:
83
83
  specification_version: 4
84
84
  summary: posix-mqueue is a simple wrapper around the mqueue(7). It only works on Linux.
85
85
  test_files:
86
+ - test/mqueue_test.rb
86
87
  - test/test_helper.rb
87
- - test/test_mqueue.rb
data/lib/posix/mqueue.rb DELETED
@@ -1,6 +0,0 @@
1
- require "posix/mqueue/version"
2
-
3
- module POSIX
4
- class Mqueue
5
- end
6
- end
data/test/test_mqueue.rb DELETED
@@ -1,9 +0,0 @@
1
- require 'test_helper'
2
-
3
- class MqueueTest < MiniTest::Unit::TestCase
4
- def test_send_and_receive
5
- m = POSIX::Mqueue.new("/whatever")
6
- m.send("hello")
7
- assert_equal "hello", m.receive
8
- end
9
- end