Compare commits

...

132 Commits

Author SHA1 Message Date
Pieter Hintjens
f45dd95ed8 Updated NEWS for release 3.2.4 2013-09-20 11:56:58 +02:00
Pieter Hintjens
a7f2ad0b24 Merge pull request #108 from hintjens/master
Updated NEWS
2013-09-16 22:39:18 -07:00
Pieter Hintjens
b36545fe70 Updated NEWS 2013-09-17 07:33:50 +02:00
Pieter Hintjens
687ea29280 Merge pull request #107 from jpoliv/master
Make ./configure --with-system-pgm detect the OpenPGM 5.2 system library.
2013-09-16 22:32:43 -07:00
Jose Pedro Oliveira
2255369a69 Make ./configure --with-system-pgm detect the OpenPGM 5.2 system library.
Note that OpenPGM installs a versioned pkgconfig file (openpgm-5.2.pc,
openpgm-5.1.pc).
2013-09-17 01:15:09 +01:00
Pieter Hintjens
c832e3d1df Merge pull request #105 from hintjens/master
Revert "fixed compilation - added detection for _WIN32_WINNT"
2013-08-23 23:09:59 -07:00
Pieter Hintjens
7f44310670 Revert "fixed compilation - added detection for _WIN32_WINNT"
This reverts commit d1ea5e525e7f8ba886eb4bc72155e6d68dafc269.
2013-08-24 08:08:04 +02:00
Pieter Hintjens
ba597c6e47 Merge pull request #104 from snikulov/cmake_fixes_msvc2012
fixed compilation - added detection for _WIN32_WINNT
2013-08-23 10:25:46 -07:00
Sergei Nikulov
d1ea5e525e fixed compilation - added detection for _WIN32_WINNT 2013-08-22 00:59:15 +04:00
Pieter Hintjens
d246aaceee Merge pull request #102 from hintjens/master
Build failed on some boxes due to missing EOL at EOF
2013-07-30 00:25:02 -07:00
Pieter Hintjens
143ae519b4 Fixed missing whitespace at end of file 2013-07-30 09:24:22 +02:00
Pieter Hintjens
2aca7b233b Merge pull request #99 from leewoosung/hotfixes/patched
Backport for LIBZMQ-541 fix
2013-07-15 00:52:12 -07:00
Pieter Hintjens
00c0d5835f Merge pull request #98 from steve-o/master
Migrate to using MSVC toolkit support independent of compiler versioning.
2013-07-13 15:24:12 -07:00
Steven McCoy
60b64748e5 Use MSVC2012's msbuild to drive everything using toolkit support for actually compilations. 2013-07-13 17:13:34 -04:00
Pieter Hintjens
aeb87cf2cc Merge pull request #97 from steve-o/master
Add MSVC 2013 support; Fix CMake regressions upstream
2013-07-13 14:08:11 -07:00
Steven McCoy
703c1a6e04 Merge remote-tracking branch 'upstream/master' 2013-07-13 12:26:11 -04:00
Steven McCoy
7604dd2d47 Add MSVC 2013 preview support; Fix upstream CMake changes wrt. PDB and lib locations. 2013-07-13 12:24:52 -04:00
Pieter Hintjens
a941934e34 Merge pull request #96 from pijyoi/master
simple Makefile for mingw32
2013-07-11 14:35:23 -07:00
KIU Shueng Chuan
51066c9767 simple Makefile for mingw32 2013-07-11 21:49:45 +08:00
Pieter Hintjens
bd77676d99 Merge pull request #93 from cjuniet/master
[LIBZMQ-543] Fix compilation errors with Clang
2013-07-03 15:42:47 -07:00
Christophe Juniet
20cce750fa Fix a few invalid forward declarations
A few forward declarations use mismatched struct and class types. Clang
won't compile this with -Werror.
2013-07-03 22:22:23 +02:00
WooSung
1b5b18cba9 LIBZMQ-541 fix 2013-06-27 23:20:14 +09:00
Ian Barber
8b6dcc8420 Merge pull request #91 from hintjens/master
test_connect_delay was failing, so I backported the code from libzmq master.
2013-05-21 13:31:51 -07:00
Pieter Hintjens
3d353f8306 Backported test_connect_delay.cpp from libzmq 2013-05-21 10:25:02 +02:00
Pieter Hintjens
ad14c562d7 Merge pull request #90 from hintjens/master
Fixed name of Travis file
2013-05-21 00:33:18 -07:00
Pieter Hintjens
37a0ec5936 Fixed name of Travis file 2013-05-21 09:32:39 +02:00
Pieter Hintjens
e9755d2a39 Merge pull request #89 from hintjens/master
Adding support for Travis CI
2013-05-21 00:25:16 -07:00
Pieter Hintjens
96fbeea5f6 Added support for Travis CI 2013-05-21 09:22:13 +02:00
Pieter Hintjens
0836de2f2e Merge pull request #88 from hintjens/master
Backported two fixes
2013-05-17 23:17:34 -07:00
Pieter Hintjens
26b182fe76 Backported #84 and #532 2013-05-18 07:17:00 +01:00
KIU Shueng Chuan
d7cad1b52a set SO_LINGER on first signaler socket to close in order to avoid
TIME_WAIT state.
2013-05-16 18:57:42 +02:00
KIU Shueng Chuan
573a1eab4b release critical section on failure to create signaler fdpair 2013-05-16 18:57:20 +02:00
Pieter Hintjens
0e5c98a9fe Merge pull request #87 from steve-o/master
Add support for vc110_xp in CMake build environment
2013-05-15 17:10:09 -07:00
Steven McCoy
2c55496d28 Update to support new toolkit functionality with CMake and VS11 for XP as a target platform. 2013-05-15 20:04:07 -04:00
Pieter Hintjens
094eceefb8 Fixed packaging for Windows, was missing errno sources 2013-05-07 14:40:15 +02:00
Martin Hurton
14bb2e46a5 Merge pull request #85 from hintjens/master
Fix for #456 was not backported to 3.2.2; will be in 3.2.4 now
2013-05-03 00:02:08 -07:00
Pieter Hintjens
11bae19cf8 #456 was not in 3.2.2 but will be in 3.2.4 2013-05-02 22:10:06 +02:00
Pieter Hintjens
a3dafd408f Code formatting 2013-05-02 22:09:30 +02:00
John Muehlhausen
58c1ba8994 patch for issue 456
Do not filter out duplicate subscriptions on the XSUB side of
XSUB/XPUB, so that ZMQ_XPUB_VERBOSE doesn't get blocked by forwarding
devices (as long as the devices all use ZMQ_XPUB_VERBOSE)
2013-05-02 22:09:21 +02:00
Pieter Hintjens
c710a39b9e Resolved merge conflict 2013-05-02 20:44:42 +02:00
Pieter Hintjens
400cbc208a Merge pull request #83 from vortechs2000/fix_323_builds
Fix 323 builds
2013-05-02 11:28:49 -07:00
Pieter Hintjens
bdd72826c9 Various cleanups to test programs
- Patch applied using git am from libzmq commit 5f009e52
 - tests/test_raw_sock.cpp doesn't exist in zeromq3-x, so that
   file was manually removed from the patch before 'git am'

Signed-off-by: AJ Lewis <aj.lewis@quantum.com>
2013-05-02 10:40:27 -05:00
AJ Lewis
1e435f59c3 Add newline to end of test_connect_delay.cpp so it compiles with older versions of GCC 2013-05-02 10:32:10 -05:00
Pieter Hintjens
0f6e357894 Bumped version number for next release 3.2.4 2013-05-02 11:23:57 +02:00
Pieter Hintjens
a85ddf3e1a Updated NEWS for 3.2.3 2013-05-02 11:12:41 +02:00
Pieter Hintjens
41b7f74d49 Merge pull request #82 from trevorbernard/master
Backport fix for LIBZMQ-526
2013-05-01 14:22:05 -07:00
Trevor Bernard
69dbe0113a Back port fix for LIBZMQ-526
Fix syntax error
2013-05-01 10:31:28 -03:00
Pieter Hintjens
894c0fb87b Merge pull request #81 from steve-o/libzmq-446
[#LIBZMQ-446] Silence error on setting PGM_TOS on REL 4.
2013-04-13 02:53:55 -07:00
Steven McCoy
521ed91289 [#LIBZMQ-446] Silence error on setting PGM_TOS due to some platforms raising an error at runtime. Noted are RHEL 4. 2013-04-12 23:44:04 -04:00
Pieter Hintjens
a436d14547 Merge pull request #79 from mika-fischer/workaround-for-496
Work around for LIBZMQ-496
2013-03-18 02:47:57 -07:00
Mika Fischer
1a17eb392e Work around for LIBZMQ-496
The problem is that other threads might still be in mailbox::send() when
it is destroyed. So as a workaround, we just acquire the mutex in the
destructor. Therefore the running send will finish before the mailbox is
destroyed.

See also the fix for LIBZMQ-281 in zeromq2-x.

Signed-off-by: Mika Fischer <mika.fischer@zoopnet.de>
2013-02-19 11:01:13 +01:00
Pieter Hintjens
4f1f68f6cc Merge pull request #78 from ianbarber/master
Backport of test_last_endpoint shutdown fix, resolves LIBZMQ-462
2013-02-11 10:21:30 -08:00
Ian Barber
5d3781a8bf Patch from Rob Gagnon, backport of test fix from master. Resolves LIBZMQ-462 2013-02-10 22:51:52 +00:00
Pieter Hintjens
d6aaa4a7ba Merge pull request #77 from ianbarber/master
Backport of test_connect_delay refactor from master
2013-02-06 23:51:22 -08:00
Ian Barber
b774772bb9 Backport of test_connect_delay refactor 2013-02-06 21:22:56 +00:00
Pieter Hintjens
a0a24a92af Merge pull request #76 from hintjens/master
Backported fix for LIBZMQ-497
2013-02-01 01:04:42 -08:00
Min(Dongmin Yu)
6a7dcfb898 LIBZMQ-497 there could be unsent bytes in encoder
When we send a large message, the message can be splitted into two chunks.
One is in the encoder buffer and the other is the zero-copy pointer.
The session could get the term before the last chunk is sent.
2013-02-01 10:03:55 +01:00
Pieter Hintjens
8e748064ac Merge pull request #75 from hintjens/master
Backported c436c8
2013-01-21 09:07:35 -08:00
MinRK
c436c8cdc3 AM_CONFIG_HEADER -> AC_CONFIG_HEADERS
AM_CONFIG_HEADER raises an 'obsolete error' with automake 1.13.
2013-01-21 18:06:40 +01:00
Pieter Hintjens
0df7bbbc9d Merge pull request #73 from amuraru/fix-newline
Fixed newline in test_disconnect_inproc
2013-01-11 13:42:27 -08:00
Pieter Hintjens
c2b6f06d0d Merge pull request #72 from amuraru/fix-spec
Fixed el5/el6 deps in RPM spec file
2013-01-11 13:41:30 -08:00
Adrian Muraru
4a0410ad21 Fixed newline in test_disconnect_inproc 2013-01-11 23:00:02 +02:00
Adrian Muraru
572be0e82c Fixed el5/el6 deps in RPM spec file 2013-01-11 22:57:40 +02:00
Ian Barber
92446d81ce Merge pull request #71 from hintjens/master
Backported fix for LIBZMQ-488
2012-12-27 06:16:08 -08:00
KIU Shueng Chuan
96ce417422 win32: close zmq-signaler-port-sync event object to avoid handle leak 2012-12-27 14:47:14 +01:00
Martin Hurton
911387cfbb Merge pull request #70 from sradomski/master
Removal of terminated pipes from inproc and ignoring peer ends
2012-12-04 08:50:44 -08:00
Stefan Radomski
2131e85cd7 Break early when pipe to be removed was found 2012-12-04 17:41:08 +01:00
Stefan Radomski
fbfd3c34d9 Fixed iterator when erasing from inprocs multimap 2012-12-04 17:32:38 +01:00
Stefan Radomski
1965e2d05d Removal of terminated pipes from inproc and ignoring peer ends 2012-12-04 17:03:58 +01:00
Martin Hurton
a91779baf1 Merge pull request #69 from sradomski/master
Close pipes for inproc sockets on zmq_disconnect
2012-12-04 05:49:13 -08:00
Stefan Radomski
8e6fdc56e1 Changed errno to ENOENT for disconnecting unconnected endpoints 2012-12-04 14:14:46 +01:00
Stefan Radomski
b0563c2103 Set errno and update documentation on zmq_disconnect 2012-12-04 13:52:23 +01:00
Stefan Radomski
2388f27bfe Close inproc socket pairs on zmq_disconnect
This patch fixes LIBZMQ-476 and LIBZMQ-475
2012-12-04 13:14:56 +01:00
Ian Barber
ba1fd8e82a Merge pull request #68 from vperron/master
ARM toolchain compatibility
2012-11-30 14:11:26 -08:00
Victor Perron
6d4e2ce93b Change NULL to 0 to keep compatibility with some cross-compiling GCC
versions
2012-11-30 22:58:03 +01:00
Pieter Hintjens
7541e38205 Merge pull request #67 from ianbarber/master
Update RPM spec file
2012-11-26 08:24:16 -08:00
Ian Barber
c7786d4374 Update SPEC file
Update the RPM spec file with Justin Cook's changes to fix the build for 3.2.2. (https://zeromq.jira.com/browse/LIBZMQ-473)
2012-11-26 16:21:06 +00:00
Pieter Hintjens
ed8ab632c6 Updated version to 3.2.3 for next stable release 2012-11-23 17:05:43 +09:00
Pieter Hintjens
2ae1bd2088 Merge pull request #66 from hintjens/master
One fix to NEWS
2012-11-22 23:58:03 -08:00
Pieter Hintjens
3b268c6943 Added NEWS entry for issue 465 2012-11-23 16:57:23 +09:00
Pieter Hintjens
025e218629 Merge pull request #65 from hintjens/master
Release 3.2.2 stable
2012-11-22 23:54:06 -08:00
Pieter Hintjens
61b936893d Updated NEWS for release 3.2.2 2012-11-23 16:52:50 +09:00
Pieter Hintjens
bcf8916e17 Backported latest socket event framework 2012-11-23 16:42:13 +09:00
Pieter Hintjens
12f3f8a7f6 Merge pull request #64 from hintjens/master
Backported fix for LIBZMQ-472
2012-11-21 19:20:21 -08:00
Martin Hurton
9120741719 Check decoder's state function for NULL before calling it
Fixes bug reported by Peter Friend
(http://lists.zeromq.org/pipermail/zeromq-dev/2012-November/019425.html)
2012-11-22 12:17:07 +09:00
Pieter Hintjens
efdb5cf076 Merge pull request #63 from hintjens/master
Added autogen.sh hint to INSTALL
2012-11-21 19:10:12 -08:00
Pieter Hintjens
ae8c4a4adf Added autogen.sh hint 2012-11-22 12:09:31 +09:00
Pieter Hintjens
f9b6da0e78 Merge pull request #61 from hintjens/master
Fixed doc for SNDHWM
2012-11-18 23:33:54 -08:00
Pieter Hintjens
f5a9c328e9 Fixed ZMQ_SNDHWM description 2012-11-19 16:33:20 +09:00
Pieter Hintjens
65a29e85ee Merge pull request #60 from hintjens/master
Fixed doc for SNDHWM
2012-11-18 17:22:24 -08:00
Pieter Hintjens
f0383bffad Clarified that SNDHWM is per part, not message 2012-11-19 10:21:46 +09:00
John Muehlhausen
a7438de239 Issue 468
XPUB "verbose" mode excludes unsubscriptions
2012-11-16 10:59:37 +09:00
Pieter Hintjens
7f81575245 Merge pull request #59 from hintjens/master
Backported fix for LIBZMQ-450
2012-11-14 02:38:02 -08:00
Lourens Naudé
c05a1b1f26 Backported fix for addresses on triggered events 2012-11-14 19:19:29 +09:00
Pieter Hintjens
f976e8cc98 Merge pull request #58 from hintjens/master
Addded ROUTER-ROUTER and DEALER-DEALER (back) as valid combinations
2012-11-13 17:03:48 -08:00
Pieter Hintjens
07122eefec Updated doc to allow DEALER-DEALER and ROUTER-ROUTER 2012-11-14 10:03:11 +09:00
Pieter Hintjens
69fa792cae Merge pull request #57 from hintjens/master
Backported fixes for LIBZMQ-465
2012-11-13 04:40:49 -08:00
Pieter Hintjens
30738e1123 Backported fix for ZMQ-465 2012-11-13 21:39:59 +09:00
Martin Hurton
50b6da0c1c Minor code cleanup 2012-11-13 21:39:41 +09:00
Martin Hurton
0c0a351fa5 Backported fix for ZMQ-465 2012-11-13 21:36:17 +09:00
Pieter Hintjens
36736e64cc Merge pull request #56 from hintjens/master
Backported fixes for LIBZMQ-459
2012-11-06 04:01:22 -08:00
Martin Hurton
50e9d72dc4 Resolve LIBZMQ-459
Ref: https://zeromq.jira.com/browse/LIBZMQ-459
2012-11-06 09:49:09 +01:00
Pieter Hintjens
87c6ebb135 Merge pull request #55 from vortechs2000/remove_cpp_comments_from_zmq_h
Older versions of C compilers don't like C++ comments
2012-11-05 09:44:33 -08:00
AJ Lewis
4527d8db6f Older versions of C compilers don't like C++ comments
There's no need to exclude older compilers by putting C++ style
comments in the C API header.

Signed-off-by: AJ Lewis <aj.lewis@quantum.com>
2012-11-05 11:32:13 -06:00
Pieter Hintjens
ed9c7440d2 Merge pull request #54 from hintjens/master
Backported fixes for LIBZMQ-464
2012-11-01 08:43:41 -07:00
Martin Hurton
fec6497976 Resolve LIBZMQ-464 2012-11-01 16:42:18 +01:00
Pieter Hintjens
f56c6faf65 Merge pull request #53 from hintjens/master
Fixed formatting on zmq_getsockopt.txt
2012-10-30 20:38:56 -07:00
Pieter Hintjens
1d9a3fd480 Fixed formatting in man page 2012-10-31 04:38:19 +01:00
Pieter Hintjens
fff267071d Merge pull request #52 from hintjens/master
Backported fixes for LIBZMQ-458
2012-10-30 03:13:50 -07:00
Martin Hurton
ec8d935acc Resolve LIBZMQ-458
Ref: https://zeromq.jira.com/browse/LIBZMQ-458
2012-10-30 11:13:09 +01:00
Pieter Hintjens
08b0af5075 Merge pull request #51 from hintjens/master
Backported fixes for LIBZMQ-447
2012-10-29 22:29:33 -07:00
Pieter Hintjens
b0576e8c54 Merge pull request #47 from steve-o/master
Improve PGM build integration for Windows
2012-10-29 22:28:16 -07:00
Martin Hurton
5b9de45a89 Resolve LIBZMQ-447 2012-10-30 06:26:30 +01:00
Pieter Hintjens
2996b25039 Merge pull request #49 from hintjens/master
Backported fixes for LIBZMQ-452 and LIBZMQ-415
2012-10-26 17:45:30 -07:00
Pieter Hintjens
09c56c4493 Cleanups to man pages 2012-10-27 09:45:01 +09:00
Martin Hurton
d9d7d9be54 Resolve LIBZMQ-452
Ref: https://zeromq.jira.com/browse/LIBZMQ-452
2012-10-25 18:22:51 +09:00
Martin Hurton
d95f8c5f55 Resolve LIBZMQ-417
Ref: https://zeromq.jira.com/browse/LIBZMQ-417
2012-10-25 18:21:08 +09:00
Pieter Hintjens
ceb388e371 Merge pull request #48 from vortechs2000/fix_aix
Fix Build Regression #449: Move socket_base.hpp and err.hpp after poll.h include
2012-10-23 17:01:36 -07:00
AJ Lewis
888c1bdb5b Move socket_base.hpp and err.hpp after poll.h include
These two headers also include zmq.h somewhere in their dependency
chain, so must be included after poll.h is included for builds to work
on AIX.
2012-10-23 16:18:36 -05:00
Steven McCoy
a5da31eb07 Update NSIS x64 install to use different registry keys to x86. 2012-10-20 14:56:00 -04:00
Steven McCoy
bbff2fc3f8 Expand Windows PGM build integration to support multiple CRTs and use registered versions.
Add libpgm to linker as now removed upstream.
Add version details to ZeroMQ library names.
Add multi-CRT dependencies to packaging.
Add x64 postfix to Win64 packages to avoid conflict with x86 installs.
2012-10-20 14:49:27 -04:00
Ian Barber
c391966fbb Merge pull request #46 from hintjens/master
Fixed build regression #449
2012-10-19 15:05:41 -07:00
Pieter Hintjens
24ea41ce7a Added unbind/disconnect man pages, notes to deprecated methods 2012-10-19 16:23:59 +09:00
Pieter Hintjens
d0eed09f6f Added ZMQ_FAIL_UNROUTABLE alias back as deprecated 2012-10-19 15:16:15 +09:00
Pieter Hintjens
5e4f858c8e Fixed issue #451 2012-10-19 15:10:34 +09:00
Pieter Hintjens
bdbdf8bb7e Fixed issue #449 2012-10-18 11:34:16 +09:00
Ian Barber
30e2da05a1 Merge pull request #45 from hintjens/master
Fixed build regression
2012-10-17 19:21:38 -07:00
Pieter Hintjens
2fe4a355fd Fixed issue #448 2012-10-18 11:10:21 +09:00
Ian Barber
da7427b771 Merge pull request #44 from hintjens/master
Packages did not build - fixed
2012-10-15 23:32:25 -07:00
Pieter Hintjens
e18b69bfa1 Several include files were missing 2012-10-16 10:00:43 +09:00
Ian Barber
05bd3ea8b9 Merge pull request #43 from hintjens/master
Updated zeromq3-x version to 3.2.2 for next release
2012-10-15 09:46:59 -07:00
Pieter Hintjens
7735322151 Updated version for next release 2012-10-15 13:07:52 +09:00
65 changed files with 1308 additions and 696 deletions

1
.gitignore vendored
View File

@ -42,6 +42,7 @@ tests/test_connect_resolve
tests/test_connect_delay
tests/test_term_endpoint
tests/test_router_mandatory
tests/test_disconnect_inproc
src/platform.hpp*
src/stamp-h1
perf/local_lat

2
.travis.yml Normal file
View File

@ -0,0 +1,2 @@
script: ./autogen.sh && ./configure && make && make check
language: c

View File

@ -66,6 +66,7 @@ Pieter Hintjens <ph@imatix.com>
Piotr Trojanek <piotr.trojanek@gmail.com>
Robert G. Jakabosky <bobby@sharedrealm.com>
Sebastian Otaegui <feniix@gmail.com>
Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de>
Steven McCoy <steven.mccoy@miru.hk>
Stuart Webster <sw_webster@hotmail.com>
Tamara Kustarova <kustarova.tamara@gmail.com>

View File

@ -1,6 +1,9 @@
# CMake build script for ZeroMQ on Windows
cmake_minimum_required (VERSION 2.8)
# 2.8.11 provides toolkit support
# 2.8.11.2 provides MSVC2013 support
cmake_minimum_required (VERSION 2.8.11.2)
project (ZeroMQ)
include (${CMAKE_SOURCE_DIR}/cmake/Modules/TestZMQVersion.cmake)
@ -11,11 +14,36 @@ option (WITH_OPENPGM "Build with support for OpenPGM" OFF)
# WARNING: Windows Python will override Cygwin yet not work with Asciidoc.
#find_package (PythonInterp REQUIRED)
# Workaround, manually set Python location
set(PYTHON_EXECUTABLE c:/cygwin/bin/python2.6.exe CACHE FILEPATH "Python interpreter executable")
set(PYTHON_EXECUTABLE c:/cygwin/bin/python2.7.exe CACHE FILEPATH "Python interpreter executable")
# TODO: Replace with FindAsciidoc.cmake
set(ASCIIDOC_EXECUTABLE c:/cygwin/bin/asciidoc CACHE FILEPATH "AsciiDoc executable")
set(OPENPGM_ROOT /libpgm/libpgm-5.1.118-1~dfsg/openpgm/pgm CACHE PATH "Location of OpenPGM")
if (WITH_OPENPGM)
# set(OPENPGM_ROOT "" CACHE PATH "Location of OpenPGM")
set(OPENPGM_VERSION_MAJOR 5)
set(OPENPGM_VERSION_MINOR 2)
set(OPENPGM_VERSION_MICRO 122)
if (CMAKE_CL_64)
find_path(OPENPGM_ROOT include/pgm/pgm.h
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Miru\\OpenPGM ${OPENPGM_VERSION_MAJOR}.${OPENPGM_VERSION_MINOR}.${OPENPGM_VERSION_MICRO}]"
NO_DEFAULT_PATH
)
else (CMAKE_CL_64)
find_path(OPENPGM_ROOT include/pgm/pgm.h
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Miru\\OpenPGM ${OPENPGM_VERSION_MAJOR}.${OPENPGM_VERSION_MINOR}.${OPENPGM_VERSION_MICRO}]"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Miru\\OpenPGM ${OPENPGM_VERSION_MAJOR}.${OPENPGM_VERSION_MINOR}.${OPENPGM_VERSION_MICRO}]"
NO_DEFAULT_PATH
)
endif (CMAKE_CL_64)
message(STATUS "OpenPGM detected - ${OPENPGM_ROOT}")
set(OPENPGM_INCLUDE_DIRS ${OPENPGM_ROOT}/include)
set(OPENPGM_LIBRARY_DIRS ${OPENPGM_ROOT}/lib)
set(OPENPGM_LIBRARIES
optimized libpgm${_zmq_TOOLSET}-mt-${OPENPGM_VERSION_MAJOR}_${OPENPGM_VERSION_MINOR}_${OPENPGM_VERSION_MICRO}.lib
debug libpgm${_zmq_TOOLSET}-mt-gd-${OPENPGM_VERSION_MAJOR}_${OPENPGM_VERSION_MINOR}_${OPENPGM_VERSION_MICRO}.lib)
endif (WITH_OPENPGM)
mark_as_advanced(PYTHON_EXECUTABLE ASCIIDOC_EXECUTABLE)
@ -54,6 +82,7 @@ add_definitions(
# NB: May require tweaking for highly connected applications.
-DFD_SETSIZE=1024
-D_CRT_SECURE_NO_WARNINGS
-D_WIN32_WINNT=${_zmq_WIN32_WINNT}
)
# Parallel make.
@ -160,28 +189,13 @@ if(WITH_OPENPGM)
add_definitions(
-DZMQ_HAVE_OPENPGM
)
include_directories(
${OPENPGM_ROOT}/include
${OPENPGM_INCLUDE_DIRS}
)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Win64
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPENPGM_LIBRARYDIR ${OPENPGM_ROOT}/debug64/lib)
else (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPENPGM_LIBRARYDIR ${OPENPGM_ROOT}/build64/lib)
endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
else (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Win32
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPENPGM_LIBRARYDIR ${OPENPGM_ROOT}/debug/lib)
else (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPENPGM_LIBRARYDIR ${OPENPGM_ROOT}/build/lib)
endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
link_directories(
${OPENPGM_LIBRARYDIR}
${OPENPGM_LIBRARY_DIRS}
)
set(OPTIONAL_LIBRARIES ${OPENPGM_LIBRARIES})
endif(WITH_OPENPGM)
#-----------------------------------------------------------------------------
@ -207,11 +221,11 @@ add_custom_command(
)
list(APPEND sources ${CMAKE_BINARY_DIR}/platform.hpp)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if (CMAKE_CL_64)
set (nsis-template ${CMAKE_SOURCE_DIR}/cmake/NSIS.template64.in)
else (CMAKE_SIZEOF_VOID_P EQUAL 8)
else (CMAKE_CL_64)
set (nsis-template ${CMAKE_SOURCE_DIR}/cmake/NSIS.template32.in)
endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
endif (CMAKE_CL_64)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/NSIS.template.in
COMMAND ${CMAKE_COMMAND}
@ -252,19 +266,29 @@ endforeach (txt ${docs})
#-----------------------------------------------------------------------------
# output
message(targetting ${_zmq_TOOLSET})
add_library(libzmq SHARED ${sources} ${html-docs} ${CMAKE_BINARY_DIR}/NSIS.template.in)
target_link_libraries(libzmq ws2_32.lib rpcrt4.lib)
target_link_libraries(libzmq ws2_32.lib rpcrt4.lib ${OPTIONAL_LIBRARIES})
set_target_properties(libzmq PROPERTIES
RELEASE_POSTFIX "${_zmq_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}"
DEBUG_POSTFIX "${_zmq_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}"
PDB_NAME "libzmq${_zmq_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}"
PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
)
set_target_properties(libzmq PROPERTIES RELEASE_POSTFIX "${_zmq_COMPILER}-mt" DEBUG_POSTFIX "${_zmq_COMPILER}-mt-gd")
#-----------------------------------------------------------------------------
# installer
install (TARGETS libzmq ARCHIVE DESTINATION lib COMPONENT SDK)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
install (FILES ${CMAKE_BINARY_DIR}/lib/libzmq${_zmq_COMPILER}-mt-gd.dll DESTINATION bin COMPONENT SDK)
install (FILES ${CMAKE_BINARY_DIR}/lib/libzmq${_zmq_COMPILER}-mt-gd.lib DESTINATION lib COMPONENT SDK)
install (FILES ${CMAKE_BINARY_DIR}/lib/libzmq${_zmq_COMPILER}-mt-gd.pdb DESTINATION lib COMPONENT SDK)
else (CMAKE_BUILD_TYPE STREQUAL "Debug")
# no -op
else ()
install (TARGETS libzmq RUNTIME DESTINATION bin COMPONENT Runtime)
install (FILES ${CMAKE_BINARY_DIR}/lib/libzmq${_zmq_COMPILER}-mt.lib DESTINATION lib COMPONENT SDK)
endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
install (FILES ${CMAKE_BINARY_DIR}/lib/Debug/libzmq${_zmq_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}.lib DESTINATION lib COMPONENT SDK)
install (FILES ${CMAKE_BINARY_DIR}/lib/Debug/libzmq${_zmq_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}.pdb DESTINATION lib COMPONENT SDK)
install (FILES ${CMAKE_BINARY_DIR}/lib/Debug/libzmq${_zmq_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}.dll DESTINATION bin COMPONENT SDK)
endif ()
install (FILES ${headers} DESTINATION include COMPONENT SDK)
set (perf-tools
@ -296,18 +320,28 @@ endif (WITH_DOC)
include (InstallRequiredSystemLibraries)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if (CMAKE_CL_64)
set (CPACK_NSIS_DISPLAY_NAME "ZeroMQ ${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH} (x64)")
set (CPACK_PACKAGE_FILE_NAME "ZeroMQ-${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH}-x64")
set (CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_SOURCE_DIR}/build64;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/debug64;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x64/v90;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x64/v110;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x64/v120;ZeroMQ;ALL;/"
# default to 2008/Vista compatible CRT
"${CMAKE_SOURCE_DIR}/build/x64/v100;ZeroMQ;ALL;/"
)
else (CMAKE_SIZEOF_VOID_P EQUAL 8)
else (CMAKE_CL_64)
set (CPACK_NSIS_DISPLAY_NAME "ZeroMQ ${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH}")
set (CPACK_PACKAGE_FILE_NAME "ZeroMQ-${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH}-x86")
set (CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_SOURCE_DIR}/build;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/debug;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x86/v90;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x86/v100;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x86/v110;ZeroMQ;ALL;/"
"${CMAKE_SOURCE_DIR}/build/x86/v120;ZeroMQ;ALL;/"
# default to XP-compatible CRT
"${CMAKE_SOURCE_DIR}/build/x86/v110_xp;ZeroMQ;ALL;/"
)
endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
endif (CMAKE_CL_64)
set (CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}")
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "ZeroMQ lightweight messaging kernel")
set (CPACK_PACKAGE_VENDOR "Miru")

View File

@ -7,6 +7,13 @@ Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
From GitHub
===========
If you clone the Git repository then you should start by running the
command `./autogen.sh`. This is not necessary if you get the source
packages.
Basic Installation
==================

51
NEWS
View File

@ -1,3 +1,54 @@
0MQ version 3.2.4 stable, released on 2013/09/20
================================================
* LIBZMQ-84 (Windows) Assertion failed: Address already in use at signaler.cpp:80
* LIBZMQ-456 ZMQ_XPUB_VERBOSE does not propagate in a tree of XPUB/XSUB devices
* LIBZMQ-532 (Windows) critical section not released on error
* LIBZMQ-569 Detect OpenPGM 5.2 system library
* LIBZMQ-563 Subscribers sometimes stopped receiving messages (aka LIBZMQ-541)
* LIBZMQ-XXX Added support for Travis Continuous Integration
* LIBZMQ-XXX Several improvements to MSVC support
0MQ version 3.2.3 stable, released on 2013/05/02
================================================
Issues addressed in this release
--------------------------------
* LIBZMQ-526 Assertion failure "Invalid argument (tcp_connecter.cpp:285)"
* LIBZMQ-446 Setting the DSCP bits by default causes CAP_NET_ADMIN error
* LIBZMQ-496 Crash on heavy socket opening/closing: Device or resource busy (mutex.hpp:90)
* LIBZMQ-462 test_connect_delay fails at test_connect_delay.cpp:80
* LIBZMQ-497 Messages getting dropped
* LIBZMQ-488 signaler.cpp leaks the win32 Event Handle
* LIBZMQ-476 zmq_disconnect has no effect for inproc sockets
* LIBZMQ-475 zmq_disconnect does not sent unsubscribe messages
0MQ version 3.2.2 stable, released on 2012/11/23
================================================
Issues addressed in this release
--------------------------------
* LIBZMQ-384 No meta data for ZMQ_EVENT_DISCONNECTED monitor event
* LIBZMQ-414 Error in ARM/Thumb2 assembly (atomic_ptr.hpp)
* LIBZMQ-417 zmq_assert (!incomplete_in) in session_base.cpp 228
* LIBZMQ-447 socket_base_t::recv() packet loss and memory leak at high receiving rate
* LIBZMQ-448 Builds fail on older versions of GCC
* LIBZMQ-449 Builds fail on AIX
* LIBZMQ-450 lt-test_monitor: fails with assertion at test_monitor.cpp:81
* LIBZMQ-451 ZMQ_ROUTER_MANDATORY blocks forever
* LIBZMQ-452 test_connect_delay.cpp:175:12: error: 'sleep' was not declared in this scope
* LIBZMQ-458 lt-test_router_mandatory fails with assertion at test_router_mandatory.cpp:53
* LIBZMQ-459 Assertion failed: encoder (stream_engine.cpp:266
* LIBZMQ-464 PUB socket with HWM set leaks memory
* LIBZMQ-465 PUB/SUB results in 80-90% of CPU load
* LIBZMQ-468 ZMQ_XPUB_VERBOSE & unsubscribe
* LIBZMQ-472 Segfault in zmq_poll in REQ to ROUTER dialog
0MQ version 3.2.1 (RC2), released on 2012/10/15
===============================================

View File

@ -0,0 +1,85 @@
@echo off
setlocal
set WITH_OPENPGM=true
set WITH_DOC=true
:: Remove old build files
echo Cleaning build area ...
rmdir /s /q build 2> null
md build\x86\v90 build\x86\v100 build\x86\v110 build\x86\v110_xp build\x86\v120 2> null
md build\x64\v90 build\x64\v100 build\x64\v110 build\x64\v120 2> null
echo Starting build ...
call:buildx86 build\x86 ..\..
call:buildx64 build\x64 ..\..
echo Build finished.
goto:eof
:buildx86
echo Building targets for x86 ...
setlocal
cd %~1\v90
call "%ProgramFiles(x86)%\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
cmake -G "Visual Studio 12" ..\..\.. -T "v90" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug /target:ALL_BUILD ZeroMQ.sln >> build.log && msbuild /nologo /property:Configuration=Release /target:ALL_BUILD ZeroMQ.sln >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..\v100
cmake -G "Visual Studio 12" ..\..\.. -T "v100" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release ALL_BUILD.vcxproj >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..\v110
cmake -G "Visual Studio 12" ..\..\.. -T "v110" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release ALL_BUILD.vcxproj >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..\v120
cmake -G "Visual Studio 12" ..\..\.. -T "v120" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release ALL_BUILD.vcxproj >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..\v110_xp
cmake -G "Visual Studio 12" ..\..\.. -T "v110_xp" -DWITH_OPENPGM=%WITH_OPENPGM% -DWITH_DOC=%WITH_DOC% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release PACKAGE.vcxproj >> build.log
(
dir *.exe
for /D %%f in (lib\*) do dir %%f\*.dll
) | findstr "\/"
cd %~2
endlocal
goto:eof
:buildx64
echo Building targets for x64 ...
cd %~1
setlocal
call "%ProgramFiles(x86)%\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
:: If linker crashes out with LNK1000 error install KB948127 to fix
:: https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=11399
(
cd v90
cmake -G "Visual Studio 12 Win64" ..\..\.. -T "v90" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug /target:ALL_BUILD ZeroMQ.sln >> build.log && msbuild /nologo /property:Configuration=Release /target:ALL_BUILD ZeroMQ.sln >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..
)
(
cd v100
cmake -G "Visual Studio 12 Win64" ..\..\.. -T "v100" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release ALL_BUILD.vcxproj >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..
)
(
cd v110
cmake -G "Visual Studio 12 Win64" ..\..\.. -T "v110" -DWITH_OPENPGM=%WITH_OPENPGM% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release ALL_BUILD.vcxproj >> build.log
for /D %%f in (lib\*) do dir %%f\*.dll | findstr "\/"
cd ..
)
(
cd v120
cmake -G "Visual Studio 12 Win64" ..\..\.. -T "v120" -DWITH_OPENPGM=%WITH_OPENPGM% -DWITH_DOC=%WITH_DOC% > build.log && msbuild /nologo /property:Configuration=Debug ALL_BUILD.vcxproj >> build.log && msbuild /nologo /property:Configuration=Release PACKAGE.vcxproj >> build.log
(
dir *.exe
for /D %%f in (lib\*) do dir %%f\*.dll
) | findstr "\/"
cd ..
)
endlocal
cd %~2
goto:eof

View File

@ -0,0 +1,31 @@
CC=gcc
CFLAGS=-Wall -Os -g -DDLL_EXPORT -DFD_SETSIZE=1024 -I.
LIBS=-lws2_32
OBJS = address.o clock.o ctx.o dealer.o decoder.o devpoll.o dist.o encoder.o epoll.o err.o fq.o \
io_object.o io_thread.o ip.o ipc_address.o ipc_connecter.o ipc_listener.o kqueue.o lb.o \
mailbox.o msg.o mtrie.o object.o options.o own.o pair.o pgm_receiver.o pgm_sender.o \
pgm_socket.o pipe.o poll.o poller_base.o precompiled.o proxy.o pub.o pull.o push.o \
random.o reaper.o rep.o req.o router.o select.o session_base.o \
signaler.o socket_base.o stream_engine.o sub.o tcp.o tcp_address.o tcp_connecter.o tcp_listener.o \
thread.o trie.o v1_decoder.o v1_encoder.o xpub.o xsub.o zmq.o zmq_utils.o
%.o: ../../src/%.cpp
$(CC) -c -o $@ $< $(CFLAGS)
%.o: ../../perf/%.cpp
$(CC) -c -o $@ $< $(CFLAGS)
all: libzmq.dll
perf: inproc_lat.exe inproc_thr.exe local_lat.exe local_thr.exe remote_lat.exe remote_thr.exe
libzmq.dll: $(OBJS)
g++ -shared -o $@ $^ -Wl,--out-implib,$@.a $(LIBS)
%.exe: %.o libzmq.dll
g++ -o $@ $^
clean:
del *.o *.a *.dll *.exe

View File

@ -0,0 +1,32 @@
/*
Copyright (c) 2007-2011 iMatix Corporation
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ 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
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ZMQ_PLATFORM_HPP_INCLUDED__
#define __ZMQ_PLATFORM_HPP_INCLUDED__
// This is the platform definition for the MSVC platform.
// As a first step of the build process it is copied to
// zmq directory to take place of platform.hpp generated from
// platform.hpp.in on platforms supported by GNU autotools.
// Place any MSVC-specific definitions here.
#define ZMQ_HAVE_WINDOWS
#endif

View File

@ -1,6 +1,7 @@
LIBZMQ_DIST = libzmq/libzmq.vcproj libzmq/libzmq.vcxproj \
libzmq/libzmq.vcxproj.filters \
platform.hpp msvc.sln msvc10.sln
platform.hpp msvc.sln msvc10.sln \
errno.cpp errno.hpp
PERF_DIST = c_local_thr/c_local_thr.vcproj \
c_local_thr/c_local_thr.vcxproj \

View File

@ -11,12 +11,15 @@ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: gcc, make, gcc-c++, libstdc++-devel
Requires: libstdc++
%if %{?rhel}%{!?rhel:0} >= 6
%if 0%{?rhel}
%if 0%{?rhel} == 6
BuildRequires: libuuid-devel
Requires: libuuid
%elseif %{?rhel}%{!?rhel:0} >= 5
%endif
%if 0%{?rhel} == 5
BuildRequires: e2fsprogs-devel
Requires: e2fsprogs
%endif
%else
BuildRequires: uuid-devel
Requires: uuid
@ -57,7 +60,7 @@ This package contains ZeroMQ related development libraries and header files.
%build
%ifarch pentium3 pentium4 athlon i386 i486 i586 i686 x86_64
%configure --with-pgm
%configure --with-pgm --with-pic --with-gnu-ld
%else
%configure
%endif
@ -87,17 +90,10 @@ This package contains ZeroMQ related development libraries and header files.
%doc AUTHORS ChangeLog COPYING COPYING.LESSER NEWS README
# libraries
%{_libdir}/libzmq.so.1
%{_libdir}/libzmq.so.1.0.0
%attr(0755,root,root) %{_bindir}/zmq_forwarder
%attr(0755,root,root) %{_bindir}/zmq_queue
%attr(0755,root,root) %{_bindir}/zmq_streamer
%{_libdir}/libzmq.so.3
%{_libdir}/libzmq.so.3.0.0
%{_mandir}/man7/zmq.7.gz
%{_mandir}/man1/zmq_forwarder.1.gz
%{_mandir}/man1/zmq_queue.1.gz
%{_mandir}/man1/zmq_streamer.1.gz
%files devel
%defattr(-,root,root,-)
@ -112,6 +108,12 @@ This package contains ZeroMQ related development libraries and header files.
%{_mandir}/man3/zmq_bind.3.gz
%{_mandir}/man3/zmq_close.3.gz
%{_mandir}/man3/zmq_connect.3.gz
%{_mandir}/man3/zmq_disconnect.3.gz
%{_mandir}/man3/zmq_ctx_destroy.3.gz
%{_mandir}/man3/zmq_ctx_get.3.gz
%{_mandir}/man3/zmq_ctx_new.3.gz
%{_mandir}/man3/zmq_ctx_set.3.gz
%{_mandir}/man3/zmq_msg_recv.3.gz
%{_mandir}/man3/zmq_errno.3.gz
%{_mandir}/man3/zmq_getsockopt.3.gz
%{_mandir}/man3/zmq_init.3.gz
@ -123,16 +125,24 @@ This package contains ZeroMQ related development libraries and header files.
%{_mandir}/man3/zmq_msg_init_size.3.gz
%{_mandir}/man3/zmq_msg_move.3.gz
%{_mandir}/man3/zmq_msg_size.3.gz
%{_mandir}/man3/zmq_msg_get.3.gz
%{_mandir}/man3/zmq_msg_more.3.gz
%{_mandir}/man3/zmq_msg_recv.3.gz
%{_mandir}/man3/zmq_msg_send.3.gz
%{_mandir}/man3/zmq_msg_set.3.gz
%{_mandir}/man3/zmq_poll.3.gz
%{_mandir}/man3/zmq_proxy.3.gz
%{_mandir}/man3/zmq_recv.3.gz
%{_mandir}/man3/zmq_recvmsg.3.gz
%{_mandir}/man3/zmq_send.3.gz
%{_mandir}/man3/zmq_sendmsg.3.gz
%{_mandir}/man3/zmq_setsockopt.3.gz
%{_mandir}/man3/zmq_socket.3.gz
%{_mandir}/man3/zmq_socket_monitor.3.gz
%{_mandir}/man3/zmq_strerror.3.gz
%{_mandir}/man3/zmq_term.3.gz
%{_mandir}/man3/zmq_version.3.gz
%{_mandir}/man3/zmq_unbind.3.gz
%{_mandir}/man7/zmq_epgm.7.gz
%{_mandir}/man7/zmq_inproc.7.gz
%{_mandir}/man7/zmq_ipc.7.gz
@ -140,6 +150,9 @@ This package contains ZeroMQ related development libraries and header files.
%{_mandir}/man7/zmq_tcp.7.gz
%changelog
* Mon Nov 26 2012 Justin Cook <jhcook@gmail.com> 3.2.2
- Update packaged files
* Fri Apr 8 2011 Mikko Koppanen <mikko@kuut.io> 3.0.0-1
- Update dependencies and packaged files

View File

@ -24,12 +24,36 @@
MESSAGE(STATUS "Detecting ZMQ - failed")
ENDIF()
if(MSVC_VERSION MATCHES "1700")
set(_zmq_COMPILER "-v110")
elseif(MSVC10)
set(_zmq_COMPILER "-v100")
elseif(MSVC90)
set(_zmq_COMPILER "-v90")
if(CMAKE_GENERATOR_TOOLSET MATCHES "v120")
set(_zmq_TOOLSET "-v120")
set(_zmq_COMPILER "vc120")
set(_zmq_WIN32_WINNT "0x0601")
elseif(CMAKE_GENERATOR_TOOLSET MATCHES "v110_xp")
set(_zmq_TOOLSET "-v110_xp")
set(_zmq_COMPILER "vc110")
set(_zmq_WIN32_WINNT "0x0501")
elseif(CMAKE_GENERATOR_TOOLSET MATCHES "v110")
set(_zmq_TOOLSET "-v110")
set(_zmq_COMPILER "vc110")
set(_zmq_WIN32_WINNT "0x0601")
elseif(CMAKE_GENERATOR_TOOLSET MATCHES "v100")
set(_zmq_TOOLSET "-v100")
set(_zmq_COMPILER "vc100")
if(CMAKE_CL_64)
set(_zmq_WIN32_WINNT "0x0600")
else()
set(_zmq_COMPILER "")
set(_zmq_WIN32_WINNT "0x0501")
endif()
elseif(CMAKE_GENERATOR_TOOLSET MATCHES "v90")
set(_zmq_TOOLSET "-v90")
set(_zmq_COMPILER "vc90")
if(CMAKE_CL_64)
set(_zmq_WIN32_WINNT "0x0600")
else()
set(_zmq_WIN32_WINNT "0x0501")
endif()
else()
set(_zmq_TOOLSET "")
set(_zmq_COMPILER "")
set(_zmq_WIN32_WINNT "")
endif()

View File

@ -75,7 +75,7 @@ Var AR_RegFlags
ClearErrors
;Reading component status from registry
ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@\Components\${SecName}" "Installed"
ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)\Components\${SecName}" "Installed"
IfErrors "default_${SecName}"
;Status will stay default if registry value not found
;(component was never installed)
@ -108,13 +108,13 @@ Var AR_RegFlags
;Section is not selected:
;Calling Section uninstall macro and writing zero installed flag
!insertmacro "Remove_${${SecName}}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@\Components\${SecName}" \
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)\Components\${SecName}" \
"Installed" 0
Goto "exit_${SecName}"
"leave_${SecName}:"
;Section is selected:
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@\Components\${SecName}" \
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)\Components\${SecName}" \
"Installed" 1
"exit_${SecName}:"
@ -494,7 +494,7 @@ Function ConditionalAddToRegisty
Pop $0
Pop $1
StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" \
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)" \
"$1" "$0"
;MessageBox MB_OK "Set Registry: '$1' to '$0'"
DetailPrint "Set install registry entry: '$1' to '$0'"
@ -810,17 +810,17 @@ FunctionEnd
Section "Uninstall"
ReadRegStr $START_MENU SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" "StartMenu"
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)" "StartMenu"
;MessageBox MB_OK "Start menu is in: $START_MENU"
ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" "DoNotAddToPath"
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)" "DoNotAddToPath"
ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" "AddToPathAllUsers"
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)" "AddToPathAllUsers"
ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" "AddToPathCurrentUser"
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)" "AddToPathCurrentUser"
;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
ReadRegStr $INSTALL_DESKTOP SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" "InstallToDesktop"
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)" "InstallToDesktop"
;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "
@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
@ -837,7 +837,7 @@ Section "Uninstall"
;Remove the uninstaller itself.
Delete "$INSTDIR\Uninstall.exe"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@ (x64)"
;Remove the installation directory if it is empty.
RMDir "$INSTDIR"

View File

@ -10,7 +10,7 @@ AC_INIT([zeromq],[m4_esyscmd([./version.sh])],[zeromq-dev@lists.zeromq.org])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR(config)
AM_CONFIG_HEADER(src/platform.hpp)
AC_CONFIG_HEADERS([src/platform.hpp])
AM_INIT_AUTOMAKE(tar-ustar dist-zip foreign)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@ -348,10 +348,18 @@ fi
# Build with system openpgm
if test "x$with_system_pgm_ext" != "xno"; then
m4_ifdef([PKG_CHECK_MODULES], [
PKG_CHECK_MODULES([OpenPGM], [openpgm-5.1 >= 5.1])
have_pgm_system_library="no"
PKG_CHECK_MODULES([OpenPGM], [openpgm-5.2 >= 5.2],
[ have_pgm_system_library="yes" ],
[PKG_CHECK_MODULES([OpenPGM], [openpgm-5.1 >= 5.1],
[ have_pgm_system_library="yes" ])
]
)
if test "x$have_pgm_system_library" = "xyes"; then
AC_DEFINE(ZMQ_HAVE_OPENPGM, 1, [Have OpenPGM extension])
LIBZMQ_EXTRA_CXXFLAGS="$OpenPGM_CFLAGS $LIBZMQ_EXTRA_CXXFLAGS"
LIBS="$OpenPGM_LIBS $LIBS"
fi
],
[AC_MSG_ERROR([--with-system-pgm requires a working pkg-config installation])])
fi

View File

@ -1,12 +1,15 @@
MAN3 = zmq_bind.3 zmq_close.3 zmq_connect.3 zmq_proxy.3 \
MAN3 = zmq_bind.3 zmq_unbind.3 zmq_connect.3 zmq_disconnect.3 zmq_close.3 \
zmq_ctx_new.3 zmq_ctx_destroy.3 zmq_ctx_get.3 zmq_ctx_set.3 \
zmq_init.3 zmq_term.3 \
zmq_msg_close.3 zmq_msg_copy.3 zmq_msg_data.3 zmq_msg_init.3 \
zmq_msg_init_data.3 zmq_msg_init_size.3 zmq_msg_move.3 zmq_msg_size.3 \
zmq_msg_init.3 zmq_msg_init_data.3 zmq_msg_init_size.3 \
zmq_msg_move.3 zmq_msg_copy.3 zmq_msg_size.3 zmq_msg_data.3 zmq_msg_close.3 \
zmq_msg_send.3 zmq_msg_recv.3 \
zmq_poll.3 zmq_recv.3 zmq_send.3 zmq_setsockopt.3 zmq_socket.3 \
zmq_socket_monitor.3 zmq_strerror.3 zmq_version.3 zmq_getsockopt.3 zmq_errno.3 \
zmq_sendmsg.3 zmq_recvmsg.3 zmq_msg_get.3 zmq_msg_set.3 zmq_msg_more.3
zmq_send.3 zmq_recv.3 \
zmq_msg_get.3 zmq_msg_set.3 zmq_msg_more.3 \
zmq_getsockopt.3 zmq_setsockopt.3 \
zmq_socket.3 zmq_socket_monitor.3 zmq_poll.3 \
zmq_errno.3 zmq_strerror.3 zmq_version.3 zmq_proxy.3 \
zmq_sendmsg.3 zmq_recvmsg.3 zmq_init.3 zmq_term.3
MAN7 = zmq.7 zmq_tcp.7 zmq_pgm.7 zmq_epgm.7 zmq_inproc.7 zmq_ipc.7
MAN_DOC = $(MAN1) $(MAN3) $(MAN7)

View File

@ -4,7 +4,7 @@ zmq_bind(3)
NAME
----
zmq_bind - accept connections on a socket
zmq_bind - accept incoming connections on a socket
SYNOPSIS
@ -14,34 +14,41 @@ SYNOPSIS
DESCRIPTION
-----------
The _zmq_bind()_ function shall create an endpoint for accepting connections
and bind it to the socket referenced by the 'socket' argument.
The _zmq_bind()_ function binds the 'socket' to a local 'endpoint' and then
accepts incoming connections on that endpoint.
The 'endpoint' argument is a string consisting of two parts as follows:
'transport'`://`'address'. The 'transport' part specifies the underlying
transport protocol to use. The meaning of the 'address' part is specific to
the underlying transport protocol selected.
The 'endpoint' is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to bind to.
The following transports are defined:
0MQ provides the the following transports:
'inproc':: local in-process (inter-thread) communication transport, see linkzmq:zmq_inproc[7]
'ipc':: local inter-process communication transport, see linkzmq:zmq_ipc[7]
'tcp':: unicast transport using TCP, see linkzmq:zmq_tcp[7]
'ipc':: local inter-process communication transport, see linkzmq:zmq_ipc[7]
'inproc':: local in-process (inter-thread) communication transport, see linkzmq:zmq_inproc[7]
'pgm', 'epgm':: reliable multicast transport using PGM, see linkzmq:zmq_pgm[7]
ZeroMQ sockets support one-to-many and many-to-one semantics. With the exception
of 'ZMQ_PAIR' sockets every ZeroMQ socket type supports being bound with
_zmq_bind()_ as a singular endpoint or connecting with _zmq_connect()_ as one
of many endpoints. This allows combinations such as 1 ZMQ_REP to 100 ZMQ_REP and
100 ZMQ_REQ to 1 ZMQ_REP socket connections. Refer to linkzmq:zmq_socket[3] for
a description of the exact semantics involved when connecting or binding a socket
to multiple endpoints.
Every 0MQ socket type except 'ZMQ_PAIR' supports one-to-many and many-to-one
semantics. The precise semantics depend on the socket type and are defined in
linkzmq:zmq_socket[3].
The 'ipc' and 'tcp' transports accept wildcard addresses: see linkzmq:zmq_ipc[7]
and linkzmq:zmq_tcp[7] for details.
NOTE: the address syntax may be different for _zmq_bind()_ and _zmq_connect()_
especially for the 'tcp', 'pgm' and 'epgm' transports.
NOTE: following a _zmq_bind()_, the socket enters a 'mute' state unless or
until at least one incoming or outgoing connection is made, at which point
the socket enters a 'ready' state. In the mute state, the socket blocks or
drops messages according to the socket type, as defined in linkzmq:zmq_socket[3].
By contrast, following a libzmq:zmq_connect[3], the socket enters the 'ready' state.
RETURN VALUE
------------
The _zmq_bind()_ function shall return zero if successful. Otherwise it shall
return `-1` and set 'errno' to one of the values defined below.
The _zmq_bind()_ function returns zero if successful. Otherwise it returns
`-1` and sets 'errno' to one of the values defined below.
ERRORS
@ -91,5 +98,5 @@ linkzmq:zmq[7]
AUTHORS
-------
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
Martin Lucina <mato@kotelna.sk>.
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.

View File

@ -4,7 +4,7 @@ zmq_connect(3)
NAME
----
zmq_connect - connect a socket
zmq_connect - create outgoing connection from socket
SYNOPSIS
@ -14,42 +14,43 @@ SYNOPSIS
DESCRIPTION
-----------
The _zmq_connect()_ function shall connect the socket referenced by the
'socket' argument to the endpoint specified by the 'endpoint' argument.
The _zmq_connect()_ function connects the 'socket' to an 'endpoint' and then
accepts incoming connections on that endpoint.
The 'endpoint' argument is a string consisting of two parts as follows:
'transport'`://`'address'. The 'transport' part specifies the underlying
transport protocol to use. The meaning of the 'address' part is specific to
the underlying transport protocol selected.
The 'endpoint' is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.
The following transports are defined:
0MQ provides the the following transports:
'inproc':: local in-process (inter-thread) communication transport, see linkzmq:zmq_inproc[7]
'ipc':: local inter-process communication transport, see linkzmq:zmq_ipc[7]
'tcp':: unicast transport using TCP, see linkzmq:zmq_tcp[7]
'ipc':: local inter-process communication transport, see linkzmq:zmq_ipc[7]
'inproc':: local in-process (inter-thread) communication transport, see linkzmq:zmq_inproc[7]
'pgm', 'epgm':: reliable multicast transport using PGM, see linkzmq:zmq_pgm[7]
ZeroMQ sockets support one-to-many and many-to-one semantics. With the exception
of 'ZMQ_PAIR' sockets every ZeroMQ socket type supports being bound with
_zmq_bind()_ as a singular endpoint or connecting with _zmq_connect()_ as one
of many endpoints. This allows combinations such as 1 ZMQ_REP to 100 ZMQ_REP and
100 ZMQ_REQ to 1 ZMQ_REP socket connections. Refer to linkzmq:zmq_socket[3] for
a description of the exact semantics involved when connecting or binding a socket
to multiple endpoints.
Every 0MQ socket type except 'ZMQ_PAIR' supports one-to-many and many-to-one
semantics. The precise semantics depend on the socket type and are defined in
linkzmq:zmq_socket[3].
NOTE: The connection will not be performed immediately but as needed by 0MQ.
Thus a successful invocation of _zmq_connect()_ does not indicate that a
physical connection was or can actually be established. Because of this, for most
socket types the order in which a listening socket is bound and a connecting socket
is connected does not matter. However, for inproc:// scheme sockets, the zmq_bind()
must be executed before any sockets zmq_connect() to that endpoint. Refer to
linkzmq:zmq_inproc[7] for more details.
NOTE: for most transports and socket types the connection is not performed
immediately but as needed by 0MQ. Thus a successful call to _zmq_connect()_
does not mean that the connection was or could actually be established.
Because of this, for most transports and socket types the order in which
a 'server' socket is bound and a 'client' socket is connected to it does not
matter. The first exception is when using the inproc:// transport: you must
call _zmq_bind()_ before calling _zmq_connect()_. The second exception are
_ZMQ_PAIR_ sockets, which do not automatically reconnect to endpoints.
NOTE: following a _zmq_connect()_, the socket enters its normal 'ready' state.
By contrast, following a _zmq_bind()_ alone, the socket enters a 'mute' state
in which the socket blocks or drops messages according to the socket type, as
defined in linkzmq:zmq_socket[3].
RETURN VALUE
------------
The _zmq_connect()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.
The _zmq_connect()_ function returns zero if successful. Otherwise it returns
`-1` and sets 'errno' to one of the values defined below.
ERRORS
@ -93,5 +94,5 @@ linkzmq:zmq[7]
AUTHORS
-------
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
Martin Lucina <mato@kotelna.sk>.
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.

View File

@ -34,6 +34,8 @@ The endpoint supplied is invalid.
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*ENOENT*::
The provided endpoint is not connected.
EXAMPLE

View File

@ -117,6 +117,7 @@ Option value unit:: N/A (bitmap)
Default value:: 0
Applicable socket types:: N/A
ZMQ_IDENTITY: Set socket identity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_IDENTITY' option shall retrieve the identity of the specified 'socket'.
@ -270,7 +271,6 @@ Applicable socket types:: all, only for connection-oriented transports
ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The option shall retrieve limit for the inbound messages. If a peer sends
a message larger than ZMQ_MAXMSGSIZE it is disconnected. Value of -1 means
'no limit'.
@ -284,7 +284,6 @@ Applicable socket types:: all
ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The option shall retrieve time-to-live used for outbound multicast packets.
The default of 1 means that the multicast packets don't leave the local network.
@ -297,7 +296,6 @@ Applicable socket types:: all, when using multicast transports
ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the timeout for recv operation on the socket. If the value is `0`,
_zmq_recv(3)_ will return immediately, with a EAGAIN error if there is no
message to receive. If the value is `-1`, it will block until a message is
@ -313,7 +311,6 @@ Applicable socket types:: all
ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the timeout for send operation on the socket. If the value is `0`,
_zmq_send(3)_ will return immediately, with a EAGAIN error if the message
cannot be sent. If the value is `-1`, it will block until the message is sent.
@ -329,7 +326,6 @@ Applicable socket types:: all
ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the underlying native socket type. A value of `1` will use IPv4
sockets, while the value of `0` will use IPv6 sockets. An IPv6 socket
lets applications connect to and accept connections from both IPv4 and IPv6
@ -342,9 +338,8 @@ Default value:: 1 (true)
Applicable socket types:: all, when using TCP transports.
ZMQ_DELAY_ATTACH_ON_CONNECT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ZMQ_DELAY_ATTACH_ON_CONNECT: Retrieve attach-on-connect value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the state of the attach on connect value. If set to `1`, will delay the
attachment of a pipe on connect until the underlying connection has completed.
This will cause the socket to block if there are no other connections, but will
@ -413,6 +408,7 @@ Option value unit:: N/A (flags)
Default value:: N/A
Applicable socket types:: all
ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_LAST_ENDPOINT' option shall retrieve the last endpoint bound for
@ -426,6 +422,7 @@ Option value unit:: N/A
Default value:: NULL
Applicable socket types:: all, when binding TCP or IPC transports
ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'SO_KEEPALIVE' socket option(where supported by OS).
@ -437,6 +434,7 @@ Option value unit:: -1,0,1
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option(where supported by OS).
@ -448,6 +446,7 @@ Option value unit:: -1,>0
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT' socket option(where supported by OS).
@ -459,6 +458,7 @@ Option value unit:: -1,>0
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPINTVL' socket option(where supported by OS).

View File

@ -20,11 +20,12 @@ linkzmq:zmq_init[3] for details.
ADDRESSING
----------
A 0MQ address string consists of two parts as follows:
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
transport protocol to use, and for the in-process transport shall be set to
`inproc`. The meaning of the 'endpoint' part for the in-process transport is
defined below.
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.
For the in-process transport, the transport is `inproc`, and the meaning of
the 'address' part is defined below.
Assigning a local address to a socket
@ -45,29 +46,24 @@ created by assigning it to at least one 'socket' within the same 0MQ 'context'
as the 'socket' being connected.
WIRE FORMAT
-----------
Not applicable.
EXAMPLES
--------
.Assigning a local address to a socket
----
/* Assign the in-process name "#1" */
// Assign the in-process name "#1"
rc = zmq_bind(socket, "inproc://#1");
assert (rc == 0);
/* Assign the in-process name "my-endpoint" */
// Assign the in-process name "my-endpoint"
rc = zmq_bind(socket, "inproc://my-endpoint");
assert (rc == 0);
----
.Connecting a socket
----
/* Connect to the in-process name "#1" */
// Connect to the in-process name "#1"
rc = zmq_connect(socket, "inproc://#1");
assert (rc == 0);
/* Connect to the in-process name "my-endpoint" */
// Connect to the in-process name "my-endpoint"
rc = zmq_connect(socket, "inproc://my-endpoint");
assert (rc == 0);
----
@ -85,5 +81,5 @@ linkzmq:zmq[7]
AUTHORS
-------
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
Martin Lucina <mato@kotelna.sk>.
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.

View File

@ -18,22 +18,31 @@ systems that provide UNIX domain sockets.
ADDRESSING
----------
A 0MQ address string consists of two parts as follows:
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
transport protocol to use, and for the inter-process transport shall be set to
`ipc`. The meaning of the 'endpoint' part for the inter-process transport is
defined below.
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.
For the inter-process transport, the transport is `ipc`, and the meaning of
the 'address' part is defined below.
Assigning a local address to a socket
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When assigning a local address to a 'socket' using _zmq_bind()_ with the 'ipc'
Binding a socket
~~~~~~~~~~~~~~~~
When binding a 'socket' to a local address using _zmq_bind()_ with the 'ipc'
transport, the 'endpoint' shall be interpreted as an arbitrary string
identifying the 'pathname' to create. The 'pathname' must be unique within the
operating system namespace used by the 'ipc' implementation, and must fulfill
any restrictions placed by the operating system on the format and length of a
'pathname'.
When the address is `*`, _zmq_bind()_ shall generate a unique temporary
pathname. The caller should retrieve this pathname using the ZMQ_LAST_ENDPOINT
socket option. See linkzmq:zmq_getsockopt[3] for details.
NOTE: any existing binding to the same endpoint shall be overridden. In this
behavior, the 'ipc' transport is not consistent with the 'tcp' or 'inproc'
transports.
Connecting a socket
~~~~~~~~~~~~~~~~~~~
When connecting a 'socket' to a peer address using _zmq_connect()_ with the
@ -43,23 +52,18 @@ previously created within the operating system namespace by assigning it to a
'socket' with _zmq_bind()_.
WIRE FORMAT
-----------
Not applicable.
EXAMPLES
--------
.Assigning a local address to a socket
----
/* Assign the pathname "/tmp/feeds/0" */
// Assign the pathname "/tmp/feeds/0"
rc = zmq_bind(socket, "ipc:///tmp/feeds/0");
assert (rc == 0);
----
.Connecting a socket
----
/* Connect to the pathname "/tmp/feeds/0" */
// Connect to the pathname "/tmp/feeds/0"
rc = zmq_connect(socket, "ipc:///tmp/feeds/0");
assert (rc == 0);
----
@ -71,10 +75,11 @@ linkzmq:zmq_connect[3]
linkzmq:zmq_inproc[7]
linkzmq:zmq_tcp[7]
linkzmq:zmq_pgm[7]
linkzmq:zmq_getsockopt[3]
linkzmq:zmq[7]
AUTHORS
-------
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
Martin Lucina <mato@kotelna.sk>.
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.

View File

@ -17,8 +17,8 @@ DESCRIPTION
-----------
0MQ implements two variants of PGM, the standard protocol where PGM datagrams
are layered directly on top of IP datagrams as defined by RFC 3208 (the 'pgm'
transport) and "Encapsulated PGM" where PGM datagrams are encapsulated inside
UDP datagrams (the 'epgm' transport).
transport) and "Encapsulated PGM" or EPGM where PGM datagrams are encapsulated
inside UDP datagrams (the 'epgm' transport).
The 'pgm' and 'epgm' transports can only be used with the 'ZMQ_PUB' and
'ZMQ_SUB' socket types.
@ -36,12 +36,12 @@ not require any special privileges.
ADDRESSING
----------
A 0MQ address string consists of two parts as follows:
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
transport protocol to use. For the standard PGM protocol, 'transport' shall be
set to `pgm`. For the "Encapsulated PGM" protocol 'transport' shall be set to
`epgm`. The meaning of the 'endpoint' part for both the 'pgm' and 'epgm'
transport is defined below.
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.
For the PGM transport, the transport is `pgm`, and for the EPGM protocol the
transport is `epgm`. The meaning of the 'address' part is defined below.
Connecting a socket
@ -134,14 +134,14 @@ EXAMPLE
-------
.Connecting a socket
----
/* Connecting to the multicast address 239.192.1.1, port 5555, */
/* using the first Ethernet network interface on Linux */
/* and the Encapsulated PGM protocol */
// Connecting to the multicast address 239.192.1.1, port 5555,
// using the first Ethernet network interface on Linux
// and the Encapsulated PGM protocol
rc = zmq_connect(socket, "epgm://eth0;239.192.1.1:5555");
assert (rc == 0);
/* Connecting to the multicast address 239.192.1.1, port 5555, */
/* using the network interface with the address 192.168.1.1 */
/* and the standard PGM protocol */
// Connecting to the multicast address 239.192.1.1, port 5555,
// using the network interface with the address 192.168.1.1
// and the standard PGM protocol
rc = zmq_connect(socket, "pgm://192.168.1.1;239.192.1.1:5555");
assert (rc == 0);
----
@ -158,5 +158,5 @@ linkzmq:zmq[7]
AUTHORS
-------
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
Martin Lucina <mato@kotelna.sk>.
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.

View File

@ -26,6 +26,8 @@ Specifies that the operation should be performed in non-blocking mode. If there
are no messages available on the specified 'socket', the _zmq_recvmsg()_
function shall fail with 'errno' set to EAGAIN.
NOTE: this API method is deprecated in favor of zmq_msg_recv(3).
Multi-part messages
~~~~~~~~~~~~~~~~~~~

View File

@ -36,6 +36,7 @@ NOTE: A successful invocation of _zmq_sendmsg()_ does not indicate that the
message has been transmitted to the network, only that it has been queued on
the 'socket' and 0MQ has assumed responsibility for the message.
NOTE: this API method is deprecated in favor of zmq_msg_send(3).
Multi-part messages
~~~~~~~~~~~~~~~~~~~

View File

@ -39,6 +39,10 @@ blocking or dropping sent messages. Refer to the individual socket descriptions
in linkzmq:zmq_socket[3] for details on the exact action taken for each socket
type.
NOTE: 0MQ does not guarantee that the socket will accept as many as ZMQ_SNDHWM
messages, and the actual limit may be as much as 60-70% lower depending on the
flow of messages on the socket.
[horizontal]
Option value type:: int
Option value unit:: messages
@ -371,11 +375,8 @@ ZMQ_ROUTER_MANDATORY: accept only routable messages on ROUTER sockets
Sets the 'ROUTER' socket behavior when an unroutable message is encountered. A
value of `0` is the default and discards the message silently when it cannot be
routed. A value of `1` returns an 'EAGAIN' error code if the message cannot be
routed.
Note: Setting this socket option may have unpredictable effects on reactor-type
libraries that assume EAGAIN will only be sent in HWM-type situations.
routed. A value of `1` returns an 'EHOSTUNREACH' error code if the message
cannot be routed.
[horizontal]
Option value type:: int

View File

@ -58,8 +58,8 @@ general _messaging pattern_ which is built from related socket types.
Request-reply pattern
~~~~~~~~~~~~~~~~~~~~~
The request-reply pattern is used for sending requests from a _client_ to one
or more instances of a _service_, and receiving subsequent replies to each
The request-reply pattern is used for sending requests from a ZMQ_REQ _client_
to one or more ZMQ_REP _services_, and receiving subsequent replies to each
request sent.
@ -71,10 +71,10 @@ sequence of _zmq_send(request)_ and subsequent _zmq_recv(reply)_ calls. Each
request sent is round-robined among all _services_, and each reply received is
matched with the last issued request.
When a 'ZMQ_REQ' socket enters an exceptional state due to having reached the
When a 'ZMQ_REQ' socket enters the 'mute' state due to having reached the
high water mark for all _services_, or if there are no _services_ at all, then
any linkzmq:zmq_send[3] operations on the socket shall block until the
exceptional state ends or at least one _service_ becomes available for sending;
'mute' state ends or at least one _service_ becomes available for sending;
messages are not discarded.
[horizontal]
@ -84,7 +84,7 @@ Direction:: Bidirectional
Send/receive pattern:: Send, Receive, Send, Receive, ...
Outgoing routing strategy:: Round-robin
Incoming routing strategy:: Last peer
ZMQ_HWM option action:: Block
Action in mute state:: Block
ZMQ_REP
@ -96,9 +96,9 @@ request received is fair-queued from among all _clients_, and each reply sent
is routed to the _client_ that issued the last request. If the original
requester doesn't exist any more the reply is silently discarded.
When a 'ZMQ_REP' socket enters an exceptional state due to having reached the
When a 'ZMQ_REP' socket enters the 'mute' state due to having reached the
high water mark for a _client_, then any replies sent to the _client_ in
question shall be dropped until the exceptional state ends.
question shall be dropped until the mute state ends.
[horizontal]
.Summary of ZMQ_REP characteristics
@ -107,7 +107,7 @@ Direction:: Bidirectional
Send/receive pattern:: Receive, Send, Receive, Send, ...
Incoming routing strategy:: Fair-queued
Outgoing routing strategy:: Last peer
ZMQ_HWM option action:: Drop
Action in mute state:: Drop
ZMQ_DEALER
@ -116,9 +116,9 @@ A socket of type 'ZMQ_DEALER' is an advanced pattern used for extending
request/reply sockets. Each message sent is round-robined among all connected
peers, and each message received is fair-queued from all connected peers.
When a 'ZMQ_DEALER' socket enters an exceptional state due to having reached the
When a 'ZMQ_DEALER' socket enters the 'mute' state due to having reached the
high water mark for all peers, or if there are no peers at all, then any
linkzmq:zmq_send[3] operations on the socket shall block until the exceptional
linkzmq:zmq_send[3] operations on the socket shall block until the mute
state ends or at least one peer becomes available for sending; messages are not
discarded.
@ -130,12 +130,12 @@ Deprecated alias: 'ZMQ_XREQ'.
[horizontal]
.Summary of ZMQ_DEALER characteristics
Compatible peer sockets:: 'ZMQ_ROUTER', 'ZMQ_REP'
Compatible peer sockets:: 'ZMQ_ROUTER', 'ZMQ_REP', 'ZMQ_DEALER'
Direction:: Bidirectional
Send/receive pattern:: Unrestricted
Outgoing routing strategy:: Round-robin
Incoming routing strategy:: Fair-queued
ZMQ_HWM option action:: Block
Action in mute state:: Block
ZMQ_ROUTER
@ -150,9 +150,9 @@ the peer the message shall be routed to. If the peer does not exist anymore
the message shall be silently discarded by default, unless 'ZMQ_ROUTER_BEHAVIOR'
socket option is set to '1'.
When a 'ZMQ_ROUTER' socket enters an exceptional state due to having reached the
When a 'ZMQ_ROUTER' socket enters the 'mute' state due to having reached the
high water mark for all peers, then any messages sent to the socket shall be dropped
until the exceptional state ends. Likewise, any messages routed to a peer for which
until the mute state ends. Likewise, any messages routed to a peer for which
the individual high water mark has been reached shall also be dropped.
When a 'ZMQ_REQ' socket is connected to a 'ZMQ_ROUTER' socket, in addition to the
@ -166,12 +166,12 @@ Deprecated alias: 'ZMQ_XREP'.
[horizontal]
.Summary of ZMQ_ROUTER characteristics
Compatible peer sockets:: 'ZMQ_DEALER', 'ZMQ_REQ'
Compatible peer sockets:: 'ZMQ_DEALER', 'ZMQ_REQ', 'ZMQ_ROUTER'
Direction:: Bidirectional
Send/receive pattern:: Unrestricted
Outgoing routing strategy:: See text
Incoming routing strategy:: Fair-queued
ZMQ_HWM option action:: Drop
Action in mute state:: Drop
Publish-subscribe pattern
@ -186,9 +186,9 @@ A socket of type 'ZMQ_PUB' is used by a _publisher_ to distribute data.
Messages sent are distributed in a fan out fashion to all connected peers.
The linkzmq:zmq_recv[3] function is not implemented for this socket type.
When a 'ZMQ_PUB' socket enters an exceptional state due to having reached the
When a 'ZMQ_PUB' socket enters the 'mute' state due to having reached the
high water mark for a _subscriber_, then any messages that would be sent to the
_subscriber_ in question shall instead be dropped until the exceptional state
_subscriber_ in question shall instead be dropped until the mute state
ends. The _zmq_send()_ function shall never block for this socket type.
[horizontal]
@ -198,7 +198,7 @@ Direction:: Unidirectional
Send/receive pattern:: Send only
Incoming routing strategy:: N/A
Outgoing routing strategy:: Fan out
ZMQ_HWM option action:: Drop
Action in mute state:: Drop
ZMQ_SUB
@ -216,7 +216,7 @@ Direction:: Unidirectional
Send/receive pattern:: Receive only
Incoming routing strategy:: Fair-queued
Outgoing routing strategy:: N/A
ZMQ_HWM option action:: Drop
Action in mute state:: Drop
ZMQ_XPUB
@ -233,7 +233,7 @@ Direction:: Unidirectional
Send/receive pattern:: Send messages, receive subscriptions
Incoming routing strategy:: N/A
Outgoing routing strategy:: Fan out
ZMQ_HWM option action:: Drop
Action in mute state:: Drop
ZMQ_XSUB
@ -249,7 +249,7 @@ Direction:: Unidirectional
Send/receive pattern:: Receive messages, send subscriptions
Incoming routing strategy:: Fair-queued
Outgoing routing strategy:: N/A
ZMQ_HWM option action:: Drop
Action in mute state:: Drop
Pipeline pattern
@ -267,10 +267,10 @@ to downstream pipeline _nodes_. Messages are round-robined to all connected
downstream _nodes_. The _zmq_recv()_ function is not implemented for this
socket type.
When a 'ZMQ_PUSH' socket enters an exceptional state due to having reached the
When a 'ZMQ_PUSH' socket enters the 'mute' state due to having reached the
high water mark for all downstream _nodes_, or if there are no downstream
_nodes_ at all, then any linkzmq:zmq_send[3] operations on the socket shall
block until the exceptional state ends or at least one downstream _node_
block until the mute state ends or at least one downstream _node_
becomes available for sending; messages are not discarded.
[horizontal]
@ -280,7 +280,7 @@ Direction:: Unidirectional
Send/receive pattern:: Send only
Incoming routing strategy:: N/A
Outgoing routing strategy:: Round-robin
ZMQ_HWM option action:: Block
Action in mute state:: Block
ZMQ_PULL
@ -297,7 +297,7 @@ Direction:: Unidirectional
Send/receive pattern:: Receive only
Incoming routing strategy:: Fair-queued
Outgoing routing strategy:: N/A
ZMQ_HWM option action:: Block
Action in mute state:: Block
Exclusive pair pattern
@ -313,7 +313,7 @@ A socket of type 'ZMQ_PAIR' can only be connected to a single peer at any one
time. No message routing or filtering is performed on messages sent over a
'ZMQ_PAIR' socket.
When a 'ZMQ_PAIR' socket enters an exceptional state due to having reached the
When a 'ZMQ_PAIR' socket enters the 'mute' state due to having reached the
high water mark for the connected peer, or if no peer is connected, then
any linkzmq:zmq_send[3] operations on the socket shall block until the peer
becomes available for sending; messages are not discarded.
@ -330,7 +330,7 @@ Direction:: Bidirectional
Send/receive pattern:: Unrestricted
Incoming routing strategy:: N/A
Outgoing routing strategy:: N/A
ZMQ_HWM option action:: Block
Action in mute state:: Block
RETURN VALUE

View File

@ -16,10 +16,12 @@ your first choice.
ADDRESSING
----------
A 0MQ address string consists of two parts as follows:
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
transport protocol to use, and for the TCP transport shall be set to `tcp`.
The meaning of the 'endpoint' part for the TCP transport is defined below.
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.
For the TCP transport, the transport is `tcp`, and the meaning of the
'address' part is defined below.
Assigning a local address to a socket
@ -33,12 +35,17 @@ An 'interface' may be specified by either of the following:
* The wild-card `*`, meaning all available interfaces.
* The primary IPv4 or IPv6 address assigned to the interface, in its numeric
representation.
* The interface name as defined by the operating system.
* The non-portable interface name as defined by the operating system.
The TCP port number may be specified by:
* A numeric value, usually above 1024 on POSIX systems.
* The wild-card `*`, meaning a system-assigned ephemeral port.
When using ephemeral ports, the caller should retrieve the actual assigned
port using the ZMQ_LAST_ENDPOINT socket option. See linkzmq:zmq_getsockopt[3]
for details.
NOTE: Interface names are not standardised in any way and should be assumed to
be arbitrary and platform dependent. On Win32 platforms no short interface
names exist, thus only the primary IP address may be used to specify an
'interface'.
Connecting a socket
~~~~~~~~~~~~~~~~~~~
@ -49,98 +56,30 @@ a colon and the TCP port number to use.
A 'peer address' may be specified by either of the following:
* The DNS name of the peer.
* The IPv4 or IPv6 address of the peer, in it's numeric representation.
WIRE FORMAT
-----------
0MQ messages are transmitted over TCP in frames consisting of an encoded
'payload length', followed by a 'flags' field and the message body. The 'payload
length' is defined as the combined length in octets of the message body and the
'flags' field.
For frames with a 'payload length' not exceeding 254 octets, the 'payload
length' shall be encoded as a single octet. The minimum valid 'payload length'
of a frame is 1 octet, thus a 'payload length' of 0 octets is invalid and such
frames SHOULD be ignored.
For frames with a 'payload length' exceeding 254 octets, the 'payload length'
shall be encoded as a single octet with the value `255` followed by the
'payload length' represented as a 64-bit unsigned integer in network byte
order.
The 'flags' field consists of a single octet containing various control flags:
Bit 0 (MORE): _More message parts to follow_. A value of 0 indicates that there
are no more message parts to follow; or that the message being sent is not a
multi-part message. A value of 1 indicates that the message being sent is a
multi-part message and more message parts are to follow.
Bits 1-7: _Reserved_. Bits 1-7 are reserved for future expansion and MUST be
set to zero.
The following ABNF grammar represents a single 'frame':
....
frame = (length flags data)
length = OCTET / (escape 8OCTET)
flags = OCTET
escape = %xFF
data = *OCTET
....
The following diagram illustrates the layout of a frame with a 'payload length'
not exceeding 254 octets:
....
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload length| Flags | Message body ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message body ...
+-+-+-+-+-+-+- ...
....
The following diagram illustrates the layout of a frame with a 'payload length'
exceeding 254 octets:
....
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0xff | Payload length ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload length ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload length| Flags | Message body ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message body ...
+-+-+-+-+-+-+-+ ...
....
* The IPv4 or IPv6 address of the peer, in its numeric representation.
EXAMPLES
--------
.Assigning a local address to a socket
----
/* TCP port 5555 on all available interfaces */
rc = zmq_bind(socket, "tcp://*:5555");
// TCP port 5555 on all available interfaces
rc = zmq_bind(socket, "tcp:/// :5555");
assert (rc == 0);
/* TCP port 5555 on the local loop-back interface on all platforms */
// TCP port 5555 on the local loop-back interface on all platforms
rc = zmq_bind(socket, "tcp://127.0.0.1:5555");
assert (rc == 0);
/* TCP port 5555 on the first Ethernet network interface on Linux */
// TCP port 5555 on the first Ethernet network interface on Linux
rc = zmq_bind(socket, "tcp://eth0:5555");
assert (rc == 0);
----
.Connecting a socket
----
/* Connecting using an IP address */
// Connecting using an IP address
rc = zmq_connect(socket, "tcp://192.168.1.1:5555");
assert (rc == 0);
/* Connecting using a DNS name */
// Connecting using a DNS name
rc = zmq_connect(socket, "tcp://server1:5555");
assert (rc == 0);
----
@ -158,5 +97,5 @@ linkzmq:zmq[7]
AUTHORS
-------
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
Martin Lucina <mato@kotelna.sk>.
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.

View File

@ -60,7 +60,7 @@ extern "C" {
/* Version macros for compile-time API version detection */
#define ZMQ_VERSION_MAJOR 3
#define ZMQ_VERSION_MINOR 2
#define ZMQ_VERSION_PATCH 1
#define ZMQ_VERSION_PATCH 4
#define ZMQ_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch))
@ -261,6 +261,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
/* Deprecated aliases */
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY
#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY
/******************************************************************************/
@ -380,15 +381,15 @@ typedef struct
ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
// Built-in message proxy (3-way)
/* Built-in message proxy (3-way) */
ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture);
// Deprecated aliases
/* Deprecated aliases */
#define ZMQ_STREAMER 1
#define ZMQ_FORWARDER 2
#define ZMQ_QUEUE 3
// Deprecated method
/* Deprecated method */
ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend);
#undef ZMQ_EXPORT

View File

@ -23,6 +23,12 @@ libzmq_la_SOURCES = \
err.hpp \
fd.hpp \
fq.hpp \
i_encoder.hpp \
i_decoder.hpp \
i_engine.hpp \
i_msg_sink.hpp \
i_msg_source.hpp \
i_poll_events.hpp \
io_object.hpp \
io_thread.hpp \
ip.hpp \
@ -134,7 +140,10 @@ libzmq_la_SOURCES = \
router.cpp \
dealer.cpp \
v1_decoder.cpp \
v1_decoder.hpp \
v1_encoder.cpp \
v1_encoder.hpp \
v1_protocol.hpp \
xsub.cpp \
zmq.cpp \
zmq_utils.cpp

View File

@ -57,11 +57,6 @@ void zmq::decoder_t::set_msg_sink (i_msg_sink *msg_sink_)
msg_sink = msg_sink_;
}
bool zmq::decoder_t::stalled () const
{
return next == &decoder_t::message_ready;
}
bool zmq::decoder_t::one_byte_size_ready ()
{
// First byte of size is read. If it is 0xff read 8-byte size.

View File

@ -35,8 +35,6 @@
namespace zmq
{
class i_msg_sink;
// Helper base class for decoders that know the amount of data to read
// in advance at any moment. Knowing the amount in advance is a property
// of the protocol used. 0MQ framing protocol is based size-prefixed
@ -143,6 +141,32 @@ namespace zmq
}
}
// Returns true if the decoder has been fed all required data
// but cannot proceed with the next decoding step.
// False is returned if the decoder has encountered an error.
bool stalled ()
{
// Check whether there was decoding error.
if (unlikely (!(static_cast <T*> (this)->next)))
return false;
while (!to_read) {
if (!(static_cast <T*> (this)->*next) ()) {
if (unlikely (!(static_cast <T*> (this)->next)))
return false;
return true;
}
}
return false;
}
inline bool message_ready_size (size_t msg_sz)
{
zmq_assert (false);
return false;
}
protected:
// Prototype of state machine action. Action should return false if
@ -166,13 +190,13 @@ namespace zmq
next = NULL;
}
private:
// Next step. If set to NULL, it means that associated data stream
// is dead. Note that there can be still data in the process in such
// case.
step_t next;
private:
// Where to store the read data.
unsigned char *read_pos;
@ -199,10 +223,6 @@ namespace zmq
// Set the receiver of decoded messages.
void set_msg_sink (i_msg_sink *msg_sink_);
// Returns true if there is a decoded message
// waiting to be delivered to the session.
bool stalled () const;
private:
bool one_byte_size_ready ();

13
src/dist.cpp Normal file → Executable file
View File

@ -80,12 +80,19 @@ void zmq::dist_t::terminated (pipe_t *pipe_)
{
// Remove the pipe from the list; adjust number of matching, active and/or
// eligible pipes accordingly.
if (pipes.index (pipe_) < matching)
if (pipes.index (pipe_) < matching) {
pipes.swap (pipes.index (pipe_), matching - 1);
matching--;
if (pipes.index (pipe_) < active)
}
if (pipes.index (pipe_) < active) {
pipes.swap (pipes.index (pipe_), active - 1);
active--;
if (pipes.index (pipe_) < eligible)
}
if (pipes.index (pipe_) < eligible) {
pipes.swap (pipes.index (pipe_), eligible - 1);
eligible--;
}
pipes.erase (pipe_);
}

View File

@ -40,8 +40,6 @@
namespace zmq
{
class i_msg_source;
// Helper base class for encoders. It implements the state machine that
// fills the outgoing buffer. Derived classes should implement individual
// state machine actions.
@ -126,6 +124,11 @@ namespace zmq
*size_ = pos;
}
inline bool has_data ()
{
return to_write > 0;
}
protected:
// Prototype of state machine action.

View File

@ -140,9 +140,10 @@ void zmq::epoll_t::loop ()
// Wait for events.
int n = epoll_wait (epoll_fd, &ev_buf [0], max_io_events,
timeout ? timeout : -1);
if (n == -1 && errno == EINTR)
if (n == -1) {
errno_assert (errno == EINTR);
continue;
errno_assert (n != -1);
}
for (int i = 0; i < n; i ++) {
poll_entry_t *pe = ((poll_entry_t*) ev_buf [i].data.ptr);

View File

@ -26,7 +26,8 @@
namespace zmq
{
class i_msg_sink;
// Forward declaration
struct i_msg_sink;
// Interface to be implemented by message decoder.
@ -40,7 +41,7 @@ namespace zmq
virtual size_t process_buffer (unsigned char *data_, size_t size_) = 0;
virtual bool stalled () const = 0;
virtual bool stalled () = 0;
};

View File

@ -27,7 +27,7 @@ namespace zmq
{
// Forward declaration
class i_msg_source;
struct i_msg_source;
// Interface to be implemented by message encoder.
@ -47,6 +47,7 @@ namespace zmq
virtual void get_data (unsigned char **data_, size_t *size_,
int *offset_ = NULL) = 0;
virtual bool has_data () = 0;
};
}

View File

@ -122,7 +122,7 @@ void zmq::ipc_connecter_t::out_event ()
// Shut the connecter down.
terminate ();
socket->event_connected (endpoint.c_str(), fd);
socket->event_connected (endpoint, fd);
}
void zmq::ipc_connecter_t::timer_event (int id_)
@ -145,11 +145,12 @@ void zmq::ipc_connecter_t::start_connecting ()
}
// Connection establishment may be delayed. Poll for its completion.
else if (rc == -1 && errno == EINPROGRESS) {
else
if (rc == -1 && errno == EINPROGRESS) {
handle = add_fd (s);
handle_valid = true;
set_pollout (handle);
socket->event_connect_delayed (endpoint.c_str(), zmq_errno());
socket->event_connect_delayed (endpoint, zmq_errno());
}
// Handle any other error condition by eventual reconnect.
@ -164,7 +165,7 @@ void zmq::ipc_connecter_t::add_reconnect_timer()
{
int rc_ivl = get_new_reconnect_ivl();
add_timer (rc_ivl, reconnect_timer_id);
socket->event_connect_retried (endpoint.c_str(), rc_ivl);
socket->event_connect_retried (endpoint, rc_ivl);
timer_started = true;
}
@ -225,7 +226,7 @@ int zmq::ipc_connecter_t::close ()
zmq_assert (s != retired_fd);
int rc = ::close (s);
errno_assert (rc == 0);
socket->event_closed (endpoint.c_str(), s);
socket->event_closed (endpoint, s);
s = retired_fd;
return 0;
}

View File

@ -76,7 +76,7 @@ void zmq::ipc_listener_t::in_event ()
// If connection was reset by the peer in the meantime, just ignore it.
// TODO: Handle specific errors like ENFILE/EMFILE etc.
if (fd == retired_fd) {
socket->event_accept_failed (endpoint.c_str(), zmq_errno());
socket->event_accept_failed (endpoint, zmq_errno());
return;
}
@ -96,7 +96,7 @@ void zmq::ipc_listener_t::in_event ()
session->inc_seqnum ();
launch_child (session);
send_attach (session, engine, false);
socket->event_accepted (endpoint.c_str(), fd);
socket->event_accepted (endpoint, fd);
}
int zmq::ipc_listener_t::get_address (std::string &addr_)
@ -155,7 +155,7 @@ int zmq::ipc_listener_t::set_address (const char *addr_)
if (rc != 0)
goto error;
socket->event_listening (endpoint.c_str(), s);
socket->event_listening (endpoint, s);
return 0;
error:
@ -178,12 +178,12 @@ int zmq::ipc_listener_t::close ()
if (has_file && !filename.empty ()) {
rc = ::unlink(filename.c_str ());
if (rc != 0) {
socket->event_close_failed (endpoint.c_str(), zmq_errno());
socket->event_close_failed (endpoint, zmq_errno());
return -1;
}
}
socket->event_closed (endpoint.c_str(), s);
socket->event_closed (endpoint, s);
return 0;
}

View File

@ -163,9 +163,10 @@ void zmq::kqueue_t::loop ()
timespec ts = {timeout / 1000, (timeout % 1000) * 1000000};
int n = kevent (kqueue_fd, NULL, 0, &ev_buf [0], max_io_events,
timeout ? &ts: NULL);
if (n == -1 && errno == EINTR)
if (n == -1) {
errno_assert (errno == EINTR);
continue;
errno_assert (n != -1);
}
for (int i = 0; i < n; i ++) {
poll_entry_t *pe = (poll_entry_t*) ev_buf [i].udata;

View File

@ -35,6 +35,11 @@ zmq::mailbox_t::mailbox_t ()
zmq::mailbox_t::~mailbox_t ()
{
// TODO: Retrieve and deallocate commands inside the cpipe.
// Work around problem that other threads might still be in our
// send() method, by waiting on the mutex before disappearing.
sync.lock ();
sync.unlock ();
}
zmq::fd_t zmq::mailbox_t::get_fd ()

View File

@ -283,7 +283,14 @@ bool zmq::msg_t::rm_refs (int refs_)
// The only message type that needs special care are long messages.
if (!u.lmsg.content->refcnt.sub (refs_)) {
close ();
// We used "placement new" operator to initialize the reference
// counter so we call the destructor explicitly now.
u.lmsg.content->refcnt.~atomic_counter_t ();
if (u.lmsg.content->ffn)
u.lmsg.content->ffn (u.lmsg.content->data, u.lmsg.content->hint);
free (u.lmsg.content);
return false;
}

View File

@ -338,10 +338,11 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
goto err_abort;
// Expedited Forwarding PHB for network elements, no ECN.
// Ignore return value due to varied runtime support.
const int dscp = 0x2e << 2;
if (AF_INET6 != sa_family && !pgm_setsockopt (sock,
IPPROTO_PGM, PGM_TOS, &dscp, sizeof (dscp)))
goto err_abort;
if (AF_INET6 != sa_family)
pgm_setsockopt (sock, IPPROTO_PGM, PGM_TOS,
&dscp, sizeof (dscp));
const int nonblocking = 1;
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NOBLOCK,

View File

@ -125,10 +125,10 @@ void zmq::poll_t::loop ()
// Wait for events.
int rc = poll (&pollset [0], pollset.size (), timeout ? timeout : -1);
if (rc == -1 && errno == EINTR)
if (rc == -1) {
errno_assert (errno == EINTR);
continue;
errno_assert (rc != -1);
}
// If there are no events (i.e. it's a timeout) there's no point
// in checking the pollset.

View File

@ -19,13 +19,42 @@
*/
#include <stddef.h>
#include "../include/zmq.h"
#include "platform.hpp"
#include "proxy.hpp"
#include "socket_base.hpp"
#include "likely.hpp"
#if defined ZMQ_FORCE_SELECT
#define ZMQ_POLL_BASED_ON_SELECT
#elif defined ZMQ_FORCE_POLL
#define ZMQ_POLL_BASED_ON_POLL
#elif defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD ||\
defined ZMQ_HAVE_OPENBSD || defined ZMQ_HAVE_SOLARIS ||\
defined ZMQ_HAVE_OSX || defined ZMQ_HAVE_QNXNTO ||\
defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_AIX ||\
defined ZMQ_HAVE_NETBSD
#define ZMQ_POLL_BASED_ON_POLL
#elif defined ZMQ_HAVE_WINDOWS || defined ZMQ_HAVE_OPENVMS ||\
defined ZMQ_HAVE_CYGWIN
#define ZMQ_POLL_BASED_ON_SELECT
#endif
// On AIX platform, poll.h has to be included first to get consistent
// definition of pollfd structure (AIX uses 'reqevents' and 'retnevents'
// instead of 'events' and 'revents' and defines macros to map from POSIX-y
// names to AIX-specific names).
#if defined ZMQ_POLL_BASED_ON_POLL
#include <poll.h>
#endif
// These headers end up pulling in zmq.h somewhere in their include
// dependency chain
#include "socket_base.hpp"
#include "err.hpp"
// zmq.h must be included *after* poll.h for AIX to build properly
#include "../include/zmq.h"
int zmq::proxy (
class socket_base_t *frontend_,
class socket_base_t *backend_,

View File

@ -162,7 +162,7 @@ int zmq::router_t::xsend (msg_t *msg_, int flags_)
else
if (mandatory) {
more_out = false;
errno = EAGAIN;
errno = EHOSTUNREACH;
return -1;
}
}

View File

@ -168,9 +168,10 @@ void zmq::select_t::loop ()
#else
int rc = select (maxfd + 1, &readfds, &writefds, &exceptfds,
timeout ? &tv : NULL);
if (rc == -1 && errno == EINTR)
if (rc == -1) {
errno_assert (errno == EINTR);
continue;
errno_assert (rc != -1);
}
#endif
// If there are no events (i.e. it's a timeout) there's no point

View File

@ -223,7 +223,7 @@ void zmq::session_base_t::clean_pipes ()
msg_t msg;
int rc = msg.init ();
errno_assert (rc == 0);
if (!pull_msg (&msg)) {
if (pull_msg (&msg) != 0) {
zmq_assert (!incomplete_in);
break;
}

View File

@ -95,7 +95,11 @@ zmq::signaler_t::~signaler_t ()
int rc = close (r);
errno_assert (rc == 0);
#elif defined ZMQ_HAVE_WINDOWS
int rc = closesocket (w);
struct linger so_linger = { 1, 0 };
int rc = setsockopt (w, SOL_SOCKET, SO_LINGER,
(char *)&so_linger, sizeof (so_linger));
wsa_assert (rc != SOCKET_ERROR);
rc = closesocket (w);
wsa_assert (rc != SOCKET_ERROR);
rc = closesocket (r);
wsa_assert (rc != SOCKET_ERROR);
@ -279,7 +283,7 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
(char *)&tcp_nodelay, sizeof (tcp_nodelay));
wsa_assert (rc != SOCKET_ERROR);
// Bind listening socket to any free local port.
// Bind listening socket to signaler port.
struct sockaddr_in addr;
memset (&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
@ -307,15 +311,19 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
// Connect writer to the listener.
rc = connect (*w_, (struct sockaddr*) &addr, sizeof (addr));
wsa_assert (rc != SOCKET_ERROR);
// Save errno if connection fails
int conn_errno = 0;
if (rc == SOCKET_ERROR) {
conn_errno = WSAGetLastError ();
} else {
// Accept connection from writer.
*r_ = accept (listener, NULL, NULL);
wsa_assert (*r_ != INVALID_SOCKET);
// On Windows, preventing sockets to be inherited by child processes.
brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0);
win_assert (brc);
if (*r_ == INVALID_SOCKET) {
conn_errno = WSAGetLastError ();
}
}
// We don't need the listening socket anymore. Close it.
rc = closesocket (listener);
@ -325,7 +333,33 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
brc = SetEvent (sync);
win_assert (brc != 0);
// Release the kernel object
brc = CloseHandle (sync);
win_assert (brc != 0);
if (*r_ != INVALID_SOCKET) {
// On Windows, preventing sockets to be inherited by child processes.
brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0);
win_assert (brc);
return 0;
} else {
// Cleanup writer if connection failed
rc = closesocket (*w_);
wsa_assert (rc != SOCKET_ERROR);
*w_ = INVALID_SOCKET;
// Set errno from saved value
errno = wsa_error_to_errno (conn_errno);
// Ideally, we would return errno to the caller signaler_t()
// Unfortunately, it uses errno_assert() which gives "Unknown error"
// We might as well assert here and print the actual error message
wsa_assert_no (conn_errno);
return -1;
}
#elif defined ZMQ_HAVE_OPENVMS

View File

@ -357,7 +357,7 @@ int zmq::socket_base_t::bind (const char *addr_)
int rc = listener->set_address (address.c_str ());
if (rc != 0) {
delete listener;
event_bind_failed (addr_, zmq_errno());
event_bind_failed (address, zmq_errno());
return -1;
}
@ -376,7 +376,7 @@ int zmq::socket_base_t::bind (const char *addr_)
int rc = listener->set_address (address.c_str ());
if (rc != 0) {
delete listener;
event_bind_failed (addr_, zmq_errno());
event_bind_failed (address, zmq_errno());
return -1;
}
@ -428,15 +428,11 @@ int zmq::socket_base_t::connect (const char *addr_)
// The total HWM for an inproc connection should be the sum of
// the binder's HWM and the connector's HWM.
int sndhwm;
int rcvhwm;
if (options.sndhwm == 0 || peer.options.rcvhwm == 0)
sndhwm = 0;
else
int sndhwm = 0;
if (options.sndhwm != 0 && peer.options.rcvhwm != 0)
sndhwm = options.sndhwm + peer.options.rcvhwm;
if (options.rcvhwm == 0 || peer.options.sndhwm == 0)
rcvhwm = 0;
else
int rcvhwm = 0;
if (options.rcvhwm != 0 && peer.options.sndhwm != 0)
rcvhwm = options.rcvhwm + peer.options.sndhwm;
// Create a bi-directional pipe to connect the peers.
@ -482,6 +478,9 @@ int zmq::socket_base_t::connect (const char *addr_)
// Save last endpoint URI
options.last_endpoint.assign (addr_);
// remember inproc connections for disconnect
inprocs.insert (inprocs_t::value_type (std::string (addr_), pipes[0]));
return 0;
}
@ -507,7 +506,8 @@ int zmq::socket_base_t::connect (const char *addr_)
}
}
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
else if(protocol == "ipc") {
else
if (protocol == "ipc") {
paddr->resolved.ipc_addr = new (std::nothrow) ipc_address_t ();
alloc_assert (paddr->resolved.ipc_addr);
int rc = paddr->resolved.ipc_addr->resolve (address.c_str ());
@ -587,10 +587,38 @@ int zmq::socket_base_t::term_endpoint (const char *addr_)
if (unlikely (rc != 0))
return -1;
// Parse addr_ string.
std::string protocol;
std::string address;
rc = parse_uri (addr_, protocol, address);
if (rc != 0)
return -1;
rc = check_protocol (protocol);
if (rc != 0)
return -1;
// Disconnect an inproc socket
if (protocol == "inproc") {
std::pair <inprocs_t::iterator, inprocs_t::iterator> range = inprocs.equal_range (std::string (addr_));
if (range.first == range.second) {
errno = ENOENT;
return -1;
}
for (inprocs_t::iterator it = range.first; it != range.second; ++it)
it->second->terminate(true);
inprocs.erase (range.first, range.second);
return 0;
}
// Find the endpoints range (if any) corresponding to the addr_ string.
std::pair <endpoints_t::iterator, endpoints_t::iterator> range = endpoints.equal_range (std::string (addr_));
if (range.first == range.second)
if (range.first == range.second) {
errno = ENOENT;
return -1;
}
for (endpoints_t::iterator it = range.first; it != range.second; ++it)
term_child (it->second);
@ -677,11 +705,6 @@ int zmq::socket_base_t::recv (msg_t *msg_, int flags_)
return -1;
}
// Get the message.
int rc = xrecv (msg_, flags_);
if (unlikely (rc != 0 && errno != EAGAIN))
return -1;
// Once every inbound_poll_rate messages check for signals and process
// incoming commands. This happens only if we are not polling altogether
// because there are messages available all the time. If poll occurs,
@ -696,6 +719,11 @@ int zmq::socket_base_t::recv (msg_t *msg_, int flags_)
ticks = 0;
}
// Get the message.
int rc = xrecv (msg_, flags_);
if (unlikely (rc != 0 && errno != EAGAIN))
return -1;
// If we have the message, return immediately.
if (rc == 0) {
extract_flags (msg_);
@ -983,6 +1011,14 @@ void zmq::socket_base_t::terminated (pipe_t *pipe_)
// Notify the specific socket type about the pipe termination.
xterminated (pipe_);
// Remove pipe from inproc pipes
for (inprocs_t::iterator it = inprocs.begin(); it != inprocs.end(); ++it) {
if (it->second == pipe_) {
inprocs.erase(it);
break;
}
}
// Remove the pipe from the list of attached pipes and confirm its
// termination if we are already shutting down.
pipes.erase (pipe_);
@ -1033,7 +1069,6 @@ int zmq::socket_base_t::monitor (const char *addr_, int events_)
// Register events to monitor
monitor_events = events_;
monitor_socket = zmq_socket (get_ctx (), ZMQ_PAIR);
if (monitor_socket == NULL)
return -1;
@ -1051,115 +1086,145 @@ int zmq::socket_base_t::monitor (const char *addr_, int events_)
return rc;
}
void zmq::socket_base_t::event_connected (const char *addr_, int fd_)
void zmq::socket_base_t::event_connected (std::string &addr_, int fd_)
{
if (monitor_events & ZMQ_EVENT_CONNECTED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_CONNECTED)) return;
event.event = ZMQ_EVENT_CONNECTED;
event.data.connected.addr = (char *)addr_;
event.data.connected.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.connected.addr, addr_);
event.data.connected.fd = fd_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_connect_delayed (const char *addr_, int err_)
void zmq::socket_base_t::event_connect_delayed (std::string &addr_, int err_)
{
if (monitor_events & ZMQ_EVENT_CONNECT_DELAYED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_CONNECT_DELAYED)) return;
event.event = ZMQ_EVENT_CONNECT_DELAYED;
event.data.connected.addr = (char *)addr_;
event.data.connect_delayed.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.connect_delayed.addr, addr_);
event.data.connect_delayed.err = err_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_connect_retried (const char *addr_, int interval_)
void zmq::socket_base_t::event_connect_retried (std::string &addr_, int interval_)
{
if (monitor_events & ZMQ_EVENT_CONNECT_RETRIED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_CONNECT_RETRIED)) return;
event.event = ZMQ_EVENT_CONNECT_RETRIED;
event.data.connected.addr = (char *)addr_;
event.data.connect_retried.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.connect_retried.addr, addr_);
event.data.connect_retried.interval = interval_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_listening (const char *addr_, int fd_)
void zmq::socket_base_t::event_listening (std::string &addr_, int fd_)
{
if (monitor_events & ZMQ_EVENT_LISTENING) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_LISTENING)) return;
event.event = ZMQ_EVENT_LISTENING;
event.data.connected.addr = (char *)addr_;
event.data.listening.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.listening.addr, addr_);
event.data.listening.fd = fd_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_bind_failed (const char *addr_, int err_)
void zmq::socket_base_t::event_bind_failed (std::string &addr_, int err_)
{
if (monitor_events & ZMQ_EVENT_BIND_FAILED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_BIND_FAILED)) return;
event.event = ZMQ_EVENT_BIND_FAILED;
event.data.connected.addr = (char *)addr_;
event.data.bind_failed.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.bind_failed.addr, addr_);
event.data.bind_failed.err = err_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_accepted (const char *addr_, int fd_)
void zmq::socket_base_t::event_accepted (std::string &addr_, int fd_)
{
if (monitor_events & ZMQ_EVENT_ACCEPTED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_ACCEPTED)) return;
event.event = ZMQ_EVENT_ACCEPTED;
event.data.connected.addr = (char *)addr_;
event.data.accepted.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.accepted.addr, addr_);
event.data.accepted.fd = fd_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_accept_failed (const char *addr_, int err_)
void zmq::socket_base_t::event_accept_failed (std::string &addr_, int err_)
{
if (monitor_events & ZMQ_EVENT_ACCEPT_FAILED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_ACCEPT_FAILED)) return;
event.event = ZMQ_EVENT_ACCEPT_FAILED;
event.data.connected.addr = (char *)addr_;
event.data.accept_failed.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.accept_failed.addr, addr_);
event.data.accept_failed.err= err_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_closed (const char *addr_, int fd_)
void zmq::socket_base_t::event_closed (std::string &addr_, int fd_)
{
if (monitor_events & ZMQ_EVENT_CLOSED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_CLOSED)) return;
event.event = ZMQ_EVENT_CLOSED;
event.data.connected.addr = (char *)addr_;
event.data.closed.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.closed.addr, addr_);
event.data.closed.fd = fd_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_close_failed (const char *addr_, int err_)
void zmq::socket_base_t::event_close_failed (std::string &addr_, int err_)
{
if (monitor_events & ZMQ_EVENT_CLOSE_FAILED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_CLOSE_FAILED)) return;
event.event = ZMQ_EVENT_CLOSE_FAILED;
event.data.connected.addr = (char *)addr_;
event.data.close_failed.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.close_failed.addr, addr_);
event.data.close_failed.err = err_;
monitor_event (event);
}
}
void zmq::socket_base_t::event_disconnected (const char *addr_, int fd_)
void zmq::socket_base_t::event_disconnected (std::string &addr_, int fd_)
{
if (monitor_events & ZMQ_EVENT_DISCONNECTED) {
zmq_event_t event;
if (!(monitor_events & ZMQ_EVENT_DISCONNECTED)) return;
event.event = ZMQ_EVENT_DISCONNECTED;
event.data.connected.addr = (char *)addr_;
event.data.disconnected.addr = (char *) malloc (addr_.size () + 1);
copy_monitor_address (event.data.disconnected.addr, addr_);
event.data.disconnected.fd = fd_;
monitor_event (event);
}
}
void zmq::socket_base_t::copy_monitor_address (char *dest_, std::string &src_)
{
alloc_assert (dest_);
dest_[src_.size ()] = 0;
memcpy (dest_, src_.c_str (), src_.size ());
}
void zmq::socket_base_t::monitor_event (zmq_event_t event_)
{
if (monitor_socket) {
zmq_msg_t msg;
if (!monitor_socket) return;
zmq_msg_init_size (&msg, sizeof (event_));
memcpy (zmq_msg_data (&msg), &event_, sizeof (event_));
void *event_data = malloc (sizeof (event_));
alloc_assert (event_data);
memcpy (event_data, &event_, sizeof (event_));
zmq_msg_init_data (&msg, event_data, sizeof (event_), zmq_free_event, NULL);
zmq_sendmsg (monitor_socket, &msg, 0);
zmq_msg_close (&msg);
}
}
void zmq::socket_base_t::stop_monitor()
{

View File

@ -38,6 +38,11 @@
#include "clock.hpp"
#include "pipe.hpp"
extern "C"
{
void zmq_free_event (void *data, void *hint);
}
namespace zmq
{
@ -104,16 +109,16 @@ namespace zmq
int monitor(const char *endpoint_, int events_);
void event_connected(const char *addr_, int fd_);
void event_connect_delayed(const char *addr_, int err_);
void event_connect_retried(const char *addr_, int interval_);
void event_listening(const char *addr_, int fd_);
void event_bind_failed(const char *addr_, int err_);
void event_accepted(const char *addr_, int fd_);
void event_accept_failed(const char *addr_, int err_);
void event_closed(const char *addr_, int fd_);
void event_close_failed(const char *addr_, int fd_);
void event_disconnected(const char *addr_, int fd_);
void event_connected (std::string &addr_, int fd_);
void event_connect_delayed (std::string &addr_, int err_);
void event_connect_retried (std::string &addr_, int interval_);
void event_listening (std::string &addr_, int fd_);
void event_bind_failed (std::string &addr_, int err_);
void event_accepted (std::string &addr_, int fd_);
void event_accept_failed (std::string &addr_, int err_);
void event_closed (std::string &addr_, int fd_);
void event_close_failed (std::string &addr_, int fd_);
void event_disconnected (std::string &addr_, int fd_);
protected:
@ -151,6 +156,9 @@ namespace zmq
// Socket event data dispath
void monitor_event (zmq_event_t data_);
// Copy monitor specific event endpoints to event messages
void copy_monitor_address (char *dest_, std::string &src_);
// Monitor socket cleanup
void stop_monitor ();
@ -162,6 +170,10 @@ namespace zmq
typedef std::multimap <std::string, own_t *> endpoints_t;
endpoints_t endpoints;
// Map of open inproc endpoints.
typedef std::multimap <std::string, pipe_t *> inprocs_t;
inprocs_t inprocs;
// To be called after processing commands or invoking any command
// handlers explicitly. If required, it will deallocate the socket.
void check_destroy ();
@ -240,3 +252,4 @@ namespace zmq
}
#endif

View File

@ -50,10 +50,10 @@
zmq::stream_engine_t::stream_engine_t (fd_t fd_, const options_t &options_, const std::string &endpoint_) :
s (fd_),
io_enabled (false),
inpos (NULL),
insize (0),
decoder (NULL),
input_error (false),
outpos (NULL),
outsize (0),
encoder (NULL),
@ -63,6 +63,7 @@ zmq::stream_engine_t::stream_engine_t (fd_t fd_, const options_t &options_, cons
options (options_),
endpoint (endpoint_),
plugged (false),
terminating (false),
socket (NULL)
{
// Put the socket into non-blocking mode.
@ -132,6 +133,7 @@ void zmq::stream_engine_t::plug (io_thread_t *io_thread_,
// Connect to I/O threads poller object.
io_object_t::plug (io_thread_);
handle = add_fd (s);
io_enabled = true;
// Send the 'length' and 'flags' fields of the identity message.
// The 'length' field is encoded in the long format.
@ -153,7 +155,10 @@ void zmq::stream_engine_t::unplug ()
plugged = false;
// Cancel all fd subscriptions.
if (io_enabled) {
rm_fd (handle);
io_enabled = false;
}
// Disconnect from I/O threads poller object.
io_object_t::unplug ();
@ -168,6 +173,11 @@ void zmq::stream_engine_t::unplug ()
void zmq::stream_engine_t::terminate ()
{
if (!terminating && encoder && encoder->has_data ()) {
// Give io_thread a chance to send in the buffer
terminating = true;
return;
}
unplug ();
delete this;
}
@ -225,9 +235,10 @@ void zmq::stream_engine_t::in_event ()
// waiting for input events and postpone the termination
// until after the session has accepted the message.
if (disconnection) {
input_error = true;
if (decoder->stalled ())
reset_pollin (handle);
if (decoder->stalled ()) {
rm_fd (handle);
io_enabled = false;
}
else
error ();
}
@ -238,8 +249,15 @@ void zmq::stream_engine_t::out_event ()
// If write buffer is empty, try to read new data from the encoder.
if (!outsize) {
// Even when we stop polling as soon as there is no
// data to send, the poller may invoke out_event one
// more time due to 'speculative write' optimisation.
if (unlikely (encoder == NULL)) {
zmq_assert (handshaking);
return;
}
outpos = NULL;
zmq_assert (encoder);
encoder->get_data (&outpos, &outsize);
// If there is no data to send, stop polling for output.
@ -261,6 +279,8 @@ void zmq::stream_engine_t::out_event ()
// this is necessary to prevent losing incomming messages.
if (nbytes == -1) {
reset_pollout (handle);
if (unlikely (terminating))
terminate ();
return;
}
@ -272,6 +292,10 @@ void zmq::stream_engine_t::out_event ()
if (unlikely (handshaking))
if (outsize == 0)
reset_pollout (handle);
if (unlikely (terminating))
if (outsize == 0)
terminate ();
}
void zmq::stream_engine_t::activate_out ()
@ -287,7 +311,7 @@ void zmq::stream_engine_t::activate_out ()
void zmq::stream_engine_t::activate_in ()
{
if (input_error) {
if (unlikely (!io_enabled)) {
// There was an input error but the engine could not
// be terminated (due to the stalled decoder).
// Flush the pending message and terminate the engine now.
@ -447,7 +471,7 @@ int zmq::stream_engine_t::push_msg (msg_t *msg_)
void zmq::stream_engine_t::error ()
{
zmq_assert (session);
socket->event_disconnected (endpoint.c_str(), s);
socket->event_disconnected (endpoint, s);
session->detach ();
unplug ();
delete this;

View File

@ -96,12 +96,14 @@ namespace zmq
// Preamble (10 bytes) + version (1 byte) + socket type (1 byte).
const static size_t greeting_size = 12;
// True iff we are registered with an I/O poller.
bool io_enabled;
handle_t handle;
unsigned char *inpos;
size_t insize;
i_decoder *decoder;
bool input_error;
unsigned char *outpos;
size_t outsize;
@ -133,6 +135,7 @@ namespace zmq
std::string endpoint;
bool plugged;
bool terminating;
// Socket
zmq::socket_base_t *socket;

View File

@ -136,7 +136,7 @@ void zmq::tcp_connecter_t::out_event ()
// Shut the connecter down.
terminate ();
socket->event_connected (endpoint.c_str(), fd);
socket->event_connected (endpoint, fd);
}
void zmq::tcp_connecter_t::timer_event (int id_)
@ -159,11 +159,12 @@ void zmq::tcp_connecter_t::start_connecting ()
}
// Connection establishment may be delayed. Poll for its completion.
else if (rc == -1 && errno == EINPROGRESS) {
else
if (rc == -1 && errno == EINPROGRESS) {
handle = add_fd (s);
handle_valid = true;
set_pollout (handle);
socket->event_connect_delayed (endpoint.c_str(), zmq_errno());
socket->event_connect_delayed (endpoint, zmq_errno());
}
// Handle any other error condition by eventual reconnect.
@ -178,7 +179,7 @@ void zmq::tcp_connecter_t::add_reconnect_timer()
{
int rc_ivl = get_new_reconnect_ivl();
add_timer (rc_ivl, reconnect_timer_id);
socket->event_connect_retried (endpoint.c_str(), rc_ivl);
socket->event_connect_retried (endpoint, rc_ivl);
timer_started = true;
}
@ -252,7 +253,7 @@ int zmq::tcp_connecter_t::open ()
zmq::fd_t zmq::tcp_connecter_t::connect ()
{
// Async connect have finished. Check whether an error occured.
// Async connect has finished. Check whether an error occurred
int err = 0;
#if defined ZMQ_HAVE_HPUX
int len = sizeof (err);
@ -267,9 +268,13 @@ zmq::fd_t zmq::tcp_connecter_t::connect ()
#ifdef ZMQ_HAVE_WINDOWS
zmq_assert (rc == 0);
if (err != 0) {
if (err == WSAECONNREFUSED || err == WSAETIMEDOUT ||
err == WSAECONNABORTED || err == WSAEHOSTUNREACH ||
err == WSAENETUNREACH || err == WSAENETDOWN)
if (err == WSAECONNREFUSED ||
err == WSAETIMEDOUT ||
err == WSAECONNABORTED ||
err == WSAEHOSTUNREACH ||
err == WSAENETUNREACH ||
err == WSAENETDOWN ||
err == WSAEINVAL)
return retired_fd;
wsa_assert_no (err);
}
@ -281,9 +286,14 @@ zmq::fd_t zmq::tcp_connecter_t::connect ()
err = errno;
if (err != 0) {
errno = err;
errno_assert (errno == ECONNREFUSED || errno == ECONNRESET ||
errno == ETIMEDOUT || errno == EHOSTUNREACH ||
errno == ENETUNREACH || errno == ENETDOWN);
errno_assert (
errno == ECONNREFUSED ||
errno == ECONNRESET ||
errno == ETIMEDOUT ||
errno == EHOSTUNREACH ||
errno == ENETUNREACH ||
errno == ENETDOWN ||
errno == EINVAL);
return retired_fd;
}
#endif
@ -304,6 +314,6 @@ void zmq::tcp_connecter_t::close ()
int rc = ::close (s);
errno_assert (rc == 0);
#endif
socket->event_closed (endpoint.c_str(), s);
socket->event_closed (endpoint, s);
s = retired_fd;
}

View File

@ -85,7 +85,7 @@ void zmq::tcp_listener_t::in_event ()
// If connection was reset by the peer in the meantime, just ignore it.
// TODO: Handle specific errors like ENFILE/EMFILE etc.
if (fd == retired_fd) {
socket->event_accept_failed (endpoint.c_str(), zmq_errno());
socket->event_accept_failed (endpoint, zmq_errno());
return;
}
@ -108,7 +108,7 @@ void zmq::tcp_listener_t::in_event ()
session->inc_seqnum ();
launch_child (session);
send_attach (session, engine, false);
socket->event_accepted (endpoint.c_str(), fd);
socket->event_accepted (endpoint, fd);
}
void zmq::tcp_listener_t::close ()
@ -121,7 +121,7 @@ void zmq::tcp_listener_t::close ()
int rc = ::close (s);
errno_assert (rc == 0);
#endif
socket->event_closed (endpoint.c_str(), s);
socket->event_closed (endpoint, s);
s = retired_fd;
}
@ -223,7 +223,7 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
goto error;
#endif
socket->event_listening (endpoint.c_str(), s);
socket->event_listening (endpoint, s);
return 0;
error:

View File

@ -58,11 +58,6 @@ void zmq::v1_decoder_t::set_msg_sink (i_msg_sink *msg_sink_)
msg_sink = msg_sink_;
}
bool zmq::v1_decoder_t::stalled () const
{
return next == &v1_decoder_t::message_ready;
}
bool zmq::v1_decoder_t::flags_ready ()
{
msg_flags = 0;

View File

@ -44,8 +44,6 @@ namespace zmq
// i_decoder interface.
virtual void set_msg_sink (i_msg_sink *msg_sink_);
virtual bool stalled () const;
private:
bool flags_ready ();

View File

@ -29,8 +29,6 @@
namespace zmq
{
class i_msg_source;
// Encoder for 0MQ framing protocol. Converts messages into data stream.
class v1_encoder_t : public encoder_base_t <v1_encoder_t>

View File

@ -70,8 +70,8 @@ void zmq::xpub_t::xread_activated (pipe_t *pipe_)
unique = subscriptions.add (data + 1, size - 1, pipe_);
// If the subscription is not a duplicate store it so that it can be
// passed to used on next recv call.
if (options.type == ZMQ_XPUB && (unique || verbose))
// passed to used on next recv call. (Unsubscribe is not verbose.)
if (options.type == ZMQ_XPUB && (unique || (*data && verbose)))
pending.push_back (blob_t (data, size));
}

View File

@ -95,7 +95,11 @@ int zmq::xsub_t::xsend (msg_t *msg_, int flags_)
// Process the subscription.
if (*data == 1) {
if (subscriptions.add (data + 1, size - 1))
// this used to filter out duplicate subscriptions,
// however this is alread done on the XPUB side and
// doing it here as well breaks ZMQ_XPUB_VERBOSE
// when there are forwarding devices involved
subscriptions.add (data + 1, size - 1);
return dist.send_to_all (msg_, flags_);
}
else {

View File

@ -674,12 +674,12 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
int nevents = 0;
while (true) {
// Compute the timeout for the subsequent poll.
int timeout;
if (first_pass)
timeout = 0;
else if (timeout_ < 0)
else
if (timeout_ < 0)
timeout = -1;
else
timeout = end - now;
@ -694,7 +694,6 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
errno_assert (rc >= 0);
break;
}
// Check for the events.
for (int i = 0; i != nitems_; i++) {
@ -848,7 +847,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
timeout.tv_usec = 0;
ptimeout = &timeout;
}
else if (timeout_ < 0)
else
if (timeout_ < 0)
ptimeout = NULL;
else {
timeout.tv_sec = (long) ((end - now) / 1000);
@ -987,6 +987,47 @@ int zmq_device (int type, void *frontend_, void *backend_)
(zmq::socket_base_t*) backend_, NULL);
}
// Callback to free socket event data
void zmq_free_event (void *event_data, void *hint)
{
zmq_event_t *event = (zmq_event_t *) event_data;
switch (event->event) {
case ZMQ_EVENT_CONNECTED:
free (event->data.connected.addr);
break;
case ZMQ_EVENT_CONNECT_DELAYED:
free (event->data.connect_delayed.addr);
break;
case ZMQ_EVENT_CONNECT_RETRIED:
free (event->data.connect_retried.addr);
break;
case ZMQ_EVENT_LISTENING:
free (event->data.listening.addr);
break;
case ZMQ_EVENT_BIND_FAILED:
free (event->data.bind_failed.addr);
break;
case ZMQ_EVENT_ACCEPTED:
free (event->data.accepted.addr);
break;
case ZMQ_EVENT_ACCEPT_FAILED:
free (event->data.accept_failed.addr);
break;
case ZMQ_EVENT_CLOSED:
free (event->data.closed.addr);
break;
case ZMQ_EVENT_CLOSE_FAILED:
free (event->data.close_failed.addr);
break;
case ZMQ_EVENT_DISCONNECTED:
free (event->data.disconnected.addr);
break;
}
free (event_data);
}
////////////////////////////////////////////////////////////////////////////////
// 0MQ utils - to be used by perf tests
////////////////////////////////////////////////////////////////////////////////

View File

@ -17,7 +17,9 @@ noinst_PROGRAMS = test_pair_inproc \
test_last_endpoint \
test_term_endpoint \
test_monitor \
test_router_mandatory
test_router_mandatory \
test_disconnect_inproc
if !ON_MINGW
noinst_PROGRAMS += test_shutdown_stress \
@ -40,6 +42,7 @@ test_connect_delay_SOURCES = test_connect_delay.cpp
test_last_endpoint_SOURCES = test_last_endpoint.cpp
test_term_endpoint_SOURCES = test_term_endpoint.cpp
test_monitor_SOURCES = test_monitor.cpp
test_disconnect_inproc_SOURCES = test_disconnect_inproc.cpp
test_router_mandatory_SOURCES = test_router_mandatory.cpp
if !ON_MINGW

View File

@ -1,6 +1,5 @@
/*
Copyright (c) 2012 Ian Barber
Copyright (c) 2012 Other contributors as noted in the AUTHORS file
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
@ -24,131 +23,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
#include <unistd.h>
#include <string>
#include <pthread.h>
#undef NDEBUG
#include <assert.h>
static void *server (void *)
{
void *socket, *context;
char buffer[16];
int rc, val;
context = zmq_init (1);
assert (context);
socket = zmq_socket (context, ZMQ_PULL);
assert (socket);
val = 0;
rc = zmq_setsockopt(socket, ZMQ_LINGER, &val, sizeof(val));
assert (rc == 0);
rc = zmq_bind (socket, "ipc:///tmp/recon");
assert (rc == 0);
memset (&buffer, 0, sizeof(buffer));
rc = zmq_recv (socket, &buffer, sizeof(buffer), 0);
// Intentionally bail out
rc = zmq_close (socket);
assert (rc == 0);
rc = zmq_term (context);
assert (rc == 0);
usleep (200000);
context = zmq_init (1);
assert (context);
socket = zmq_socket (context, ZMQ_PULL);
assert (socket);
val = 0;
rc = zmq_setsockopt(socket, ZMQ_LINGER, &val, sizeof(val));
assert (rc == 0);
rc = zmq_bind (socket, "ipc:///tmp/recon");
assert (rc == 0);
usleep (200000);
memset (&buffer, 0, sizeof(buffer));
rc = zmq_recv (socket, &buffer, sizeof(buffer), ZMQ_DONTWAIT);
assert (rc != -1);
// Start closing the socket while the connecting process is underway.
rc = zmq_close (socket);
assert (rc == 0);
rc = zmq_term (context);
assert (rc == 0);
pthread_exit(NULL);
}
static void *worker (void *)
{
void *socket, *context;
int rc, hadone, val;
context = zmq_init (1);
assert (context);
socket = zmq_socket (context, ZMQ_PUSH);
assert (socket);
val = 0;
rc = zmq_setsockopt(socket, ZMQ_LINGER, &val, sizeof(val));
assert (rc == 0);
val = 1;
rc = zmq_setsockopt (socket, ZMQ_DELAY_ATTACH_ON_CONNECT, &val, sizeof(val));
assert (rc == 0);
rc = zmq_connect (socket, "ipc:///tmp/recon");
assert (rc == 0);
hadone = 0;
// Not checking RC as some may be -1
for (int i = 0; i < 6; i++) {
usleep(200000);
rc = zmq_send (socket, "hi", 2, ZMQ_DONTWAIT);
if (rc != -1)
hadone ++;
}
assert (hadone >= 2);
assert (hadone < 4);
rc = zmq_close (socket);
assert (rc == 0);
rc = zmq_term (context);
assert (rc == 0);
pthread_exit(NULL);
}
int main (void)
{
fprintf (stderr, "test_connect_delay running...\n");
int val;
int rc;
char buffer[16];
int seen = 0;
// TEST 1.
// First we're going to attempt to send messages to two
// pipes, one connected, the other not. We should see
// the PUSH load balancing to both pipes, and hence half
// of the messages getting queued, as connect() creates a
// pipe immediately.
void *context = zmq_ctx_new();
assert (context);
void *to = zmq_socket(context, ZMQ_PULL);
assert (to);
// Bind the one valid receiver
val = 0;
rc = zmq_setsockopt(to, ZMQ_LINGER, &val, sizeof(val));
assert (rc == 0);
rc = zmq_bind(to, "tcp://*:5555");
rc = zmq_bind (to, "tcp://*:6555");
assert (rc == 0);
// Create a socket pushing to two endpoints - only 1 message should arrive.
@ -157,27 +57,31 @@ int main (void)
val = 0;
zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof (val));
// This pipe will not connect
rc = zmq_connect (from, "tcp://localhost:5556");
assert (rc == 0);
rc = zmq_connect (from, "tcp://localhost:5555");
// This pipe will
rc = zmq_connect (from, "tcp://localhost:6555");
assert (rc == 0);
for (int i = 0; i < 10; ++i)
{
std::string message("message ");
message += ('0' + i);
rc = zmq_send (from, message.data(), message.size(), 0);
assert(rc >= 0);
// We send 10 messages, 5 should just get stuck in the queue
// for the not-yet-connected pipe
for (int i = 0; i < 10; ++i) {
rc = zmq_send (from, "Hello", 5, 0);
assert (rc == 5);
}
sleep(1);
seen = 0;
for (int i = 0; i < 10; ++i)
{
memset (&buffer, 0, sizeof(buffer));
rc = zmq_recv (to, &buffer, sizeof(buffer), ZMQ_DONTWAIT);
// We now consume from the connected pipe
// - we should see just 5
int timeout = 100;
rc = zmq_setsockopt (to, ZMQ_RCVTIMEO, &timeout, sizeof (int));
assert (rc == 0);
int seen = 0;
while (true) {
rc = zmq_recv (to, &buffer, sizeof (buffer), 0);
if (rc == -1)
break;
break; // Break when we didn't get a message
seen++;
}
assert (seen == 5);
@ -188,12 +92,19 @@ int main (void)
rc = zmq_close (to);
assert (rc == 0);
rc = zmq_ctx_destroy(context);
rc = zmq_term (context);
assert (rc == 0);
// TEST 2
// This time we will do the same thing, connect two pipes,
// one of which will succeed in connecting to a bound
// receiver, the other of which will fail. However, we will
// also set the delay attach on connect flag, which should
// cause the pipe attachment to be delayed until the connection
// succeeds.
context = zmq_ctx_new();
fprintf (stderr, " Rerunning with DELAY_ATTACH_ON_CONNECT\n");
// Bind the valid socket
to = zmq_socket (context, ZMQ_PULL);
assert (to);
rc = zmq_bind (to, "tcp://*:5560");
@ -211,33 +122,34 @@ int main (void)
rc = zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof(val));
assert (rc == 0);
// Set the key flag
val = 1;
rc = zmq_setsockopt (from, ZMQ_DELAY_ATTACH_ON_CONNECT, &val, sizeof(val));
assert (rc == 0);
// Connect to the invalid socket
rc = zmq_connect (from, "tcp://localhost:5561");
assert (rc == 0);
// Connect to the valid socket
rc = zmq_connect (from, "tcp://localhost:5560");
assert (rc == 0);
for (int i = 0; i < 10; ++i)
{
std::string message("message ");
message += ('0' + i);
rc = zmq_send (from, message.data(), message.size(), 0);
assert (rc >= 0);
// Send 10 messages, all should be routed to the connected pipe
for (int i = 0; i < 10; ++i) {
rc = zmq_send (from, "Hello", 5, 0);
assert (rc == 5);
}
sleep(1);
rc = zmq_setsockopt (to, ZMQ_RCVTIMEO, &timeout, sizeof (int));
assert (rc == 0);
seen = 0;
for (int i = 0; i < 10; ++i)
{
memset(&buffer, 0, sizeof(buffer));
rc = zmq_recv (to, &buffer, sizeof(buffer), ZMQ_DONTWAIT);
assert (rc != -1);
while (true) {
rc = zmq_recv (to, &buffer, sizeof (buffer), 0);
if (rc == -1)
break; // Break when we didn't get a message
seen++;
}
assert (seen == 10);
rc = zmq_close (from);
assert (rc == 0);
@ -245,18 +157,82 @@ int main (void)
rc = zmq_close (to);
assert (rc == 0);
rc = zmq_ctx_destroy(context);
rc = zmq_term (context);
assert (rc == 0);
fprintf (stderr, " Running DELAY_ATTACH_ON_CONNECT with disconnect\n");
// TEST 3
// This time we want to validate that the same blocking behaviour
// occurs with an existing connection that is broken. We will send
// messages to a connected pipe, disconnect and verify the messages
// block. Then we reconnect and verify messages flow again.
context = zmq_ctx_new ();
pthread_t serv, work;
rc = pthread_create (&serv, NULL, server, NULL);
void *backend = zmq_socket (context, ZMQ_DEALER);
assert (backend);
void *frontend = zmq_socket (context, ZMQ_DEALER);
assert (frontend);
int zero = 0;
rc = zmq_setsockopt (backend, ZMQ_LINGER, &zero, sizeof (zero));
assert (rc == 0);
rc = zmq_setsockopt (frontend, ZMQ_LINGER, &zero, sizeof (zero));
assert (rc == 0);
rc = pthread_create (&work, NULL, worker, NULL);
// Frontend connects to backend using DELAY_ATTACH_ON_CONNECT
int on = 1;
rc = zmq_setsockopt (frontend, ZMQ_DELAY_ATTACH_ON_CONNECT, &on, sizeof (on));
assert (rc == 0);
rc = zmq_bind (backend, "tcp://*:5560");
assert (rc == 0);
rc = zmq_connect (frontend, "tcp://localhost:5560");
assert (rc == 0);
pthread_exit(NULL);
// Ping backend to frontend so we know when the connection is up
rc = zmq_send (backend, "Hello", 5, 0);
assert (rc == 5);
rc = zmq_recv (frontend, buffer, 255, 0);
assert (rc == 5);
// Send message from frontend to backend
rc = zmq_send (frontend, "Hello", 5, ZMQ_DONTWAIT);
assert (rc == 5);
rc = zmq_close (backend);
assert (rc == 0);
// Give time to process disconnect
// There's no way to do this except with a sleep
struct timespec t = { 0, 250 * 1000000 };
nanosleep (&t, NULL);
// Send a message, should fail
rc = zmq_send (frontend, "Hello", 5, ZMQ_DONTWAIT);
assert (rc == -1);
// Recreate backend socket
backend = zmq_socket (context, ZMQ_DEALER);
assert (backend);
rc = zmq_setsockopt (backend, ZMQ_LINGER, &zero, sizeof (zero));
assert (rc == 0);
rc = zmq_bind (backend, "tcp://*:5560");
assert (rc == 0);
// Ping backend to frontend so we know when the connection is up
rc = zmq_send (backend, "Hello", 5, 0);
assert (rc == 5);
rc = zmq_recv (frontend, buffer, 255, 0);
assert (rc == 5);
// After the reconnect, should succeed
rc = zmq_send (frontend, "Hello", 5, ZMQ_DONTWAIT);
assert (rc == 5);
rc = zmq_close (backend);
assert (rc == 0);
rc = zmq_close (frontend);
assert (rc == 0);
rc = zmq_term (context);
assert (rc == 0);
}

View File

@ -0,0 +1,113 @@
#include <zmq.h>
#include <inttypes.h>
#include <string.h>
#include <assert.h>
/// Initialize a zeromq message with a given null-terminated string
#define ZMQ_PREPARE_STRING(msg, data, size) \
zmq_msg_init(&msg) && printf("zmq_msg_init: %s\n", zmq_strerror(errno)); \
zmq_msg_init_size (&msg, size + 1) && printf("zmq_msg_init_size: %s\n",zmq_strerror(errno)); \
memcpy(zmq_msg_data(&msg), data, size + 1);
int publicationsReceived = 0;
bool isSubscribed = false;
int main(int argc, char** argv) {
void* context = zmq_ctx_new();
void* pubSocket;
void* subSocket;
(pubSocket = zmq_socket(context, ZMQ_XPUB)) || printf("zmq_socket: %s\n", zmq_strerror(errno));
(subSocket = zmq_socket(context, ZMQ_SUB)) || printf("zmq_socket: %s\n", zmq_strerror(errno));
zmq_setsockopt(subSocket, ZMQ_SUBSCRIBE, "foo", 3) && printf("zmq_setsockopt: %s\n",zmq_strerror(errno));
zmq_bind(pubSocket, "inproc://someInProcDescriptor") && printf("zmq_bind: %s\n", zmq_strerror(errno));
//zmq_bind(pubSocket, "tcp://*:30010") && printf("zmq_bind: %s\n", zmq_strerror(errno));
int32_t more;
size_t more_size = sizeof(more);
int iteration = 0;
while(1) {
zmq_pollitem_t items [] = {
{ subSocket, 0, ZMQ_POLLIN, 0 }, // read publications
{ pubSocket, 0, ZMQ_POLLIN, 0 }, // read subscriptions
};
zmq_poll(items, 2, 500);
if (items[1].revents & ZMQ_POLLIN) {
while (1) {
zmq_msg_t msg;
zmq_msg_init (&msg);
zmq_msg_recv (&msg, pubSocket, 0);
char* buffer = (char*)zmq_msg_data(&msg);
if (buffer[0] == 0) {
assert(isSubscribed);
isSubscribed = false;
}
else {
assert(!isSubscribed);
isSubscribed = true;
}
zmq_getsockopt (pubSocket, ZMQ_RCVMORE, &more, &more_size);
zmq_msg_close (&msg);
if (!more)
break; // Last message part
}
}
if (items[0].revents & ZMQ_POLLIN) {
while (1) {
zmq_msg_t msg;
zmq_msg_init (&msg);
zmq_msg_recv (&msg, subSocket, 0);
zmq_getsockopt (subSocket, ZMQ_RCVMORE, &more, &more_size);
zmq_msg_close (&msg);
if (!more) {
publicationsReceived++;
break; // Last message part
}
}
}
if (iteration == 1) {
zmq_connect(subSocket, "inproc://someInProcDescriptor") && printf("zmq_connect: %s\n", zmq_strerror(errno));
//zmq_connect(subSocket, "tcp://127.0.0.1:30010") && printf("zmq_connect: %s\n", zmq_strerror(errno));
}
if (iteration == 4) {
zmq_disconnect(subSocket, "inproc://someInProcDescriptor") && printf("zmq_disconnect(%d): %s\n", errno, zmq_strerror(errno));
//zmq_disconnect(subSocket, "tcp://127.0.0.1:30010") && printf("zmq_disconnect: %s\n", zmq_strerror(errno));
}
if (iteration == 10) {
break;
}
zmq_msg_t channelEnvlp;
ZMQ_PREPARE_STRING(channelEnvlp, "foo", 3);
zmq_sendmsg(pubSocket, &channelEnvlp, ZMQ_SNDMORE) >= 0 || printf("zmq_sendmsg: %s\n",zmq_strerror(errno));
zmq_msg_close(&channelEnvlp) && printf("zmq_msg_close: %s\n",zmq_strerror(errno));
zmq_msg_t message;
ZMQ_PREPARE_STRING(message, "this is foo!", 12);
zmq_sendmsg(pubSocket, &message, 0) >= 0 || printf("zmq_sendmsg: %s\n",zmq_strerror(errno));
zmq_msg_close(&message) && printf("zmq_msg_close: %s\n",zmq_strerror(errno));
iteration++;
}
assert(publicationsReceived == 3);
assert(!isSubscribed);
zmq_close(pubSocket) && printf("zmq_close: %s", zmq_strerror(errno));
zmq_close(subSocket) && printf("zmq_close: %s", zmq_strerror(errno));
zmq_ctx_destroy(context);
return 0;
}

View File

@ -29,11 +29,10 @@ static void do_bind_and_verify (void *s, const char *endpoint)
{
int rc = zmq_bind (s, endpoint);
assert (rc == 0);
char test [255];
size_t siz = 255;
rc = zmq_getsockopt (s, ZMQ_LAST_ENDPOINT, test, &siz);
assert (rc == 0 && strcmp (test, endpoint) == 0);
char reported [255];
size_t size = 255;
rc = zmq_getsockopt (s, ZMQ_LAST_ENDPOINT, reported, &size);
assert (rc == 0 && strcmp (reported, endpoint) == 0);
}
int main (void)
@ -49,6 +48,12 @@ int main (void)
do_bind_and_verify (sb, "tcp://127.0.0.1:5561");
do_bind_and_verify (sb, "ipc:///tmp/testep");
int rc = zmq_close (sb);
assert (rc == 0);
rc = zmq_term (ctx);
assert (rc == 0);
return 0;
}

View File

@ -50,7 +50,7 @@ int main (void)
// Send a message and check that it fails
rc = zmq_send (sa, "UNKNOWN", 7, ZMQ_SNDMORE | ZMQ_DONTWAIT);
assert (rc == -1 && errno == EAGAIN);
assert (rc == -1 && errno == EHOSTUNREACH);
rc = zmq_close (sa);
assert (rc == 0);