0mq 0.5.1 → 0.5.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: b804860f9ff37973173ff9061a18674bfebfdc1d
4
- data.tar.gz: fb5c958be97696bed9da3faa6c04bc7362377234
3
+ metadata.gz: 136e40f0d38d2aa86916cc8134140819f3b6153d
4
+ data.tar.gz: b9dc4d0d931e3069dcd6f72705d23276e5b96fd5
5
5
  SHA512:
6
- metadata.gz: 16dbace3339b1acf206c4f9cdcb33bedb8a92291748feec4c6a437b55a3595245aa6ba12502f8e39ddf4416ffd543288a4e164ad47ed56960e2e48da117acd1c
7
- data.tar.gz: 31357bb71a7f4f43525f328ee87a195472d6d4f1d22f1391f44b456043cb4e3841353f7922b5a7d75e8a22fe0e6c7e19ea59932a482b8f0596ac9449095c212e
6
+ metadata.gz: 6e78f5d97aac700192c295c5c246e310154c1a259d7f9e478552bcadf62daec60aee60994c8bba0cd8430fd872a7cd6f8de9bd73f577d7058fe0557b67198069
7
+ data.tar.gz: fedd23a1ff754f4e94da1388990633dea10b1b87b48951189093d3b801e5d4d24dfd6ce051c7330a10d1e77f4b536099fc87048ff3b01a4d3fe1cbf3ba3ef3d0
data/lib/0mq.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'ffi-rzmq-core'
2
2
 
3
- require_relative '0mq/error_map'
3
+ require_relative '0mq/error_check'
4
4
 
5
5
  require_relative '0mq/context'
6
6
  require_relative '0mq/socket'
@@ -9,21 +9,70 @@ module ZMQ
9
9
  attr_reader :pointer
10
10
 
11
11
  def initialize
12
+ # FFI socket pointer for this context
12
13
  @pointer = LibZMQ.zmq_ctx_new
14
+
15
+ # List of FFI socket pointers associated with this context.
16
+ # Each Socket is responsible for registering and unregistering
17
+ # its pointer from the Context it is associated with.
18
+ # See #register_socket_pointer and #unregister_socket_pointer,
19
+ # as well as #terminate and self.finalizer (where they get closed)
20
+ @socket_pointers = Array.new
21
+ @socket_pointers_mutex = Mutex.new
22
+
23
+ ObjectSpace.define_finalizer self,
24
+ self.class.finalizer(@pointer, @socket_pointers, Process.pid)
25
+ end
26
+
27
+ # @api private
28
+ def register_socket_pointer pointer
29
+ @socket_pointers_mutex.synchronize do
30
+ @socket_pointers.push pointer
31
+ end
32
+ end
33
+
34
+ # @api private
35
+ def unregister_socket_pointer pointer
36
+ @socket_pointers_mutex.synchronize do
37
+ @socket_pointers.delete pointer
38
+ end
13
39
  end
14
40
 
15
41
  # Destroy the ØMQ context.
16
42
  def terminate
17
43
  if @pointer
18
- rc = LibZMQ.version4? ?
19
- LibZMQ.zmq_ctx_term(@pointer) :
20
- LibZMQ.zmq_term(@pointer)
21
- ZMQ.error_check true if rc == -1
44
+ ObjectSpace.undefine_finalizer self
45
+
46
+ rc = LibZMQ.respond_to?(:zmq_ctx_term) ?
47
+ LibZMQ.zmq_ctx_term(pointer) :
48
+ LibZMQ.zmq_term(pointer)
49
+ ZMQ.error_check true if rc==-1
22
50
 
23
51
  @pointer = nil
24
52
  end
25
53
  end
26
54
 
55
+ # Create a safe finalizer for the context pointer to terminate on GC
56
+ def self.finalizer(pointer, socket_pointers, pid)
57
+ Proc.new do
58
+ if Process.pid == pid
59
+ # Close all socket pointers associated with this context.
60
+ #
61
+ # If any of these sockets are still open when zmq_ctx_term is called,
62
+ # the call will hang. This is problematic, as the execution of
63
+ # finalizers is not multithreaded, and the order of finalizers is not
64
+ # guaranteed. Even when the Sockets each hold a reference to the
65
+ # Context, the Context could still be GCed first, causing lockup.
66
+ socket_pointers.each { |ptr| LibZMQ.zmq_close ptr }
67
+ socket_pointers.clear
68
+
69
+ LibZMQ.respond_to?(:zmq_ctx_term) ?
70
+ LibZMQ.zmq_ctx_term(pointer) :
71
+ LibZMQ.zmq_term(pointer)
72
+ end
73
+ end
74
+ end
75
+
27
76
  # Create a Socket within this context.
28
77
  def socket(type, opts={})
29
78
  opts[:context] = self
@@ -3,12 +3,12 @@ module ZMQ
3
3
 
4
4
  # A hash of error number => exception class.
5
5
  # Example: 1 => Errno::EPERM
6
- ErrorMap = Hash.new
6
+ @error_map = Hash.new
7
7
 
8
8
  Errno.constants
9
9
  .map { |x| Errno.const_get x }
10
10
  .select { |x| x.is_a?(Class) && x < SystemCallError }
11
- .each { |x| ErrorMap[x.const_get(:Errno)] = x }
11
+ .each { |x| @error_map[x.const_get(:Errno)] = x }
12
12
 
13
13
 
14
14
  # Checks the libzmq global error number and raises it as an exception.
@@ -16,11 +16,14 @@ module ZMQ
16
16
  # Example: ZMQ.error_check if rc == -1
17
17
  def self.error_check(adjust_backtrace=false)
18
18
  errno = LibZMQ.zmq_errno
19
- return true if errno == 25
19
+ return true if errno == 25 # TODO: What is this for? Remove?
20
20
 
21
- # TODO: Use adjust_backtrace
22
- str = ''
23
- raise ErrorMap[errno], str, caller[0...-2]
21
+ backtrace = adjust_backtrace ? caller[0...-2] : caller
22
+ if @error_map.has_key? errno
23
+ raise @error_map[errno], '', backtrace
24
+ else
25
+ raise SystemCallError, errno.to_s, backtrace
26
+ end
24
27
  end
25
28
 
26
29
  end
@@ -106,7 +106,5 @@ module ZMQ
106
106
  @dead
107
107
  end
108
108
 
109
- # TODO: add finalizer for cleanup for neglectful user developers
110
-
111
109
  end
112
110
  end
@@ -23,8 +23,10 @@ module ZMQ
23
23
 
24
24
  @msgptr = FFI::MemoryPointer.new LibZMQ::Message.size, 1, false
25
25
 
26
+ @context.send :register_socket_pointer, @pointer
27
+
26
28
  ObjectSpace.define_finalizer self,
27
- self.class.finalizer(@socket, Process.pid)
29
+ self.class.finalizer(@pointer, @context, Process.pid)
28
30
  end
29
31
 
30
32
  # Show a useful inspect output
@@ -37,13 +39,16 @@ module ZMQ
37
39
  @closed = true
38
40
 
39
41
  if @pointer
40
- ObjectSpace.undefine_finalizer self
41
42
  @temp_buffers.clear if @temp_buffers
42
43
 
44
+ ObjectSpace.undefine_finalizer self
45
+ @context.send :unregister_socket_pointer, @pointer
46
+
43
47
  rc = LibZMQ.zmq_close @pointer
44
48
  ZMQ.error_check true if rc==-1
45
49
 
46
50
  @pointer = nil
51
+ @context = nil
47
52
  end
48
53
  end
49
54
 
@@ -52,9 +57,14 @@ module ZMQ
52
57
  @closed
53
58
  end
54
59
 
55
- # Create a safe finalizer for the socket pointer to close on GC of the object
56
- def self.finalizer(pointer, pid)
57
- Proc.new { LibZMQ.zmq_close pointer if Process.pid == pid }
60
+ # Create a safe finalizer for the socket pointer to close on GC
61
+ def self.finalizer(pointer, context, pid)
62
+ Proc.new do
63
+ if Process.pid == pid
64
+ context.send :unregister_socket_pointer, pointer
65
+ LibZMQ.zmq_close pointer
66
+ end
67
+ end
58
68
  end
59
69
 
60
70
  # Get the socket type name as a symbol
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 0mq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe McIlvain
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-08 00:00:00.000000000 Z
12
+ date: 2014-06-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi-rzmq-core
@@ -134,7 +134,7 @@ files:
134
134
  - lib/0mq.rb
135
135
  - lib/0mq/context.rb
136
136
  - lib/0mq/curve.rb
137
- - lib/0mq/error_map.rb
137
+ - lib/0mq/error_check.rb
138
138
  - lib/0mq/poll.rb
139
139
  - lib/0mq/poll_interruptible.rb
140
140
  - lib/0mq/proxy.rb