ffi-rxs 1.1.0 → 1.2.0

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.
@@ -1,100 +0,0 @@
1
- module XS
2
- # Set up all of the constants
3
-
4
- # Socket types
5
- PAIR = 0
6
- PUB = 1
7
- SUB = 2
8
- REQ = 3
9
- REP = 4
10
- XREQ = 5
11
- XREP = 6
12
- PULL = 7
13
- PUSH = 8
14
- XPUB = 9
15
- XSUB = 10
16
- DEALER = XREQ
17
- ROUTER = XREP
18
-
19
- SocketTypeNameMap = {
20
- PAIR => "PAIR",
21
- PUB => "PUB",
22
- SUB => "SUB",
23
- REQ => "REQ",
24
- REP => "REP",
25
- PULL => "PULL",
26
- PUSH => "PUSH",
27
- XREQ => "XREQ",
28
- XREP => "XREP",
29
- ROUTER => "ROUTER",
30
- DEALER => "DEALER",
31
- XPUB => "XPUB",
32
- XSUB => "XSUB"
33
- }
34
-
35
- # Socket options
36
- AFFINITY = 4
37
- IDENTITY = 5
38
- SUBSCRIBE = 6
39
- UNSUBSCRIBE = 7
40
- RATE = 8
41
- RECOVERY_IVL = 9
42
- SNDBUF = 11
43
- RCVBUF = 12
44
- RCVMORE = 13
45
- FD = 14
46
- EVENTS = 15
47
- TYPE = 16
48
- LINGER = 17
49
- RECONNECT_IVL = 18
50
- BACKLOG = 19
51
- RECONNECT_IVL_MAX = 21
52
- MAXMSGSIZE = 22
53
- SNDHWM = 23
54
- RCVHWM = 24
55
- MULTICAST_HOPS = 25
56
- RCVTIMEO = 27
57
- SNDTIMEO = 28
58
-
59
- # Send/recv options
60
- DONTWAIT = 1
61
- SNDMORE = 2
62
- SNDLABEL = 4
63
- NonBlocking = DONTWAIT
64
-
65
- # I/O multiplexing
66
-
67
- POLL = 1
68
- POLLIN = 1
69
- POLLOUT = 2
70
- POLLERR = 4
71
-
72
- # Socket errors
73
- EAGAIN = Errno::EAGAIN::Errno
74
- EFAULT = Errno::EFAULT::Errno
75
- EINVAL = Errno::EINVAL::Errno
76
- EMFILE = Errno::EMFILE::Errno
77
- ENOMEM = Errno::ENOMEM::Errno
78
- ENODEV = Errno::ENODEV::Errno
79
-
80
- # XS errors
81
- HAUSNUMERO = 156384712
82
- EMTHREAD = (HAUSNUMERO + 50)
83
- EFSM = (HAUSNUMERO + 51)
84
- ENOCOMPATPROTO = (HAUSNUMERO + 52)
85
- ETERM = (HAUSNUMERO + 53)
86
-
87
- # Rescue unknown constants and use the Crossroads defined values
88
- # Usually only happens on Windows though some don't resolve on
89
- # OSX too (ENOTSUP)
90
- ENOTSUP = Errno::ENOTSUP::Errno rescue (HAUSNUMERO + 1)
91
- EPROTONOSUPPORT = Errno::EPROTONOSUPPORT::Errno rescue (HAUSNUMERO + 2)
92
- ENOBUFS = Errno::ENOBUFS::Errno rescue (HAUSNUMERO + 3)
93
- ENETDOWN = Errno::ENETDOWN::Errno rescue (HAUSNUMERO + 4)
94
- EADDRINUSE = Errno::EADDRINUSE::Errno rescue (HAUSNUMERO + 5)
95
- EADDRNOTAVAIL = Errno::EADDRNOTAVAIL::Errno rescue (HAUSNUMERO + 6)
96
- ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue (HAUSNUMERO + 7)
97
- EINPROGRESS = Errno::EINPROGRESS::Errno rescue (HAUSNUMERO + 8)
98
- ENOTSOCK = Errno::ENOTSOCK::Errno rescue (HAUSNUMERO + 9)
99
- EINTR = Errno::EINTR::Errno rescue (HAUSNUMERO + 10)
100
- end # module XS
@@ -1,155 +0,0 @@
1
-
2
- module XS
3
-
4
-
5
- # Recommended to use the default for +io_threads+
6
- # since most programs will not saturate I/O.
7
- #
8
- # The rule of thumb is to make +io_threads+ equal to the number
9
- # gigabits per second that the application will produce.
10
- #
11
- # The +io_threads+ number specifies the size of the thread pool
12
- # allocated by 0mq for processing incoming/outgoing messages.
13
- #
14
- # Returns a context object when allocation succeeds. It's necessary
15
- # for passing to the
16
- # #Socket constructor when allocating new sockets. All sockets
17
- # live within a context.
18
- #
19
- # Also, Sockets should *only* be accessed from the thread where they
20
- # were first created. Do *not* pass sockets between threads; pass
21
- # in the context and allocate a new socket per thread. If you must
22
- # use threads, then make sure to execute a full memory barrier (e.g.
23
- # mutex) as you pass a socket from one thread to the next.
24
- #
25
- # To connect sockets between contexts, use +inproc+ or +ipc+
26
- # transport and set up a Crossroads socket between them. This is also the
27
- # recommended technique for allowing sockets to communicate between
28
- # threads.
29
- #
30
- # context = XS::Context.create
31
- # if context
32
- # socket = context.socket(XS::REQ)
33
- # if socket
34
- # ...
35
- # else
36
- # STDERR.puts "Socket allocation failed"
37
- # end
38
- # else
39
- # STDERR.puts "Context allocation failed"
40
- # end
41
- #
42
- #
43
- class Context
44
- include XS::Util
45
-
46
- attr_reader :context, :pointer
47
-
48
- def self.create
49
- new() rescue nil
50
- end
51
-
52
- # Use the factory method Context#create to make contexts.
53
- #
54
- def initialize
55
- @sockets = []
56
- @context = LibXS.xs_init()
57
- @pointer = @context
58
- error_check 'xs_init', (@context.nil? || @context.null?) ? -1 : 0
59
-
60
- define_finalizer
61
- end
62
-
63
- # Set options on this context.
64
- #
65
- # Context options take effect only if set with setctxopt() prior to
66
- # creating the first socket in a given context with socket().
67
- #
68
- # Valid +name+ values that take a numeric +value+ are:
69
- # XS::IO_THREADS
70
- # XS::MAX_SOCKETS
71
- #
72
- # Returns 0 when the operation completed successfully.
73
- # Returns -1 when this operation failed.
74
- #
75
- # With a -1 return code, the user must check XS.errno to determine the
76
- # cause.
77
- #
78
- # rc = context.setctxopt(XS::IO_THREADS, 10)
79
- # XS::Util.resultcode_ok?(rc) ? puts("succeeded") : puts("failed")
80
- #
81
- def setctxopt name, value, length = nil
82
- #if (name == XS::IO_THREADS) || (name == XS::MAX_SOCKETS)
83
- length = 4
84
- pointer = LibC.malloc length
85
- pointer.write_int value
86
- #end
87
-
88
- rc = LibXS.xs_setctxopt @context, name, pointer, length
89
- LibC.free(pointer) unless pointer.nil? || pointer.null?
90
- rc
91
- end
92
-
93
- # Call to release the context and any remaining data associated
94
- # with past sockets. This will close any sockets that remain
95
- # open; further calls to those sockets will return -1 to indicate
96
- # the operation failed.
97
- #
98
- # Returns 0 for success, -1 for failure.
99
- #
100
- def terminate
101
- unless @context.nil? || @context.null?
102
- remove_finalizer
103
- rc = LibXS.xs_term @context
104
- @context = nil
105
- @sockets = nil
106
- rc
107
- else
108
- 0
109
- end
110
- end
111
-
112
- # Short-cut to allocate a socket for a specific context.
113
- #
114
- # Takes several +type+ values:
115
- # #XS::REQ
116
- # #XS::REP
117
- # #XS::PUB
118
- # #XS::SUB
119
- # #XS::PAIR
120
- # #XS::PULL
121
- # #XS::PUSH
122
- # #XS::DEALER
123
- # #XS::ROUTER
124
- #
125
- # Returns a #XS::Socket when the allocation succeeds, nil
126
- # if it fails.
127
- #
128
- def socket type
129
- sock = nil
130
- begin
131
- sock = Socket.new @context, type
132
- rescue ContextError => e
133
- sock = nil
134
- end
135
-
136
- sock
137
- end
138
-
139
-
140
- private
141
-
142
- def define_finalizer
143
- ObjectSpace.define_finalizer(self, self.class.close(@context))
144
- end
145
-
146
- def remove_finalizer
147
- ObjectSpace.undefine_finalizer self
148
- end
149
-
150
- def self.close context
151
- Proc.new { LibXS.xs_term context unless context.null? }
152
- end
153
- end
154
-
155
- end # module XS
@@ -1,28 +0,0 @@
1
- module ZMQ
2
- if LibZMQ.version2?
3
- class Device
4
- attr_reader :device
5
-
6
- def self.create(device_type, frontend, backend)
7
- dev = nil
8
- begin
9
- dev = new device_type, frontend, backend
10
- rescue ArgumentError
11
- dev = nil
12
- end
13
-
14
- dev
15
- end
16
-
17
- def initialize(device_type,frontend,backend)
18
- [["frontend", frontend],["backend", backend]].each do |name,socket|
19
- unless socket.is_a?(ZMQ::Socket)
20
- raise ArgumentError, "Expected a ZMQ::Socket, not a #{socket.class} as the #{name}"
21
- end
22
- end
23
-
24
- LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
25
- end
26
- end
27
- end
28
- end
@@ -1,47 +0,0 @@
1
-
2
- module ZMQ
3
-
4
- class ZeroMQError < StandardError
5
- attr_reader :source, :result_code, :error_code, :message
6
-
7
- def initialize source, result_code, error_code, message
8
- @source = source
9
- @result_code = result_code
10
- @error_code = error_code
11
- @message = "msg [#{message}], error code [#{error_code}], rc [#{result_code}]"
12
- super message
13
- end
14
- end # call ZeroMQError
15
-
16
-
17
- class ContextError < ZeroMQError
18
- # True when the exception was raised due to the library
19
- # returning EINVAL.
20
- #
21
- # Occurs when he number of app_threads requested is less
22
- # than one, or the number of io_threads requested is
23
- # negative.
24
- #
25
- def einval?() EINVAL == @error_code; end
26
-
27
- # True when the exception was raised due to the library
28
- # returning ETERM.
29
- #
30
- # The associated context was terminated.
31
- #
32
- def eterm?() ETERM == @error_code; end
33
-
34
- end # class ContextError
35
-
36
-
37
- class MessageError < ZeroMQError
38
- # True when the exception was raised due to the library
39
- # returning ENOMEM.
40
- #
41
- # Only ever raised by the #Message class when it fails
42
- # to allocate sufficient memory to send a message.
43
- #
44
- def enomem?() ENOMEM == @error_code; end
45
- end
46
-
47
- end # module ZMQ
data/lib/ffi-rxs/libc.rb~ DELETED
@@ -1,19 +0,0 @@
1
-
2
- module LibC
3
- extend FFI::Library
4
- # figures out the correct libc for each platform including Windows
5
- library = ffi_lib(FFI::Library::LIBC).first
6
-
7
- # Size_t not working properly on Windows
8
- find_type(:size_t) rescue typedef(:ulong, :size_t)
9
-
10
- # memory allocators
11
- attach_function :malloc, [:size_t], :pointer
12
- attach_function :free, [:pointer], :void
13
-
14
- # get a pointer to the free function; used for ZMQ::Message deallocation
15
- Free = library.find_symbol('free')
16
-
17
- # memory movers
18
- attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
19
- end # module LibC
@@ -1,156 +0,0 @@
1
- module XS
2
-
3
- # Wraps the libxs library and attaches to the API functions
4
- #
5
- module LibXS
6
- extend FFI::Library
7
-
8
- begin
9
- # bias the library discovery to a path inside the gem first, then
10
- # to the usual system paths
11
- inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext')
12
- XS_LIB_PATHS = [
13
- inside_gem, '/usr/local/lib', '/opt/local/lib', '/usr/local/homebrew/lib', '/usr/lib64'
14
- ].map{|path| "#{path}/libxs.#{FFI::Platform::LIBSUFFIX}"}
15
- ffi_lib(XS_LIB_PATHS + %w{libxs})
16
- rescue LoadError
17
- STDERR.puts "Unable to load this gem. The libxs library (or DLL) could not be found."
18
- STDERR.puts "If this is a Windows platform, make sure libxs.dll is on the PATH."
19
- STDERR.puts "For non-Windows platforms, make sure libxs is located in this search path:"
20
- STDERR.puts XS_LIB_PATHS.inspect
21
- exit 255
22
- end
23
-
24
- # Size_t not working properly on Windows
25
- find_type(:size_t) rescue typedef(:ulong, :size_t)
26
-
27
- # Context and misc api
28
- #
29
- # @blocking = true is a hint to FFI that the following (and only the following)
30
- # function may block, therefore it should release the GIL before calling it.
31
- # This can aid in situations where the function call will/may block and another
32
- # thread within the lib may try to call back into the ruby runtime. Failure to
33
- # release the GIL will result in a hang; the hint *may* allow things to run
34
- # smoothly for Ruby runtimes hampered by a GIL.
35
- #
36
- # This is really only honored by the MRI implementation but it *is* necessary
37
- # otherwise the runtime hangs (and requires a kill -9 to terminate)
38
- #
39
- @blocking = true
40
- attach_function :xs_errno, [], :int
41
- @blocking = true
42
- attach_function :xs_init, [:int], :pointer
43
- @blocking = true
44
- attach_function :xs_setctxopt, [:pointer, :int, :pointer, :int], :int
45
- @blocking = true
46
- attach_function :xs_socket, [:pointer, :int], :pointer
47
- @blocking = true
48
- attach_function :xs_strerror, [:int], :pointer
49
- @blocking = true
50
- attach_function :xs_term, [:pointer], :int
51
- @blocking = true
52
- attach_function :xs_version, [:pointer, :pointer, :pointer], :void
53
-
54
- def self.version
55
- if @version.nil?
56
- major = FFI::MemoryPointer.new :int
57
- minor = FFI::MemoryPointer.new :int
58
- patch = FFI::MemoryPointer.new :int
59
- LibXS.xs_version major, minor, patch
60
- @version = {:major => major.read_int, :minor => minor.read_int, :patch => patch.read_int}
61
- end
62
-
63
- @version
64
- end
65
-
66
- # Message api
67
- @blocking = true
68
- attach_function :xs_msg_close, [:pointer], :int
69
- @blocking = true
70
- attach_function :xs_msg_copy, [:pointer, :pointer], :int
71
- @blocking = true
72
- attach_function :xs_msg_data, [:pointer], :pointer
73
- @blocking = true
74
- attach_function :xs_msg_init, [:pointer], :int
75
- @blocking = true
76
- attach_function :xs_msg_init_size, [:pointer, :size_t], :int
77
- @blocking = true
78
- attach_function :xs_msg_init_data, [:pointer, :pointer, :size_t, :pointer, :pointer], :int
79
- @blocking = true
80
- attach_function :xs_msg_move, [:pointer, :pointer], :int
81
- @blocking = true
82
- attach_function :xs_msg_size, [:pointer], :size_t
83
-
84
- # Used for casting pointers back to the struct
85
- #
86
- class Msg < FFI::Struct
87
- layout :content, :pointer,
88
- :flags, :uint8,
89
- :vsm_size, :uint8,
90
- :vsm_data, [:uint8, 30]
91
- end # class Msg
92
-
93
- # Socket api
94
- @blocking = true
95
- attach_function :xs_bind, [:pointer, :string], :int
96
- @blocking = true
97
- attach_function :xs_connect, [:pointer, :string], :int
98
- @blocking = true
99
- attach_function :xs_close, [:pointer], :int
100
- @blocking = true
101
- attach_function :xs_getsockopt, [:pointer, :int, :pointer, :pointer], :int
102
- @blocking = true
103
- attach_function :xs_recvmsg, [:pointer, :pointer, :int], :int
104
- @blocking = true
105
- attach_function :xs_recv, [:pointer, :pointer, :size_t, :int], :int
106
- @blocking = true
107
- attach_function :xs_sendmsg, [:pointer, :pointer, :int], :int
108
- @blocking = true
109
- attach_function :xs_send, [:pointer, :pointer, :size_t, :int], :int
110
- @blocking = true
111
- attach_function :xs_setsockopt, [:pointer, :int, :pointer, :int], :int
112
-
113
- # Poll api
114
- @blocking = true
115
- attach_function :xs_poll, [:pointer, :int, :long], :int
116
-
117
- module PollItemLayout
118
- def self.included(base)
119
- base.class_eval do
120
- layout :socket, :pointer,
121
- :fd, :int,
122
- :events, :short,
123
- :revents, :short
124
- end
125
- end
126
- end # module PollItemLayout
127
-
128
- class PollItem < FFI::Struct
129
- include PollItemLayout
130
-
131
- def socket() self[:socket]; end
132
-
133
- def fd() self[:fd]; end
134
-
135
- def readable?
136
- (self[:revents] & XS::POLLIN) > 0
137
- end
138
-
139
- def writable?
140
- (self[:revents] & XS::POLLOUT) > 0
141
- end
142
-
143
- def both_accessible?
144
- readable? && writable?
145
- end
146
-
147
- def inspect
148
- "socket [#{socket}], fd [#{fd}], events [#{self[:events]}], revents [#{self[:revents]}]"
149
- end
150
-
151
- def to_s; inspect; end
152
- end # class PollItem
153
-
154
- end
155
-
156
- end # module XS