ffi-rzmq-core-1.0.6/0000755000004100000410000000000013312112075014222 5ustar www-datawww-dataffi-rzmq-core-1.0.6/ffi-rzmq-core.gemspec0000644000004100000410000000176613312112075020262 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "ffi-rzmq-core/version" Gem::Specification.new do |s| s.name = "ffi-rzmq-core" s.version = LibZMQ::VERSION s.authors = ["Chuck Remes"] s.email = ["git@chuckremes.com"] s.homepage = "http://github.com/chuckremes/ffi-rzmq-core" s.summary = %q{This gem provides only the FFI wrapper for the ZeroMQ (0mq) networking library.} s.description = %q{This gem provides only the FFI wrapper for the ZeroMQ (0mq) networking library. Project can be used by any other zeromq gems that want to provide their own high-level Ruby API.} s.license = 'MIT' s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.add_runtime_dependency "ffi" s.add_development_dependency "rspec" s.add_development_dependency "rake" end ffi-rzmq-core-1.0.6/.travis.yml0000644000004100000410000000036513312112075016337 0ustar www-datawww-databefore_install: sudo apt-get install libzmq3-dev script: bundle exec rspec language: ruby rvm: - 1.9.3 - 2.0.0 - ruby-head - jruby-19mode - jruby-head - rbx-2.1.1 matrix: allow_failures: - rvm: ruby-head - rvm: jruby-head ffi-rzmq-core-1.0.6/README.md0000644000004100000410000000232513312112075015503 0ustar www-datawww-dataffi-rzmq-core ============= The intention of this gem is to provide a very basic FFI wrapper around the Zeromq libzmq C API. This gem isn't intended to be used directly by any Ruby programmer looking to write Zeromq code. They should use a higher-level gem like ffi-rzmq which pulls in this gem for its FFI definitions. There have been complaints that the ffi-rzmq gem doesn't provide the correct or best Ruby idioms, so I am hoping this encourages other library writers to create their own. Rather than duplicate the FFI wrapping code, they can just pull in this gem and build a more idiomatic library around the basic definitions. As of zeromq 4.2.x, this library does not yet support the `zmq_atomic_counter_*` functions or many of the other newly exposed functions. Pull requests encouraged! See [ffi-rzmq] ### Development As this library supports both ZeroMQ 3.2+ and ZeroMQ 4.0+ it's common to have to swap out which version of ZeroMQ is installed to test out various features (say, 4.0 for security). With Homebrew on Mac OS X this is easy enough. The main ZeroMQ formula installs 4.0. To get version 3.2 pull in the homebrew-versions using: brew tap homebrew/versions and install version 3.2: brew install zeromq32 ffi-rzmq-core-1.0.6/spec/0000755000004100000410000000000013312112075015154 5ustar www-datawww-dataffi-rzmq-core-1.0.6/spec/structures_spec.rb0000644000004100000410000000175513312112075020746 0ustar www-datawww-datarequire 'spec_helper' describe LibZMQ do if LibZMQ.version_number >= 040101 it "the msg_t struct wrapped in Message is 64 bytes" do LibZMQ::Message.size == 64 end elsif LibZMQ.version_number < 040100 it "the msg_t struct wrapped in Message is 32 bytes" do LibZMQ::Message.size == 32 end elsif LibZMQ.version_number == 040100 it "the msg_t struct wrapped in Message is 48 bytes" do LibZMQ::Message.size == 32 end end it "wraps poll_item_t in a PollItem" do poll_item = LibZMQ::PollItem.new expect(poll_item.socket).to_not be_nil expect(poll_item.fd).to_not be_nil expect(poll_item.readable?).to_not be_nil expect(poll_item.writable?).to_not be_nil expect(poll_item.inspect).to_not be_nil end it "wraps zmq_event_t in an EventData" do event_data = LibZMQ::EventData.new expect(event_data.event).to_not be_nil expect(event_data.value).to_not be_nil expect(event_data.inspect).to_not be_nil end end ffi-rzmq-core-1.0.6/spec/libzmq4_spec.rb0000644000004100000410000000117113312112075020075 0ustar www-datawww-datarequire 'spec_helper' if LibZMQ.version4? describe LibZMQ do it "exposes new context management methods" do [:zmq_ctx_term, :zmq_ctx_shutdown].each do |method| expect(LibZMQ).to respond_to(method) end end it "exposes new sending methods" do expect(LibZMQ).to respond_to(:zmq_send_const) end it "exposes the binary encoding / decoding API" do [:zmq_z85_encode, :zmq_z85_decode].each do |method| expect(LibZMQ).to respond_to(method) end end it "exposes CURVE security methods" do expect(LibZMQ).to respond_to(:zmq_curve_keypair) end end end ffi-rzmq-core-1.0.6/spec/libc_spec.rb0000644000004100000410000000051513312112075017425 0ustar www-datawww-datarequire 'spec_helper' describe LibC do it "exposes the malloc function" do expect(LibC).to respond_to(:malloc) end it "exposes the free function" do expect(LibC).to respond_to(:free) expect(LibC::Free).to_not be_nil end it "exposes the memcpy function" do expect(LibC).to respond_to(:memcpy) end end ffi-rzmq-core-1.0.6/spec/spec_helper.rb0000644000004100000410000000041613312112075017773 0ustar www-datawww-datarequire File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib ffi-rzmq-core])) require 'rspec' Dir[File.join(File.dirname(__FILE__), "support", "*.rb")].each do |support| require support end RSpec.configure do |config| config.include VersionChecking end ffi-rzmq-core-1.0.6/spec/support/0000755000004100000410000000000013312112075016670 5ustar www-datawww-dataffi-rzmq-core-1.0.6/spec/support/version_checking.rb0000644000004100000410000000025313312112075022535 0ustar www-datawww-data# Helper methods for figuring out which version of Ruby / ZMQ we are # testing and working with. module VersionChecking def jruby? RUBY_PLATFORM =~ /java/ end end ffi-rzmq-core-1.0.6/spec/libzmq_spec.rb0000644000004100000410000000244413312112075020015 0ustar www-datawww-datarequire 'spec_helper' describe LibZMQ do it "exposes basic query methods" do [:zmq_version, :zmq_errno, :zmq_strerror].each do |method| expect(LibZMQ).to respond_to(method) end end it "exposes initialization and context methods" do [:zmq_init, :zmq_term, :zmq_ctx_new, :zmq_ctx_destroy, :zmq_ctx_set, :zmq_ctx_get].each do |method| expect(LibZMQ).to respond_to(method) end end it "exposes the message API" do [:zmq_msg_init, :zmq_msg_init_size, :zmq_msg_init_data, :zmq_msg_close, :zmq_msg_data, :zmq_msg_size, :zmq_msg_copy, :zmq_msg_move, :zmq_msg_send, :zmq_msg_recv, :zmq_msg_more, :zmq_msg_get, :zmq_msg_set].each do |method| expect(LibZMQ).to respond_to(method) end end it "exposes the socket API" do [:zmq_socket, :zmq_setsockopt, :zmq_getsockopt, :zmq_bind, :zmq_connect, :zmq_close, :zmq_unbind, :zmq_disconnect, :zmq_recvmsg, :zmq_recv, :zmq_sendmsg, :zmq_send].each do |method| expect(LibZMQ).to respond_to(method) end end it "exposes the Device API" do expect(LibZMQ).to respond_to(:zmq_proxy) end it "exposes the Poll API" do expect(LibZMQ).to respond_to(:zmq_poll) end it "exposes the Monitoring API" do expect(LibZMQ).to respond_to(:zmq_socket_monitor) end end ffi-rzmq-core-1.0.6/.gitignore0000644000004100000410000000006113312112075016207 0ustar www-datawww-data*.gem .bundle Gemfile.lock pkg/* *.rbc .redcar/ ffi-rzmq-core-1.0.6/LICENSE0000644000004100000410000000206613312112075015233 0ustar www-datawww-dataThe MIT License (MIT) Copyright (c) 2013 Chuck Remes Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ffi-rzmq-core-1.0.6/Rakefile0000644000004100000410000000047513312112075015675 0ustar www-datawww-datarequire 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new task :default => :spec task :console do require 'irb' require 'irb/completion' require 'ffi-rzmq-core' ARGV.clear IRB.start end task :pryconsole do require 'pry' require 'ffi-rzmq-core' ARGV.clear Pry.start endffi-rzmq-core-1.0.6/lib/0000755000004100000410000000000013312112075014770 5ustar www-datawww-dataffi-rzmq-core-1.0.6/lib/ffi-rzmq-core.rb0000644000004100000410000000035413312112075020000 0ustar www-datawww-datarequire 'ffi' require 'ffi-rzmq-core/libc' require 'ffi-rzmq-core/libzmq' require 'ffi-rzmq-core/utilities' require 'ffi-rzmq-core/structures' require 'ffi-rzmq-core/constants' if LibZMQ.version4? require 'ffi-rzmq-core/libzmq4' end ffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/0000755000004100000410000000000013312112075017451 5ustar www-datawww-dataffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/version.rb0000644000004100000410000000004613312112075021463 0ustar www-datawww-datamodule LibZMQ VERSION = "1.0.6" end ffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/libc.rb0000644000004100000410000000110413312112075020703 0ustar www-datawww-data module LibC extend FFI::Library # figures out the correct libc for each platform including Windows library = ffi_lib(FFI::Library::LIBC).first # Size_t not working properly on Windows find_type(:size_t) rescue typedef(:ulong, :size_t) # memory allocators attach_function :malloc, [:size_t], :pointer attach_function :free, [:pointer], :void # get a pointer to the free function; used for ZMQ::Message deallocation Free = library.find_symbol('free') # memory movers attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer end # module LibC ffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/structures.rb0000644000004100000410000001025713312112075022226 0ustar www-datawww-datamodule LibZMQ def self.version_number 10000 * version[:major] + 100 * version[:minor] + version[:patch] end def self.version_string "%d.%d.%d" % version.values_at(:major, :minor, :patch) end raise "zmq library version not supported: #{version_string}" if version_number < 030200 # here are the typedefs for zmsg_msg_t for all known releases of libzmq # grep 'typedef struct zmq_msg_t' */include/zmq.h # zeromq-3.2.2/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-3.2.3/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-3.2.4/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-3.2.5/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.0/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.1/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.2/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.3/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.4/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.5/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.6/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.0.7/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; # zeromq-4.1.0/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [48];} zmq_msg_t; # zeromq-4.1.1/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [64];} zmq_msg_t; # zeromq-4.1.2/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [64];} zmq_msg_t; # zeromq-4.1.3/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [64];} zmq_msg_t; # zeromq-4.1.4/include/zmq.h:typedef struct zmq_msg_t {unsigned char _ [64];} zmq_msg_t; # libzmq/include/zmq.h: typedef union zmq_msg_t {unsigned char _ [64]; void *p; } zmq_msg_t; def self.size_of_zmq_msg_t if version_number < 040100 32 elsif version_number < 040101 48 else 64 end end # Declare Message with correct size and alignment class Message < FFI::Union layout :'_', [:uint8, LibZMQ.size_of_zmq_msg_t], :p, :pointer end # Create the basic mapping for the poll_item_t structure so we can # access those fields via Ruby. # module PollItemLayout def self.included(base) fd_type = if FFI::Platform::IS_WINDOWS && FFI::Platform::ADDRESS_SIZE == 64 # On Windows, zmq.h defines fd as a SOCKET, which is 64 bits on x64. :uint64 else :int end base.class_eval do layout :socket, :pointer, :fd, fd_type, :events, :short, :revents, :short end end end # PollItem class includes the PollItemLayout module so that we can use the # basic FFI accessors to get at the structure's fields. We also want to provide # some higher-level Ruby accessors for convenience. # class PollItem < FFI::Struct include PollItemLayout def socket self[:socket] end def fd self[:fd] end def readable? (self[:revents] & ZMQ::POLLIN) > 0 end def writable? (self[:revents] & ZMQ::POLLOUT) > 0 end def inspect "socket [#{socket}], fd [#{fd}], events [#{self[:events]}], revents [#{self[:revents]}]" end end # /* Socket event data */ # typedef struct { # uint16_t event; // id of the event as bitfield # int32_t value ; // value is either error code, fd or reconnect interval # } zmq_event_t; module EventDataLayout def self.included(base) base.class_eval do layout :event, :uint16, :value, :int32 end end end # module EventDataLayout # Provide a few convenience methods for accessing the event structure. # class EventData < FFI::Struct include EventDataLayout def event self[:event] end def value self[:value] end def inspect "event [#{event}], value [#{value}]" end end # class EventData end ffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/libzmq4.rb0000644000004100000410000000125513312112075021363 0ustar www-datawww-data# Wraps the new API methods available in ZeroMQ 4 # module LibZMQ attach_function :zmq_ctx_term, [:pointer], :void, :blocking => true attach_function :zmq_ctx_shutdown, [:pointer], :void, :blocking => true attach_function :zmq_send_const, [:pointer, :pointer, :size_t], :int, :blocking => true attach_function :zmq_z85_encode, [:pointer, :pointer, :size_t], :string, :blocking => true attach_function :zmq_z85_decode, [:pointer, :string], :pointer, :blocking => true # Requires ZMQ compiled with libsodium # Will return -1 with errno set to ENOSUP otherwise attach_function :zmq_curve_keypair, [:pointer, :pointer], :int, :blocking => true end ffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/utilities.rb0000644000004100000410000000205013312112075022006 0ustar www-datawww-data module LibZMQ # Returns a hash of the form {:major => X, :minor => Y, :patch => Z} to represent the # version of libzmq. # # Class method. # # Invoke as: ZMQ::LibZMQ.version # def self.version unless @version major = FFI::MemoryPointer.new :int minor = FFI::MemoryPointer.new :int patch = FFI::MemoryPointer.new :int LibZMQ.zmq_version major, minor, patch @version = {:major => major.read_int, :minor => minor.read_int, :patch => patch.read_int} end @version end def self.version3? version[:major] == 3 && version[:minor] >= 2 end def self.version4? version[:major] == 4 end # Sanity check; print an error and exit if we are trying to load an unsupported # version of libzmq. # hash = LibZMQ.version major, minor = hash[:major], hash[:minor] if major < 3 || (major == 3 && minor < 2) version = "#{hash[:major]}.#{hash[:minor]}.#{hash[:patch]}" raise LoadError, "The libzmq version #{version} is incompatible with this version of ffi-rzmq-core." end endffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/constants.rb0000644000004100000410000001624313312112075022020 0ustar www-datawww-data module ZMQ # Set up all of the constants that are *common* to all API # versions # Socket types PAIR = 0 PUB = 1 SUB = 2 REQ = 3 REP = 4 XREQ = 5 XREP = 6 PULL = 7 PUSH = 8 XPUB = 9 XSUB = 10 DEALER = XREQ ROUTER = XREP STREAM = 11 SocketTypeNameMap = { PAIR => "PAIR", PUB => "PUB", SUB => "SUB", REQ => "REQ", REP => "REP", PULL => "PULL", PUSH => "PUSH", XREQ => "XREQ", XREP => "XREP", ROUTER => "ROUTER", DEALER => "DEALER", XPUB => "XPUB", XSUB => "XSUB", STREAM => "STREAM", } # Socket options AFFINITY = 4 IDENTITY = 5 SUBSCRIBE = 6 UNSUBSCRIBE = 7 RATE = 8 RECOVERY_IVL = 9 SNDBUF = 11 RCVBUF = 12 RCVMORE = 13 FD = 14 EVENTS = 15 TYPE = 16 LINGER = 17 RECONNECT_IVL = 18 BACKLOG = 19 RECONNECT_IVL_MAX = 21 MAXMSGSIZE = 22 SNDHWM = 23 RCVHWM = 24 MULTICAST_HOPS = 25 RCVTIMEO = 27 SNDTIMEO = 28 IPV4ONLY = 31 LAST_ENDPOINT = 32 ROUTER_MANDATORY = 33 TCP_KEEPALIVE = 34 TCP_KEEPALIVE_CNT = 35 TCP_KEEPALIVE_IDLE = 36 TCP_KEEPALIVE_INTVL = 37 TCP_ACCEPT_FILTER = 38 DELAY_ATTACH_ON_CONNECT = 39 XPUB_VERBOSE = 40 ROUTER_RAW = 41 IPV6 = 42 MECHANISM = 43 PLAIN_SERVER = 44 PLAIN_USERNAME = 45 PLAIN_PASSWORD = 46 CURVE_SERVER = 47 CURVE_PUBLICKEY = 48 CURVE_SECRETKEY = 49 CURVE_SERVERKEY = 50 PROBE_ROUTER = 51 REQ_CORRELATE = 52 REQ_RELAXED = 53 CONFLATE = 54 ZAP_DOMAIN = 55 ROUTER_HANDOVER = 56 TOS = 57 CONNECT_RID = 61 GSSAPI_SERVER = 62 GSSAPI_PRINCIPAL = 63 GSSAPI_SERVICE_PRINCIPAL = 64 GSSAPI_PLAINTEXT = 65 HANDSHAKE_IVL = 66 SOCKS_PROXY = 68 XPUB_NODROP = 69 BLOCKY = 70 XPUB_MANUAL = 71 XPUB_WELCOME_MSG = 72 STREAM_NOTIFY = 73 INVERT_MATCHING = 74 HEARTBEAT_IVL = 75 HEARTBEAT_TTL = 76 HEARTBEAT_TIMEOUT = 77 XPUB_VERBOSE_UNSUBSCRIBE = 78 IMMEDIATE = DELAY_ATTACH_ON_CONNECT FAIL_UNROUTABLE = ROUTER_MANDATORY ROUTER_BEHAVIOR = ROUTER_MANDATORY # Socket Security Types NULL = 0 PLAIN = 1 CURVE = 2 # Send/recv options DONTWAIT = 1 SNDMORE = 2 SNDLABEL = 4 NOBLOCK = DONTWAIT # Message options MORE = 1 # Context options IO_THREADS = 1 MAX_SOCKETS = 2 IO_THREADS_DFLT = 1 MAX_SOCKETS_DFLT = 1023 # I/O multiplexing POLL = 1 POLLIN = 1 POLLOUT = 2 POLLERR = 4 # Socket errors EAGAIN = Errno::EAGAIN::Errno EINVAL = Errno::EINVAL::Errno ENOMEM = Errno::ENOMEM::Errno ENODEV = Errno::ENODEV::Errno EFAULT = Errno::EFAULT::Errno EINTR = Errno::EINTR::Errno EMFILE = Errno::EMFILE::Errno # ZMQ errors HAUSNUMERO = 156384712 EFSM = (HAUSNUMERO + 51) ENOCOMPATPROTO = (HAUSNUMERO + 52) ETERM = (HAUSNUMERO + 53) EMTHREAD = (HAUSNUMERO + 54) # Rescue unknown constants and use the ZeroMQ defined values # Usually only happens on Windows though some don't resolve on # OSX too (ENOTSUP) ENOTSUP = Errno::ENOTSUP::Errno rescue (HAUSNUMERO + 1) EPROTONOSUPPORT = Errno::EPROTONOSUPPORT::Errno rescue (HAUSNUMERO + 2) ENOBUFS = Errno::ENOBUFS::Errno rescue (HAUSNUMERO + 3) ENETDOWN = Errno::ENETDOWN::Errno rescue (HAUSNUMERO + 4) EADDRINUSE = Errno::EADDRINUSE::Errno rescue (HAUSNUMERO + 5) EADDRNOTAVAIL = Errno::EADDRNOTAVAIL::Errno rescue (HAUSNUMERO + 6) ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue (HAUSNUMERO + 7) EINPROGRESS = Errno::EINPROGRESS::Errno rescue (HAUSNUMERO + 8) ENOTSOCK = Errno::ENOTSOCK::Errno rescue (HAUSNUMERO + 9) EMSGSIZE = Errno::EMSGSIZE::Errno rescue (HAUSNUMERO + 10) EAFNOSUPPORT = Errno::EAFNOSUPPORT::Errno rescue (HAUSNUMERO + 11) ENETUNREACH = Errno::ENETUNREACH::Errno rescue (HAUSNUMERO + 12) ECONNABORTED = Errno::ECONNABORTED::Errno rescue (HAUSNUMERO + 13) ECONNRESET = Errno::ECONNRESET::Errno rescue (HAUSNUMERO + 14) ENOTCONN = Errno::ENOTCONN::Errno rescue (HAUSNUMERO + 15) ETIMEDOUT = Errno::ETIMEDOUT::Errno rescue (HAUSNUMERO + 16) EHOSTUNREACH = Errno::EHOSTUNREACH::Errno rescue (HAUSNUMERO + 17) ENETRESET = Errno::ENETRESET::Errno rescue (HAUSNUMERO + 18) # Device Types STREAMER = 1 FORWARDER = 2 QUEUE = 3 # Socket events and monitoring EVENT_CONNECTED = 1 EVENT_CONNECT_DELAYED = 2 EVENT_CONNECT_RETRIED = 4 EVENT_LISTENING = 8 EVENT_BIND_FAILED = 16 EVENT_ACCEPTED = 32 EVENT_ACCEPT_FAILED = 64 EVENT_CLOSED = 128 EVENT_CLOSE_FAILED = 256 EVENT_DISCONNECTED = 512 EVENT_MONITOR_STOPPED = 1024 EVENT_ALL = (EVENT_CONNECTED | EVENT_CONNECT_DELAYED | EVENT_CONNECT_RETRIED | EVENT_LISTENING | EVENT_BIND_FAILED | EVENT_ACCEPTED | EVENT_ACCEPT_FAILED | EVENT_CLOSED | EVENT_CLOSE_FAILED | EVENT_DISCONNECTED | EVENT_MONITOR_STOPPED) # version checking # This gem supports both libzmq 3.2+ and 4.x. However, not all socket options are visible between versions. # To make support easier for consumers of this gem, we do all version checking here and only # expose the appropriate socket options. Note that *all* options are defined above even if the library # version doesn't support it. Consumers of this gem can enable support at runtime. integer_socket_options = [ EVENTS, LINGER, RCVTIMEO, SNDTIMEO, RECONNECT_IVL, FD, TYPE, BACKLOG, RECONNECT_IVL_MAX, RCVHWM, SNDHWM, RATE, RECOVERY_IVL, SNDBUF, RCVBUF, IPV4ONLY, ROUTER_BEHAVIOR, TCP_KEEPALIVE, TCP_KEEPALIVE_CNT, TCP_KEEPALIVE_IDLE, TCP_KEEPALIVE_INTVL, TCP_ACCEPT_FILTER, MULTICAST_HOPS, IMMEDIATE, ] long_long_socket_options = [ RCVMORE, AFFINITY, MAXMSGSIZE, ] string_socket_options = [ IDENTITY, SUBSCRIBE, UNSUBSCRIBE, LAST_ENDPOINT, ] if LibZMQ.version4? integer_socket_options += [ IPV6, MECHANISM, PLAIN_SERVER, CURVE_SERVER, PROBE_ROUTER, REQ_CORRELATE, REQ_RELAXED, CONFLATE, ] string_socket_options += [ ZAP_DOMAIN, PLAIN_USERNAME, PLAIN_PASSWORD, CURVE_PUBLICKEY, CURVE_SERVERKEY, CURVE_SECRETKEY, ] end IntegerSocketOptions = integer_socket_options.sort LongLongSocketOptions = long_long_socket_options.sort StringSocketOptions = string_socket_options.sort SocketOptions = (IntegerSocketOptions + LongLongSocketOptions + StringSocketOptions).sort end ffi-rzmq-core-1.0.6/lib/ffi-rzmq-core/libzmq.rb0000644000004100000410000001407613312112075021304 0ustar www-datawww-datarequire 'open3' require 'rbconfig' # Wraps the libzmq library and attaches to the functions that are # common across the 3.2.x+ and 4.x APIs. # module LibZMQ extend FFI::Library begin # bias the library discovery to a path inside the gem first, then # to the usual system paths inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext') local_path = FFI::Platform::IS_WINDOWS ? ENV['PATH'].split(';') : ENV['PATH'].split(':') env_path = [ ENV['ZMQ_LIB_PATH'] ].compact rbconfig_path = RbConfig::CONFIG["libdir"] homebrew_path = nil # RUBYOPT set by RVM breaks 'brew' so we need to unset it. rubyopt = ENV.delete('RUBYOPT') begin stdout, stderr, status = Open3.capture3("brew", "--prefix") homebrew_path = if status.success? "#{stdout.chomp}/lib" else '/usr/local/homebrew/lib' end rescue # Homebrew doesn't exist end # Restore RUBYOPT after executing 'brew' above. ENV['RUBYOPT'] = rubyopt # Search for libzmq in the following order... ZMQ_LIB_PATHS = ([inside_gem] + env_path + local_path + [rbconfig_path] + [ '/usr/local/lib', '/opt/local/lib', homebrew_path, '/usr/lib64' ]).compact.map{|path| "#{path}/libzmq.#{FFI::Platform::LIBSUFFIX}"} # Recent versions of libzmq do not put all symbols into the global namespace so # lazy linking can fail at runtime. Force all symbols to global namespace. ffi_lib_flags :now, :global ffi_lib(ZMQ_LIB_PATHS + %w{libzmq}) rescue LoadError if ZMQ_LIB_PATHS.any? {|path| File.file? File.join(path, "libzmq.#{FFI::Platform::LIBSUFFIX}")} warn "Unable to load this gem. The libzmq library exists, but cannot be loaded." warn "If this is Windows:" warn "- Check that you have MSVC runtime installed or statically linked" warn "- Check that your DLL is compiled for #{FFI::Platform::ADDRESS_SIZE} bit" else warn "Unable to load this gem. The libzmq library (or DLL) could not be found." warn "If this is a Windows platform, make sure libzmq.dll is on the PATH." warn "If the DLL was built with mingw, make sure the other two dependent DLLs," warn "libgcc_s_sjlj-1.dll and libstdc++6.dll, are also on the PATH." warn "For non-Windows platforms, make sure libzmq is located in this search path:" warn ZMQ_LIB_PATHS.inspect end raise LoadError, "The libzmq library (or DLL) could not be loaded" end # Size_t not working properly on Windows find_type(:size_t) rescue typedef(:ulong, :size_t) # Context and misc api # # The `:blocking` option is a hint to FFI that the following (and only the following) # function may block, therefore it should release the GIL before calling it. # This can aid in situations where the function call will/may block and another # thread within the lib may try to call back into the ruby runtime. Failure to # release the GIL will result in a hang; the hint is required for MRI otherwise # there are random hangs (which require kill -9 to terminate). # attach_function :zmq_version, [:pointer, :pointer, :pointer], :void, :blocking => true attach_function :zmq_errno, [], :int, :blocking => true attach_function :zmq_strerror, [:int], :pointer, :blocking => true # Context initialization and destruction attach_function :zmq_init, [:int], :pointer, :blocking => true attach_function :zmq_term, [:pointer], :int, :blocking => true attach_function :zmq_ctx_new, [], :pointer, :blocking => true attach_function :zmq_ctx_destroy, [:pointer], :int, :blocking => true attach_function :zmq_ctx_set, [:pointer, :int, :int], :int, :blocking => true attach_function :zmq_ctx_get, [:pointer, :int], :int, :blocking => true # Message API attach_function :zmq_msg_init, [:pointer], :int, :blocking => true attach_function :zmq_msg_init_size, [:pointer, :size_t], :int, :blocking => true attach_function :zmq_msg_init_data, [:pointer, :pointer, :size_t, :pointer, :pointer], :int, :blocking => true attach_function :zmq_msg_close, [:pointer], :int, :blocking => true attach_function :zmq_msg_data, [:pointer], :pointer, :blocking => true attach_function :zmq_msg_size, [:pointer], :size_t, :blocking => true attach_function :zmq_msg_copy, [:pointer, :pointer], :int, :blocking => true attach_function :zmq_msg_move, [:pointer, :pointer], :int, :blocking => true attach_function :zmq_msg_send, [:pointer, :pointer, :int], :int, :blocking => true attach_function :zmq_msg_recv, [:pointer, :pointer, :int], :int, :blocking => true attach_function :zmq_msg_more, [:pointer], :int, :blocking => true attach_function :zmq_msg_get, [:pointer, :int], :int, :blocking => true attach_function :zmq_msg_set, [:pointer, :int, :int], :int, :blocking => true # Socket API attach_function :zmq_socket, [:pointer, :int], :pointer, :blocking => true attach_function :zmq_setsockopt, [:pointer, :int, :pointer, :int], :int, :blocking => true attach_function :zmq_getsockopt, [:pointer, :int, :pointer, :pointer], :int, :blocking => true attach_function :zmq_bind, [:pointer, :string], :int, :blocking => true attach_function :zmq_connect, [:pointer, :string], :int, :blocking => true attach_function :zmq_close, [:pointer], :int, :blocking => true attach_function :zmq_unbind, [:pointer, :string], :int, :blocking => true attach_function :zmq_disconnect, [:pointer, :string], :int, :blocking => true attach_function :zmq_recvmsg, [:pointer, :pointer, :int], :int, :blocking => true attach_function :zmq_recv, [:pointer, :pointer, :size_t, :int], :int, :blocking => true attach_function :zmq_sendmsg, [:pointer, :pointer, :int], :int, :blocking => true attach_function :zmq_send, [:pointer, :pointer, :size_t, :int], :int, :blocking => true # Device API attach_function :zmq_proxy, [:pointer, :pointer, :pointer], :int, :blocking => true # Poll API attach_function :zmq_poll, [:pointer, :int, :long], :int, :blocking => true # Monitoring API attach_function :zmq_socket_monitor, [:pointer, :pointer, :int], :int, :blocking => true end ffi-rzmq-core-1.0.6/Gemfile0000644000004100000410000000004713312112075015516 0ustar www-datawww-datasource "https://rubygems.org" gemspec