Class: ZMQ::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/0mq/context.rb

Overview

The context object encapsulates all the global state associated with the library.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeContext

Returns a new instance of Context.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/0mq/context.rb', line 11

def initialize
  # FFI socket pointer for this context
  @pointer = LibZMQ.zmq_ctx_new
  
  # List of FFI socket pointers associated with this context.
  # Each Socket is responsible for registering and unregistering
  # its pointer from the Context it is associated with.
  # See #register_socket_pointer and #unregister_socket_pointer,
  # as well as #terminate and self.finalizer (where they get closed)
  @socket_pointers = Array.new
  @socket_pointers_mutex = Mutex.new
  
  ObjectSpace.define_finalizer self,
    self.class.finalizer(@pointer, @socket_pointers, Process.pid)
end

Instance Attribute Details

#pointerObject (readonly)

The FFI pointer to the context.



9
10
11
# File 'lib/0mq/context.rb', line 9

def pointer
  @pointer
end

Class Method Details

.finalizer(pointer, socket_pointers, pid) ⇒ Object

Create a safe finalizer for the context pointer to terminate on GC



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/0mq/context.rb', line 56

def self.finalizer(pointer, socket_pointers, pid)
  Proc.new do
    if Process.pid == pid
      # Close all socket pointers associated with this context.
      #
      # If any of these sockets are still open when zmq_ctx_term is called,
      # the call will hang.  This is problematic, as the execution of
      # finalizers is not multithreaded, and the order of finalizers is not
      # guaranteed.  Even when the Sockets each hold a reference to the
      # Context, the Context could still be GCed first, causing lockup.
      socket_pointers.each { |ptr| LibZMQ.zmq_close ptr }
      socket_pointers.clear
      
      LibZMQ.respond_to?(:zmq_ctx_term) ? 
        LibZMQ.zmq_ctx_term(pointer)    : 
        LibZMQ.zmq_term(pointer)
    end
  end
end

Instance Method Details

#register_socket_pointer(pointer) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



28
29
30
31
32
# File 'lib/0mq/context.rb', line 28

def register_socket_pointer pointer
  @socket_pointers_mutex.synchronize do
    @socket_pointers.push pointer
  end
end

#socket(type, opts = {}) ⇒ Object

Create a Socket within this context.



77
78
79
80
# File 'lib/0mq/context.rb', line 77

def socket(type, opts={})
  opts[:context] = self
  ZMQ::Socket.new type, opts
end

#terminateObject

Destroy the ØMQ context.



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/0mq/context.rb', line 42

def terminate
  if @pointer
    ObjectSpace.undefine_finalizer self
    
    rc = LibZMQ.respond_to?(:zmq_ctx_term) ? 
      LibZMQ.zmq_ctx_term(pointer)   : 
      LibZMQ.zmq_term(pointer)
    ZMQ.error_check true if rc==-1
    
    @pointer = nil
  end
end

#to_ptrObject

Returns the context’s FFI pointer.



83
84
85
# File 'lib/0mq/context.rb', line 83

def to_ptr
  @pointer
end

#unregister_socket_pointer(pointer) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



35
36
37
38
39
# File 'lib/0mq/context.rb', line 35

def unregister_socket_pointer pointer
  @socket_pointers_mutex.synchronize do
    @socket_pointers.delete pointer
  end
end