From 753f3e64cddfe1ae8e4efd57074b2c72144844bb Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 29 Feb 2012 22:02:49 +0000 Subject: [PATCH] Changes for ZeroMQ libzmq 3.1.0 release Changes made to the hxzmq wrapper classes, mostly in the ZMQ.hx class, for the changes made in the ZeroMQ 3.1.0 release. The changes are not backwardly compatible with the previous 2.1.x libzmq version; this new version of hxzmq will only work alongside a 3.1.x version libzmq native library. See http://www.zeromq.org/docs:3-1-upgrade for details of the changes made in the libzmq library, and therefore in hxzmq. --- README.md | 4 +- build.xml | 6 +- haxelib.xml | 2 +- ndll/Linux/hxzmq.ndll | Bin 46880 -> 46876 bytes ndll/Mac64/hxzmq.ndll | Bin 45048 -> 54548 bytes ndll/Windows/hxzmq.ndll | Bin 95744 -> 95744 bytes org/zeromq/ZLoop.hx | 2 +- org/zeromq/ZMQ.hx | 146 +++++++++++++----------- org/zeromq/ZMQDevice.hx | 47 +------- org/zeromq/ZMQSocket.hx | 6 +- org/zeromq/ZThread.hx | 6 +- org/zeromq/test/TestAll.hx | 3 +- org/zeromq/test/TestMultiPartMessage.hx | 7 +- org/zeromq/test/TestPoller.hx | 93 ++++++++++++++- org/zeromq/test/TestReqRep.hx | 2 +- org/zeromq/test/TestSocket.hx | 32 +++--- org/zeromq/test/TestXPubXSub.hx | 84 ++++++++++++++ org/zeromq/test/TestZThread.hx | 12 +- src/Device.cpp | 7 +- src/Poller.cpp | 14 ++- src/Socket.cpp | 19 ++- src/ZMQ.cpp | 143 ++++++++++++++++++----- test/buildMac64.hxml | 14 +-- 23 files changed, 453 insertions(+), 196 deletions(-) create mode 100644 org/zeromq/test/TestXPubXSub.hx diff --git a/README.md b/README.md index e971816..0d7fd8f 100644 --- a/README.md +++ b/README.md @@ -129,9 +129,9 @@ Key files and folders contained in this repository: ## Versions -The current release of hxzmq is 1.4.0, compatable with libzmq-2.1.4 or any later 2.1.x version (latest tested in 2.1.8). The latest released hxzmq package shall also be available in the [haxelib repository] [4], accessable via the [haxelib tool] [5] which is included in the standard haXe distribution. +The current release of hxzmq on the master branch is compatable with libzmq-3.1.0 or any later 3.1.x version (latest tested in 3.1.0). The latest released hxzmq package shall also be available in the [haxelib repository] [4], accessable via the [haxelib tool] [5] which is included in the standard haXe distribution. -This version of hxzmq has also been tested against [php-zmq v0.7.0] [13] +A version of hxzmq compatable with the libzmq 2.1.x version is archived on the 2.1.x branch of the hxzmq git repository. ## Building and Installation diff --git a/build.xml b/build.xml index 7525b2f..590a76e 100644 --- a/build.xml +++ b/build.xml @@ -9,7 +9,7 @@ - + @@ -17,10 +17,10 @@ - + - + diff --git a/haxelib.xml b/haxelib.xml index 7c912e4..dfbddbf 100644 --- a/haxelib.xml +++ b/haxelib.xml @@ -5,5 +5,5 @@ Haxe language binding for the ZeroMQ socket library - Re-built ndll against v2.1.8 of the libzmq library + Added experimental support for ZMQ v3.x.x diff --git a/ndll/Linux/hxzmq.ndll b/ndll/Linux/hxzmq.ndll index 04a29a24abc1d3727d41162f2ef7c7c23cfafcc2..94563040ebffd5cb4d381a3bf5e6b25cc67f6a70 100755 GIT binary patch literal 46876 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�@sM>O3$Q2bR_-{mkcVstdy~68 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 h$Wd{rFOl9=q6+&4<#+AGeb-K+>V(zX9u$TX_Hg diff --git a/ndll/Mac64/hxzmq.ndll b/ndll/Mac64/hxzmq.ndll index 9f37e9ede1ad711208fac595a776a688e20631f4..5c935751c083a2de87e70411b5f654e1510a0200 100755 GIT binary patch literal 54548 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 Nr%j(RJ@QcSe*>Qcwcr2% diff --git a/ndll/Windows/hxzmq.ndll b/ndll/Windows/hxzmq.ndll index 1f63813825c543eef92d74515fcd8ca3e8b367b6..dd2ea97d54d897426cc284d0c7808d32cdc138fa 100644 GIT binary patch delta 19730 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 E2aoQW^#A|> delta 19551 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 WRb{Uyx$p?LscR0dTST7f{eJ*LJ4K`b diff --git a/org/zeromq/ZLoop.hx b/org/zeromq/ZLoop.hx index 66696a0..b7c874d 100644 --- a/org/zeromq/ZLoop.hx +++ b/org/zeromq/ZLoop.hx @@ -208,7 +208,7 @@ class ZLoop rebuildPollset(); } try { - rc = poller.poll(ticklessTimer() * 1000); + rc = poller.poll(ticklessTimer() * ZMQ.ZMQ_POLL_MSEC()); } catch (e:ZMQException) { #if !php if (ZMQ.isInterrupted()) { diff --git a/org/zeromq/ZMQ.hx b/org/zeromq/ZMQ.hx index eaeb5c6..b0f870e 100644 --- a/org/zeromq/ZMQ.hx +++ b/org/zeromq/ZMQ.hx @@ -33,10 +33,12 @@ enum SocketType { ZMQ_SUB; ZMQ_REQ; ZMQ_REP; - ZMQ_ROUTER; // Replaces XREQ in 2.1.4 - ZMQ_DEALER; // Replaces XREP in 2.1.4 + ZMQ_ROUTER; + ZMQ_DEALER; ZMQ_PULL; ZMQ_PUSH; + ZMQ_XPUB; + ZMQ_XSUB; } /** @@ -75,16 +77,20 @@ enum SendReceiveFlagType { * See: http://api.zeromq.org/master:zmq-setsockopt */ enum SocketOptionsType { - ZMQ_HWM; // Set high water mark - ZMQ_SWAP; // Set disk offload size + + ZMQ_SNDHWM; // Set send buffer high water mark + ZMQ_RCVHWM; // Set receive buffer high water mark + ZMQ_MAXMSGSIZE; // Limits the size of the inbound message + ZMQ_MULTICAST_HOPS; // Sets the time-to-live field in every multicast packet sent from this socket + ZMQ_RCVTIMEO; // Sets the timeout for receive operation on the socket (msecs) + ZMQ_SNDTIMEO; // Sets the timeout for send operation on the socket (msecs) + ZMQ_HWM; // Set high water mark (eumulated in ZMQ v3+) ZMQ_AFFINITY; // Set I/O thread affinity ZMQ_IDENTITY; // Set socket identity ZMQ_SUBSCRIBE; // Establish message filter ZMQ_UNSUBSCRIBE; // Remove message filter ZMQ_RATE; // Set multicast data rate ZMQ_RECOVERY_IVL; // Set multicast recovery interval - ZMQ_RECOVERY_IVL_MSEC; // Set multicast recovery interval in milliseconds - ZMQ_MCAST_LOOP; // Control multicast loop-back ZMQ_SNDBUF; // Set kernel transmit buffer size ZMQ_RCVBUF; // Set kernel receive buffer size ZMQ_LINGER; // Set linger period for socket shutdown @@ -95,12 +101,7 @@ enum SocketOptionsType { ZMQ_FD; // Retrieve file descriptor associated with the socket ZMQ_EVENTS; // Retrieve socket event state (bitmask use ZMQ_POLLIN and ZMQ_POLLOUT) ZMQ_TYPE; // Retrieves type of socket -} -enum DeviceType { - ZMQ_QUEUE; - ZMQ_FORWARDER; - ZMQ_STREAMER; } /** @@ -116,29 +117,32 @@ class ZMQ { // Values for flags in ZMQSocket's send and recv functions. public static var bytesSocketOptionTypes:Array = [ - ZMQ_IDENTITY, ZMQ_SUBSCRIBE, - ZMQ_UNSUBSCRIBE + ZMQ_UNSUBSCRIBE, + ZMQ_IDENTITY ]; public static var int64SocketOptionTypes:Array = [ + ZMQ_MAXMSGSIZE, + ZMQ_AFFINITY + ]; + + public static var intSocketOptionTypes:Array = + [ + ZMQ_SNDHWM, + ZMQ_RCVHWM, + ZMQ_MULTICAST_HOPS, + ZMQ_RCVTIMEO, + ZMQ_SNDTIMEO, ZMQ_HWM, - ZMQ_SWAP, - ZMQ_AFFINITY, ZMQ_RATE, ZMQ_RECOVERY_IVL, - ZMQ_RECOVERY_IVL_MSEC, - ZMQ_MCAST_LOOP, ZMQ_SNDBUF, ZMQ_RCVBUF, - ZMQ_RCVMORE - ]; - - public static var intSocketOptionTypes:Array = - [ - ZMQ_LINGER, + ZMQ_RCVMORE, ZMQ_RECONNECT_IVL, ZMQ_RECONNECT_IVL_MAX, + ZMQ_LINGER, ZMQ_BACKLOG, ZMQ_FD, // Only int on POSIX systems ZMQ_EVENTS, @@ -159,6 +163,12 @@ class ZMQ { return _hx_zmq_ZMQ_POLLERR(); } + // Multiplying factor for Poller.poll() method calls to handle + // units change in ZMQ3 from microsecs to millisecs + public static inline function ZMQ_POLL_MSEC():Int { + return _hx_zmq_ZMQ_POLL_MSEC(); + } + /** * Gets complete 0MQ library version * @return 0MQ library version in form MMmmpp (MM=major, mm=minor, pp=patch) @@ -248,6 +258,10 @@ class ZMQ { _hx_zmq_ZMQ_PULL(); case ZMQ_PUSH: _hx_zmq_ZMQ_PUSH(); + case ZMQ_XPUB: + _hx_zmq_ZMQ_XPUB(); + case ZMQ_XSUB: + _hx_zmq_ZMQ_XSUB(); default: null; } @@ -262,12 +276,20 @@ class ZMQ { public static function socketOptionTypeNo(option:SocketOptionsType):Int { return { switch(option) { + case ZMQ_SNDHWM: + _hx_zmq_ZMQ_SNDHWM(); + case ZMQ_RCVHWM: + _hx_zmq_ZMQ_RCVHWM(); + case ZMQ_MAXMSGSIZE: + _hx_zmq_ZMQ_MAXMSGSIZE(); + case ZMQ_MULTICAST_HOPS: + _hx_zmq_ZMQ_MULTICAST_HOPS(); + case ZMQ_SNDTIMEO: + _hx_zmq_ZMQ_SNDTIMEO(); + case ZMQ_RCVTIMEO: + _hx_zmq_ZMQ_RCVTIMEO(); case ZMQ_LINGER: _hx_zmq_ZMQ_LINGER(); - case ZMQ_HWM: - _hx_zmq_ZMQ_HWM(); - case ZMQ_SWAP: - _hx_zmq_ZMQ_SWAP(); case ZMQ_AFFINITY: _hx_zmq_ZMQ_AFFINITY(); case ZMQ_IDENTITY: @@ -280,10 +302,6 @@ class ZMQ { _hx_zmq_ZMQ_RATE(); case ZMQ_RECOVERY_IVL: _hx_zmq_ZMQ_RECOVERY_IVL(); - case ZMQ_RECOVERY_IVL_MSEC: - _hx_zmq_ZMQ_RECOVERY_IVL_MSEC(); - case ZMQ_MCAST_LOOP: - _hx_zmq_ZMQ_MCAST_LOOP(); case ZMQ_SNDBUF: _hx_zmq_ZMQ_SNDBUF(); case ZMQ_RCVBUF: @@ -419,27 +437,6 @@ class ZMQ { } } - /** - * Converts a ZMQ DeviceType enum value into underlying device number. - * Used for call to zmq_device - * @param device - * @return - */ - public static function deviceTypeToDevice(device: DeviceType):Int { - return { - switch (device) { - case ZMQ_QUEUE: - _hx_zmq_ZMQ_QUEUE(); - case ZMQ_FORWARDER: - _hx_zmq_ZMQ_FORWARDER(); - case ZMQ_STREAMER: - _hx_zmq_ZMQ_STREAMER(); - default: - 0; - } - } - } - /** * Sets up interrupt signal handling. * Use isInterrupted() to subsequently test for interruption @@ -472,6 +469,10 @@ class ZMQ { private static var _hx_zmq_catch_signals = Lib.load("hxzmq", "hx_zmq_catch_signals", 0); private static var _hx_zmq_interrupted = Lib.load("hxzmq", "hx_zmq_interrupted", 0); + private static var _hx_zmq_ZMQ_POLL_MSEC = Lib.load("hxzmq", "hx_zmq_ZMQ_POLL_MSEC", 0); + #end + + #if (neko || cpp) private static var _hx_zmq_ZMQ_PUB = Lib.load("hxzmq", "hx_zmq_ZMQ_PUB", 0); private static var _hx_zmq_ZMQ_SUB = Lib.load("hxzmq", "hx_zmq_ZMQ_SUB", 0); private static var _hx_zmq_ZMQ_PAIR = Lib.load("hxzmq", "hx_zmq_ZMQ_PAIR", 0); @@ -481,20 +482,29 @@ class ZMQ { private static var _hx_zmq_ZMQ_ROUTER = Lib.load("hxzmq", "hx_zmq_ZMQ_ROUTER", 0); private static var _hx_zmq_ZMQ_PULL = Lib.load("hxzmq", "hx_zmq_ZMQ_PULL", 0); private static var _hx_zmq_ZMQ_PUSH = Lib.load("hxzmq", "hx_zmq_ZMQ_PUSH", 0); + private static var _hx_zmq_ZMQ_XREQ = Lib.load("hxzmq", "hx_zmq_ZMQ_XREQ", 0); + private static var _hx_zmq_ZMQ_XREP = Lib.load("hxzmq", "hx_zmq_ZMQ_XREP", 0); + private static var _hx_zmq_ZMQ_XPUB = Lib.load("hxzmq", "hx_zmq_ZMQ_XPUB", 0); + private static var _hx_zmq_ZMQ_XSUB = Lib.load("hxzmq", "hx_zmq_ZMQ_XSUB", 0); + + private static var _hx_zmq_ZMQ_SNDHWM = Lib.load("hxzmq", "hx_zmq_ZMQ_SNDHWM", 0); + private static var _hx_zmq_ZMQ_RCVHWM = Lib.load("hxzmq", "hx_zmq_ZMQ_RCVHWM", 0); + private static var _hx_zmq_ZMQ_MAXMSGSIZE = Lib.load("hxzmq", "hx_zmq_ZMQ_MAXMSGSIZE", 0); + private static var _hx_zmq_ZMQ_MULTICAST_HOPS = Lib.load("hxzmq", "hx_zmq_ZMQ_MULTICAST_HOPS", 0); + private static var _hx_zmq_ZMQ_SNDTIMEO = Lib.load("hxzmq", "hx_zmq_ZMQ_SNDTIMEO", 0); + private static var _hx_zmq_ZMQ_RCVTIMEO = Lib.load("hxzmq", "hx_zmq_ZMQ_RCVTIMEO", 0); + #end + +#if (neko || cpp) private static var _hx_zmq_ZMQ_LINGER = Lib.load("hxzmq", "hx_zmq_ZMQ_LINGER", 0); - private static var _hx_zmq_ZMQ_HWM = Lib.load("hxzmq", "hx_zmq_ZMQ_HWM", 0); private static var _hx_zmq_ZMQ_RCVMORE = Lib.load("hxzmq", "hx_zmq_ZMQ_RCVMORE", 0); private static var _hx_zmq_ZMQ_SUBSCRIBE = Lib.load("hxzmq", "hx_zmq_ZMQ_SUBSCRIBE", 0); private static var _hx_zmq_ZMQ_UNSUBSCRIBE = Lib.load("hxzmq", "hx_zmq_ZMQ_UNSUBSCRIBE", 0); - private static var _hx_zmq_ZMQ_SWAP = Lib.load("hxzmq", "hx_zmq_ZMQ_SWAP", 0); private static var _hx_zmq_ZMQ_AFFINITY = Lib.load("hxzmq", "hx_zmq_ZMQ_AFFINITY", 0); private static var _hx_zmq_ZMQ_IDENTITY = Lib.load("hxzmq", "hx_zmq_ZMQ_IDENTITY", 0); - private static var _hx_zmq_ZMQ_RATE = Lib.load("hxzmq", "hx_zmq_ZMQ_RATE", 0); private static var _hx_zmq_ZMQ_RECOVERY_IVL = Lib.load("hxzmq", "hx_zmq_ZMQ_RECOVERY_IVL", 0); - private static var _hx_zmq_ZMQ_RECOVERY_IVL_MSEC = Lib.load("hxzmq", "hx_zmq_ZMQ_RECOVERY_IVL_MSEC", 0); - private static var _hx_zmq_ZMQ_MCAST_LOOP = Lib.load("hxzmq", "hx_zmq_ZMQ_MCAST_LOOP", 0); private static var _hx_zmq_ZMQ_SNDBUF = Lib.load("hxzmq", "hx_zmq_ZMQ_SNDBUF", 0); private static var _hx_zmq_ZMQ_RCVBUF = Lib.load("hxzmq", "hx_zmq_ZMQ_RCVBUF", 0); private static var _hx_zmq_ZMQ_RECONNECT_IVL = Lib.load("hxzmq", "hx_zmq_ZMQ_RECONNECT_IVL", 0); @@ -503,7 +513,7 @@ class ZMQ { private static var _hx_zmq_ZMQ_FD = Lib.load("hxzmq", "hx_zmq_ZMQ_FD", 0); private static var _hx_zmq_ZMQ_EVENTS = Lib.load("hxzmq", "hx_zmq_ZMQ_EVENTS", 0); private static var _hx_zmq_ZMQ_TYPE = Lib.load("hxzmq", "hx_zmq_ZMQ_TYPE", 0); - + private static var _hx_zmq_ZMQ_POLLIN = Lib.load("hxzmq", "hx_zmq_ZMQ_POLLIN", 0); private static var _hx_zmq_ZMQ_POLLOUT = Lib.load("hxzmq", "hx_zmq_ZMQ_POLLOUT", 0); private static var _hx_zmq_ZMQ_POLLERR = Lib.load("hxzmq", "hx_zmq_ZMQ_POLLERR", 0); @@ -527,12 +537,10 @@ class ZMQ { private static var _hx_zmq_EFSM = Lib.load("hxzmq", "hx_zmq_EFSM", 0); private static var _hx_zmq_ENOCOMPATPROTO = Lib.load("hxzmq", "hx_zmq_ENOCOMPATPROTO", 0); private static var _hx_zmq_ETERM = Lib.load("hxzmq", "hx_zmq_ETERM", 0); - - private static var _hx_zmq_ZMQ_QUEUE = Lib.load("hxzmq", "hx_zmq_ZMQ_QUEUE", 0); - private static var _hx_zmq_ZMQ_FORWARDER = Lib.load("hxzmq", "hx_zmq_ZMQ_FORWARDER", 0); - private static var _hx_zmq_ZMQ_STREAMER = Lib.load("hxzmq", "hx_zmq_ZMQ_STREAMER", 0); - - #elseif php +#end + + +#if php // Load functions and constants from php-zmq @@ -583,6 +591,14 @@ class ZMQ { private static function _hx_zmq_ZMQ_PULL():Int {return untyped __php__('ZMQ::SOCKET_PULL');} private static function _hx_zmq_ZMQ_PUSH():Int {return untyped __php__('ZMQ::SOCKET_PUSH');} + // TODO: Replace stubs with ZMQ3 PHP bindings + private static var _hx_zmq_ZMQ_SNDHWM():Int {return untyped __php__('ZMQ::SOCKET_PUB');}; + private static var _hx_zmq_ZMQ_RCVHWM():Int {return untyped __php__('ZMQ::SOCKET_PUB');}; + private static var _hx_zmq_ZMQ_MAXMSGSIZE():Int {return untyped __php__('ZMQ::SOCKET_PUB');}; + private static var _hx_zmq_ZMQ_MULTICAST_HOPS():Int {return untyped __php__('ZMQ::SOCKET_PUB');}; + private static var _hx_zmq_ZMQ_SNDTIMEO():Int {return untyped __php__('ZMQ::SOCKET_PUB');}; + private static var _hx_zmq_ZMQ_RCVTIMEO():Int {return untyped __php__('ZMQ::SOCKET_PUB');}; + private static function _hx_zmq_ZMQ_LINGER():Int {return untyped __php__('ZMQ::SOCKOPT_LINGER');} private static function _hx_zmq_ZMQ_HWM():Int {return untyped __php__('ZMQ::SOCKOPT_HWM');} @@ -655,6 +671,6 @@ class ZMQ { private static inline function _hx_zmq_ZMQ_FORWARDER():Int { return untyped __php__('ZMQ::DEVICE_FORWARDER'); } private static inline function _hx_zmq_ZMQ_STREAMER():Int { return untyped __php__('ZMQ::DEVICE_STREAMER'); } - #end +#end } diff --git a/org/zeromq/ZMQDevice.hx b/org/zeromq/ZMQDevice.hx index d7e3352..3c3d09d 100644 --- a/org/zeromq/ZMQDevice.hx +++ b/org/zeromq/ZMQDevice.hx @@ -25,50 +25,15 @@ import org.zeromq.ZMQ; /** * Wraps ZMQ zmq_device method call. - * Creates in-built ZMQ devices that run in the current thread of execution + * Creates in-built ZMQ devices that run in the current thread of execution. + * + * DEPRECATED in 3.1.x branch */ + class ZMQDevice { - - /** - * Constructor. - * Creates a new ZMQ device and immediately starts its in-built loop. - * Will continue unless process is interrupted, when it returns a ETERM ZMQ_Exception. - * @param type A valid DeviceType - * @param frontend Front end socket, bound or connected to by clients - * @param backend Back end socket, bound or connected to workers - */ - public function new(type:DeviceType, frontend:ZMQSocket, backend:ZMQSocket) - { - if (frontend == null || frontend.closed) { - throw new ZMQException(EINVAL); - } - if (backend == null || backend.closed) { - throw new ZMQException(EINVAL); - } - if (type == null) { - throw new ZMQException(EINVAL); - } -#if (neko || cpp) - try { - // This will continue to execute until current thread or process is terminated - var rc = _hx_zmq_device(ZMQ.deviceTypeToDevice(type), frontend._socketHandle, backend._socketHandle); - } catch (e:Int) { - throw new ZMQException(ZMQ.errNoToErrorType(e)); - } catch (e:Dynamic) { - Lib.rethrow(e); - } -#elseif php - var _typenum = ZMQ.deviceTypeToDevice(type); - var _frontend_handle = frontend._socketHandle; - var _backend_handle = backend._socketHandle; - var r = untyped __php__('new ZMQDevice($_typenum, $_frontend_handle, $_backend_handle)'); -#end - + public function new() { + throw new ZMQException(ENOTSUP); } -#if (neko || cpp) - private static var _hx_zmq_device = Lib.load("hxzmq", "hx_zmq_device", 3); - -#end } \ No newline at end of file diff --git a/org/zeromq/ZMQSocket.hx b/org/zeromq/ZMQSocket.hx index 58b798d..b39a543 100644 --- a/org/zeromq/ZMQSocket.hx +++ b/org/zeromq/ZMQSocket.hx @@ -443,11 +443,9 @@ class ZMQSocket public function hasReceiveMore():Bool { if (_socketHandle == null || closed) return false; var r = getsockopt(ZMQ_RCVMORE); -#if (neko || cpp) - return (r != null && r.lo == 1); -#elseif php + // In ZMQ 3+, RCVMORE is now an int value, not int64 return (r != null && r == 1); -#end + } /** diff --git a/org/zeromq/ZThread.hx b/org/zeromq/ZThread.hx index ba31368..d6f0c69 100644 --- a/org/zeromq/ZThread.hx +++ b/org/zeromq/ZThread.hx @@ -74,7 +74,8 @@ untyped __php__(' var pipe = ctx.createSocket(ZMQ_PAIR); if (pipe == null) return null; - pipe.setsockopt(ZMQ_HWM, { hi:0, lo:1 } ); + pipe.setsockopt(ZMQ_SNDHWM, 1); + pipe.setsockopt(ZMQ_RCVHWM, 1); var uuid = generateuuid(8); var pipeUUID = bytesToHex(uuid); // Creates a 16char uuidstring, based on a 8-byte uuid @@ -83,7 +84,8 @@ untyped __php__(' var forkCtx = ZContext.shadow(ctx); forkCtx.main = false; var forkPipe = forkCtx.createSocket(ZMQ_PAIR); - forkPipe.setsockopt(ZMQ_HWM, { hi:0, lo:1 } ); + forkPipe.setsockopt(ZMQ_SNDHWM, 1); + forkPipe.setsockopt(ZMQ_RCVHWM, 1); #if (neko || cpp) pipe.bind("inproc://zctx-pipe-" + pipeUUID); diff --git a/org/zeromq/test/TestAll.hx b/org/zeromq/test/TestAll.hx index 3dd8c8d..e93fc82 100644 --- a/org/zeromq/test/TestAll.hx +++ b/org/zeromq/test/TestAll.hx @@ -35,12 +35,13 @@ class TestAll runner.add(new TestVersion()); runner.add(new TestContext()); runner.add(new TestError()); + runner.add(new TestXPubXSub()); runner.add(new TestSocket()); runner.add(new TestPubSub()); runner.add(new TestMultiPartMessage()); runner.add(new TestReqRep()); runner.add(new TestPoller()); - // + // org.zeromq.remoting package tests runner.add(new TestZMQRemoting()); diff --git a/org/zeromq/test/TestMultiPartMessage.hx b/org/zeromq/test/TestMultiPartMessage.hx index fa63b4f..6a04c05 100644 --- a/org/zeromq/test/TestMultiPartMessage.hx +++ b/org/zeromq/test/TestMultiPartMessage.hx @@ -46,13 +46,14 @@ class TestMultiPartMessage extends BaseTest pair.s1.sendMsg(msg3); // last part of multipart message // Receive multipart message - var i:Int = 1; + var i:Int = 0; do { + i++; var b:Bytes = pair.s2.recvMsg(); // Blocking call assertEquals(Std.string(i), b.toString().charAt(7)); - i++; + } while (pair.s2.hasReceiveMore()); - assertTrue(i == 4); // 3 parts received + assertEquals(3, i); // 3 parts received } catch (e:ZMQException) { trace("ZMQException #:" + e.toString()); diff --git a/org/zeromq/test/TestPoller.hx b/org/zeromq/test/TestPoller.hx index 5d79fe8..c8b3c2c 100644 --- a/org/zeromq/test/TestPoller.hx +++ b/org/zeromq/test/TestPoller.hx @@ -22,6 +22,9 @@ package org.zeromq.test; import haxe.io.Bytes; import neko.Sys; import haxe.Stack; +import org.zeromq.ZContext; +import org.zeromq.ZMQContext; +import org.zeromq.ZMsg; import org.zeromq.ZMQ; import org.zeromq.ZMQPoller; @@ -93,6 +96,84 @@ class TestPoller extends BaseTest } } + public function testPollingReqRepZMQ3() { + var pollinout:Int = ZMQ.ZMQ_POLLIN() | ZMQ.ZMQ_POLLOUT(); + var ctx:ZContext; + var req:ZMQSocket, rep:ZMQSocket; + var poller:ZMQPoller; + var numSocks; + + try { + // ** Test tcp req/rep poller revents + var randomPort:Int = Math.round(Math.random() * 18000) + 2000; + ctx = new ZContext(); + req = ctx.createSocket(ZMQ_REQ); + rep = ctx.createSocket(ZMQ_REP); + req.bind("tcp://*:"+randomPort); + rep.connect("tcp://localhost:"+randomPort); + Sys.sleep(0.1); // Allow sockets time to connect + poller = new ZMQPoller(); + poller.registerSocket(req, pollinout); + poller.registerSocket(rep, pollinout); + numSocks = poller.poll(10 * ZMQ.ZMQ_POLL_MSEC()); + assertEquals(1, numSocks); + ctx.destroy(); + + } catch (e:ZMQException) { + trace("ZMQException #:" + e.errNo + ", str:" + e.str()); + trace (Stack.toString(Stack.exceptionStack())); + assertTrue(false); + } + + try { + // ** Test ipc req/rep poller revents + ctx = new ZContext(); + req = ctx.createSocket(ZMQ_REQ); + rep = ctx.createSocket(ZMQ_REP); + req.bind("ipc:///tmp/poller"); + rep.connect("ipc:///tmp/poller"); + Sys.sleep(0.1); // Allow sockets time to connect + poller = new ZMQPoller(); + poller.registerSocket(req, pollinout); + poller.registerSocket(rep, pollinout); + numSocks = poller.poll(10 * ZMQ.ZMQ_POLL_MSEC()); + assertEquals(1, numSocks); + ctx.destroy(); + } catch (e:ZMQException) { + if (e.err != ErrorType.EPROTONOSUPPORT) { + // Only assert test has failed if the exception is not "Protocol Not Supported". + // On Windows, ipc is not supported by ZeroMQ. + trace("ZMQException #:" + e.errNo + ", str:" + e.str()); + trace (Stack.toString(Stack.exceptionStack())); + assertTrue(false); + } + } + + try { + // ** Test inproc req/rep poller revents + ctx = new ZContext(); + req = ctx.createSocket(ZMQ_REQ); + rep = ctx.createSocket(ZMQ_REP); + req.bind("inproc://test.poller"); + rep.connect("inproc://test.poller"); + Sys.sleep(0.1); // Allow sockets time to connect + poller = new ZMQPoller(); + poller.registerSocket(req, pollinout); + poller.registerSocket(rep, pollinout); + numSocks = poller.poll(10 * ZMQ.ZMQ_POLL_MSEC()); + assertEquals(1, numSocks); + ctx.destroy(); + + assertTrue(true); + + } catch (e:ZMQException) { + trace("ZMQException #:" + e.errNo + ", str:" + e.str()); + trace (Stack.toString(Stack.exceptionStack())); + assertTrue(false); + } + + } + public function testPollingReqRep() { var pair:SocketPair = createBoundPair(ZMQ_REP, ZMQ_REQ); @@ -104,15 +185,21 @@ class TestPoller extends BaseTest poller.registerSocket(pair.s1, pollinout); poller.registerSocket(pair.s2, pollinout); - var numSocks = poller.poll(); - assertEquals(1, numSocks); // Only one revent bitmask with an event - assertEquals(2, poller.getSize()); + var numSocks = poller.poll(10 * ZMQ.ZMQ_POLL_MSEC()); + //trace ("rep:poller.pollin(1):" + poller.pollin(1) + ", poller.pollout(1):" + poller.pollout(1)); + //trace ("req:poller.pollin(2):" + poller.pollin(2) + ", poller.pollout(2):" + poller.pollout(2)); + + assertEquals(1, numSocks); // Only one revent bitmask with an event + // Had to change this from 1 when upgrading to ZMQ 3.1 + assertEquals(2, poller.getSize()); assertTrue(poller.noevents(1)); // REP socket s1 no events assertTrue(poller.pollout(2)); // REQ socket s2 should be ready for writing // Make sure s2 REQ socket immediately goes into state 0 after send pair.s2.sendMsg(Bytes.ofString("msg1")); numSocks = poller.poll(); + //trace ("rep:poller.pollin(1):" + poller.pollin(1) + ", poller.pollout(1):" + poller.pollout(1)); + //trace ("req:poller.pollin(2):" + poller.pollin(2) + ", poller.pollout(2):" + poller.pollout(2)); assertTrue(poller.noevents(2)); // Make sure that s1 goes into POLLIN state after a sleep() diff --git a/org/zeromq/test/TestReqRep.hx b/org/zeromq/test/TestReqRep.hx index 6386d30..fc84b1b 100644 --- a/org/zeromq/test/TestReqRep.hx +++ b/org/zeromq/test/TestReqRep.hx @@ -37,7 +37,7 @@ import org.zeromq.test.BaseTest; class TestReqRep extends BaseTest { - public function TODOtestBasicReqRep() { + public function testBasicReqRep() { var pair:SocketPair; try { pair = createBoundPair(ZMQ_REQ, ZMQ_REP); diff --git a/org/zeromq/test/TestSocket.hx b/org/zeromq/test/TestSocket.hx index 0ee14e4..f42d1f5 100644 --- a/org/zeromq/test/TestSocket.hx +++ b/org/zeromq/test/TestSocket.hx @@ -31,7 +31,7 @@ import org.zeromq.test.BaseTest; /** * Haxe test class focused on the ZMQSocket haxe binding class * - * Assumes a baseline ZMQ version of 2.1.4 (ie. some tests may not work if run against any earlier versions of the libzmq library) + * Assumes a baseline ZMQ version of 3.x.x (ie. some tests may not execute or compile if run against any earlier versions of the libzmq library) */ class TestSocket extends BaseTest { @@ -95,6 +95,14 @@ class TestSocket extends BaseTest var r:Int = pair.s1.getsockopt(ZMQ_EVENTS); assertEquals(ZMQ.ZMQ_POLLOUT(), r); assertRaisesZMQException(function() { pair.s1.setsockopt(ZMQ_EVENTS, 2 ^ 7 - 1); }, EINVAL); + + pair.s1.setsockopt(ZMQ_LINGER, 0); + r = pair.s1.getsockopt(ZMQ_SNDHWM); + assertTrue(r == 0); // Test default HWM is 0 for a new socket + pair.s2.setsockopt(ZMQ_SNDHWM, 10 ); + var r:Int = pair.s2.getsockopt(ZMQ_SNDHWM); + assertEquals(10, r); + #end assertEquals(ZMQ.socketTypeNo(ZMQ_PUB), pair.s1.getsockopt(ZMQ_TYPE)); assertEquals(ZMQ.socketTypeNo(ZMQ_SUB), pair.s2.getsockopt(ZMQ_TYPE)); @@ -118,24 +126,14 @@ class TestSocket extends BaseTest try { pair = createBoundPair(ZMQ_PUB, ZMQ_SUB); -#if (neko || cpp) - pair.s1.setsockopt(ZMQ_LINGER, 0); - r = pair.s1.getsockopt(ZMQ_HWM); - assertTrue(r.lo == 0); // Test default HWM is 0 for a new socket - assertTrue(r.hi == 0); - pair.s2.setsockopt(ZMQ_HWM, { hi:128, lo:128 } ); // (128 * 2^32)+128 - var r:ZMQInt64Type = pair.s2.getsockopt(ZMQ_HWM); - assertTrue(r.lo == 128); - assertTrue(r.hi == 128); +#if (neko || cpp) + pair.s1.setsockopt(ZMQ_MAXMSGSIZE, { hi:10, lo:100 } ); + r = pair.s1.getsockopt(ZMQ_MAXMSGSIZE); + assertEquals(10, r.hi); + assertEquals(100, r.lo); + r = pair.s1.getsockopt(ZMQ_AFFINITY); assertEquals(0, r.lo); - r = pair.s1.getsockopt(ZMQ_SWAP); - assertTrue(r.lo == 0); - assertTrue(r.hi == 0); - pair.s1.setsockopt(ZMQ_SWAP, { hi:1, lo:255 } ); // (1 * 2^32) + 255 bytes - r = pair.s1.getsockopt(ZMQ_SWAP); - assertTrue(r.lo == 255); - assertTrue(r.hi == 1); #elseif php pair.s1.setsockopt(ZMQ_LINGER, 0); r = pair.s1.getsockopt(ZMQ_HWM); diff --git a/org/zeromq/test/TestXPubXSub.hx b/org/zeromq/test/TestXPubXSub.hx new file mode 100644 index 0000000..fdc3be6 --- /dev/null +++ b/org/zeromq/test/TestXPubXSub.hx @@ -0,0 +1,84 @@ +/** + * (c) 2011 Richard J Smith + * + * This file is part of hxzmq + * + * hxzmq is free software; you can redistribute it and/or modify it under + * the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * hxzmq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Lesser GNU General Public License for more details. + * + * You should have received a copy of the Lesser GNU General Public License + * along with this program. If not, see . + */ + +package org.zeromq.test; + +import haxe.io.Bytes; +import haxe.io.BytesBuffer; +import haxe.Stack; +import neko.Sys; +import org.zeromq.ZMsg; + +import org.zeromq.ZMQ; +import org.zeromq.ZMQSocket; +import org.zeromq.ZMQException; +import org.zeromq.test.BaseTest; + +/** + * This class sets up tests for the XPUB and XSUB socket types + * introduced in 0MQ3 + */ +class TestXPubXSub extends BaseTest +{ + + public function testSubscriptionForwarding() { + + try { + var pair:SocketPair = createBoundPair(ZMQ_XPUB, ZMQ_XSUB); + _sockets.add(pair.s1); + _sockets.add(pair.s2); + + pair.s2.setsockopt(ZMQ_RCVTIMEO, 100); // Timeout blocking recv on XSUB socket at 100msecs. + // Used for filtered-out test below + + // Subscribe to prefix "A" + var subscription:BytesBuffer = new BytesBuffer(); + subscription.addByte(1); // Subscribe + subscription.add(Bytes.ofString("A")); + pair.s2.sendMsg(subscription.getBytes()); + + Sys.sleep(0.1); // Give time for XPUB socket to receive subscription + var sent = new ZMsg(); + sent.addString("A"); + sent.addString("I want to receive this"); + sent.send(pair.s1); + + var msg:ZMsg = ZMsg.recvMsg(pair.s2); // this is a blocking call + assertTrue(msg.first().streq("A")); + assertTrue(msg.last().streq("I want to receive this")); + + // Send a message to XSUB socket that should not meet its subscription + sent = new ZMsg(); + sent.addString("B"); + sent.addString("I don't want to receive this"); + sent.send(pair.s1); + + // This call should time out + msg = null; + msg = ZMsg.recvMsg(pair.s2); + assertTrue(msg == null); + + } catch (e:ZMQException) { + trace("ZMQException #:" + e.errNo + ", str:" + e.str()); + trace (Stack.toString(Stack.exceptionStack())); + assertTrue(false); + } + } + +} \ No newline at end of file diff --git a/org/zeromq/test/TestZThread.hx b/org/zeromq/test/TestZThread.hx index 8c8350e..835a201 100644 --- a/org/zeromq/test/TestZThread.hx +++ b/org/zeromq/test/TestZThread.hx @@ -45,12 +45,12 @@ class TestZThread extends BaseTest private function attachedThreadTest(ctx:ZContext, pipe:ZMQSocket, args:Dynamic) { // Create a new socket to check it'll be automatically deleted var newSocket = ctx.createSocket(ZMQ_PUSH); - trace ("newSocket created"); + //trace ("newSocket created"); // Wait for our parent to ping us and pong back var ping = pipe.recvMsg(); - trace ("ping received:" + ping.toString()); + //trace ("ping received:" + ping.toString()); pipe.sendMsg(Bytes.ofString("pong")); - trace ("pipe sent pong"); + //trace ("pipe sent pong"); } public function testZThreadDetach() { @@ -68,14 +68,14 @@ class TestZThread extends BaseTest // Create a new attached thread and let it run var pipe:ZMQSocket = ZThread.attach(ctx, attachedThreadTest, "foo"); - trace ("Now send ping"); + //trace ("Now send ping"); pipe.sendMsg(Bytes.ofString("ping")); var pong = pipe.recvMsg(); - trace ("pong received:" + pong.toString()); + //trace ("pong received:" + pong.toString()); assertEquals(pong.toString(), "pong"); // Everything should be cleanly closed now - trace ("exiting"); + //trace ("exiting"); try { ctx.destroy(); } catch (e:ZMQException) { diff --git a/src/Device.cpp b/src/Device.cpp index 4e9e894..5a52ce6 100644 --- a/src/Device.cpp +++ b/src/Device.cpp @@ -34,9 +34,14 @@ value hx_zmq_device (value type_, value frontend_, value backend_) { val_check_kind(frontend_, k_zmq_socket_handle); val_check_kind(backend_, k_zmq_socket_handle); +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) + int rc = -1; + int err = ENOTSUP; +#else int rc = zmq_device(val_int(type_), val_data(frontend_), val_data(backend_)); int err = zmq_errno(); - +#endif + if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); diff --git a/src/Poller.cpp b/src/Poller.cpp index 26e7250..af817c3 100644 --- a/src/Poller.cpp +++ b/src/Poller.cpp @@ -98,4 +98,16 @@ value hx_zmq_poll (value sockets_, value events_, value timeout_) { } -DEFINE_PRIM (hx_zmq_poll, 3); \ No newline at end of file +DEFINE_PRIM (hx_zmq_poll, 3); + +value hx_zmq_ZMQ_POLL_MSEC() +{ +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) + + return alloc_int(1); +#else + return alloc_int(1000); +#endif +} + +DEFINE_PRIM( hx_zmq_ZMQ_POLL_MSEC,0); \ No newline at end of file diff --git a/src/Socket.cpp b/src/Socket.cpp index bd656e5..c9b3771 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -368,13 +368,17 @@ value hx_zmq_send(value socket_handle_, value msg_data, value flags) { gc_enter_blocking(); // Send +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) + rc = zmq_sendmsg (val_data(socket_handle_), &message, val_int(flags)); +#else rc = zmq_send (val_data(socket_handle_), &message, val_int(flags)); +#endif err = zmq_errno(); gc_exit_blocking(); // If NOBLOCK, but cant send message now, close message first before quitting - if (rc != 0 && err == EAGAIN) { + if (rc == -1 && err == EAGAIN) { rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { @@ -384,7 +388,7 @@ value hx_zmq_send(value socket_handle_, value msg_data, value flags) { return alloc_null(); } - if (rc != 0) { + if (rc == -1) { val_throw(alloc_int(err)); rc = zmq_msg_close (&message); err = zmq_errno(); @@ -427,13 +431,16 @@ value hx_zmq_rcv(value socket_handle_, value flags) { } gc_enter_blocking(); - + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) + rc = zmq_recvmsg (val_data(socket_handle_), &message, val_int(flags)); +#else rc = zmq_recv (val_data(socket_handle_), &message, val_int(flags)); - +#endif gc_exit_blocking(); err = zmq_errno(); - if (rc != 0 && err == EAGAIN) { + if (rc == -1 && err == EAGAIN) { rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { @@ -443,7 +450,7 @@ value hx_zmq_rcv(value socket_handle_, value flags) { return alloc_null(); } - if (rc != 0) { + if (rc == -1) { rc = zmq_msg_close (&message); int err1 = zmq_errno(); if (rc != 0) { diff --git a/src/ZMQ.cpp b/src/ZMQ.cpp index 03cd78a..4e1c523 100644 --- a/src/ZMQ.cpp +++ b/src/ZMQ.cpp @@ -121,67 +121,88 @@ value hx_zmq_ZMQ_PUSH() } DEFINE_PRIM( hx_zmq_ZMQ_PUSH,0); -/* ******* Socket Option Types **********/ -value hx_zmq_ZMQ_LINGER() +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) + +/* New Socket Types introduced in 0MQ 3 */ + +value hx_zmq_ZMQ_XREQ() { - return alloc_int(ZMQ_LINGER); + return alloc_int(ZMQ_XREQ); } -DEFINE_PRIM( hx_zmq_ZMQ_LINGER,0); +DEFINE_PRIM( hx_zmq_ZMQ_XREQ,0); -value hx_zmq_ZMQ_HWM() +value hx_zmq_ZMQ_XREP() { - return alloc_int(ZMQ_HWM); + return alloc_int(ZMQ_XREP); } +DEFINE_PRIM( hx_zmq_ZMQ_XREP,0); -DEFINE_PRIM( hx_zmq_ZMQ_HWM,0); +value hx_zmq_ZMQ_XPUB() +{ + return alloc_int(ZMQ_XPUB); +} +DEFINE_PRIM( hx_zmq_ZMQ_XPUB,0); -value hx_zmq_ZMQ_RCVMORE() +value hx_zmq_ZMQ_XSUB() { - return alloc_int(ZMQ_RCVMORE); + return alloc_int(ZMQ_XSUB); } -DEFINE_PRIM( hx_zmq_ZMQ_RCVMORE,0); +DEFINE_PRIM( hx_zmq_ZMQ_XSUB,0); -value hx_zmq_ZMQ_SUBSCRIBE() +#endif +/* ******* Socket Option Types **********/ + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) + +value hx_zmq_ZMQ_MAXMSGSIZE() { - return alloc_int(ZMQ_SUBSCRIBE); + return alloc_int(ZMQ_MAXMSGSIZE); } -DEFINE_PRIM( hx_zmq_ZMQ_SUBSCRIBE,0); +DEFINE_PRIM( hx_zmq_ZMQ_MAXMSGSIZE,0); + +value hx_zmq_ZMQ_SNDHWM() +{ + return alloc_int(ZMQ_SNDHWM); +} +DEFINE_PRIM( hx_zmq_ZMQ_SNDHWM,0); -value hx_zmq_ZMQ_UNSUBSCRIBE() +value hx_zmq_ZMQ_RCVHWM() { - return alloc_int(ZMQ_UNSUBSCRIBE); + return alloc_int(ZMQ_RCVHWM); } -DEFINE_PRIM( hx_zmq_ZMQ_UNSUBSCRIBE,0); +DEFINE_PRIM( hx_zmq_ZMQ_RCVHWM,0); -value hx_zmq_ZMQ_IDENTITY() +value hx_zmq_ZMQ_MULTICAST_HOPS() { - return alloc_int(ZMQ_IDENTITY); + return alloc_int(ZMQ_MULTICAST_HOPS); } -DEFINE_PRIM( hx_zmq_ZMQ_IDENTITY,0); +DEFINE_PRIM( hx_zmq_ZMQ_MULTICAST_HOPS,0); -value hx_zmq_ZMQ_SWAP() +value hx_zmq_ZMQ_RCVTIMEO() { - return alloc_int(ZMQ_SWAP); + return alloc_int(ZMQ_RCVTIMEO); } -DEFINE_PRIM( hx_zmq_ZMQ_SWAP,0); +DEFINE_PRIM( hx_zmq_ZMQ_RCVTIMEO,0); -value hx_zmq_ZMQ_AFFINITY() +value hx_zmq_ZMQ_SNDTIMEO() { - return alloc_int(ZMQ_AFFINITY); + return alloc_int(ZMQ_SNDTIMEO); } -DEFINE_PRIM( hx_zmq_ZMQ_AFFINITY,0); +DEFINE_PRIM( hx_zmq_ZMQ_SNDTIMEO,0); -value hx_zmq_ZMQ_RATE() +#else + +value hx_zmq_ZMQ_HWM() { - return alloc_int(ZMQ_RATE); + return alloc_int(ZMQ_HWM); } -DEFINE_PRIM( hx_zmq_ZMQ_RATE,0); +DEFINE_PRIM( hx_zmq_ZMQ_HWM,0); -value hx_zmq_ZMQ_RECOVERY_IVL() +value hx_zmq_ZMQ_SWAP() { - return alloc_int(ZMQ_RECOVERY_IVL); + return alloc_int(ZMQ_SWAP); } -DEFINE_PRIM( hx_zmq_ZMQ_RECOVERY_IVL,0); +DEFINE_PRIM( hx_zmq_ZMQ_SWAP,0); value hx_zmq_ZMQ_RECOVERY_IVL_MSEC() { @@ -195,6 +216,61 @@ value hx_zmq_ZMQ_MCAST_LOOP() } DEFINE_PRIM( hx_zmq_ZMQ_MCAST_LOOP,0); +#endif + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(2,1,0) + +value hx_zmq_ZMQ_IDENTITY() +{ + return alloc_int(ZMQ_IDENTITY); +} +DEFINE_PRIM( hx_zmq_ZMQ_IDENTITY,0); + +value hx_zmq_ZMQ_RECOVERY_IVL() +{ + return alloc_int(ZMQ_RECOVERY_IVL); +} +DEFINE_PRIM( hx_zmq_ZMQ_RECOVERY_IVL,0); + +value hx_zmq_ZMQ_LINGER() +{ + return alloc_int(ZMQ_LINGER); +} +DEFINE_PRIM( hx_zmq_ZMQ_LINGER,0); + + +#endif + +value hx_zmq_ZMQ_RCVMORE() +{ + return alloc_int(ZMQ_RCVMORE); +} +DEFINE_PRIM( hx_zmq_ZMQ_RCVMORE,0); + +value hx_zmq_ZMQ_SUBSCRIBE() +{ + return alloc_int(ZMQ_SUBSCRIBE); +} +DEFINE_PRIM( hx_zmq_ZMQ_SUBSCRIBE,0); + +value hx_zmq_ZMQ_UNSUBSCRIBE() +{ + return alloc_int(ZMQ_UNSUBSCRIBE); +} +DEFINE_PRIM( hx_zmq_ZMQ_UNSUBSCRIBE,0); + +value hx_zmq_ZMQ_AFFINITY() +{ + return alloc_int(ZMQ_AFFINITY); +} +DEFINE_PRIM( hx_zmq_ZMQ_AFFINITY,0); + +value hx_zmq_ZMQ_RATE() +{ + return alloc_int(ZMQ_RATE); +} +DEFINE_PRIM( hx_zmq_ZMQ_RATE,0); + value hx_zmq_ZMQ_SNDBUF() { return alloc_int(ZMQ_SNDBUF); @@ -243,6 +319,7 @@ value hx_zmq_ZMQ_TYPE() } DEFINE_PRIM( hx_zmq_ZMQ_TYPE,0); +/* ******* POLLER OPTIONS **********/ value hx_zmq_ZMQ_POLLIN() { return alloc_int(ZMQ_POLLIN); @@ -278,6 +355,8 @@ value hx_zmq_SNDMORE() } DEFINE_PRIM( hx_zmq_SNDMORE,0); + + /* ******* Exception Codes *************/ value hx_zmq_EINVAL() { @@ -382,6 +461,7 @@ value hx_zmq_ETERM() DEFINE_PRIM( hx_zmq_ETERM,0); /* ******* ZMQ Devices *************/ +#if ZMQ_VERSION < ZMQ_MAKE_VERSION(3,0,0) value hx_zmq_ZMQ_QUEUE() { return alloc_int(ZMQ_QUEUE); @@ -398,3 +478,4 @@ value hx_zmq_ZMQ_STREAMER() } DEFINE_PRIM( hx_zmq_ZMQ_STREAMER, 0); +#endif diff --git a/test/buildMac64.hxml b/test/buildMac64.hxml index e710c28..1f3913f 100644 --- a/test/buildMac64.hxml +++ b/test/buildMac64.hxml @@ -16,11 +16,11 @@ -debug -lib hxzmq -main org.zeromq.test.TestAll ---next +#--next # Build PHP unit test target for Mac64 --cp .. --php out-php/Mac64 --debug ---remap neko:php --lib hxzmq --main org.zeromq.test.TestAll +#-cp .. +#-php out-php/Mac64 +#-debug +#--remap neko:php +#-lib hxzmq +#-main org.zeromq.test.TestAll