posix-mqueue 0.0.1 → 0.0.2

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.
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