mirror of
https://github.com/zeromq/libzmq.git
synced 2025-08-11 21:18:16 +02:00
Compare commits
88 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a85ddf3e1a | ||
![]() |
41b7f74d49 | ||
![]() |
69dbe0113a | ||
![]() |
894c0fb87b | ||
![]() |
521ed91289 | ||
![]() |
a436d14547 | ||
![]() |
1a17eb392e | ||
![]() |
4f1f68f6cc | ||
![]() |
5d3781a8bf | ||
![]() |
d6aaa4a7ba | ||
![]() |
b774772bb9 | ||
![]() |
a0a24a92af | ||
![]() |
6a7dcfb898 | ||
![]() |
8e748064ac | ||
![]() |
c436c8cdc3 | ||
![]() |
0df7bbbc9d | ||
![]() |
c2b6f06d0d | ||
![]() |
4a0410ad21 | ||
![]() |
572be0e82c | ||
![]() |
92446d81ce | ||
![]() |
96ce417422 | ||
![]() |
911387cfbb | ||
![]() |
2131e85cd7 | ||
![]() |
fbfd3c34d9 | ||
![]() |
1965e2d05d | ||
![]() |
a91779baf1 | ||
![]() |
8e6fdc56e1 | ||
![]() |
b0563c2103 | ||
![]() |
2388f27bfe | ||
![]() |
ba1fd8e82a | ||
![]() |
6d4e2ce93b | ||
![]() |
7541e38205 | ||
![]() |
c7786d4374 | ||
![]() |
ed8ab632c6 | ||
![]() |
2ae1bd2088 | ||
![]() |
3b268c6943 | ||
![]() |
025e218629 | ||
![]() |
61b936893d | ||
![]() |
bcf8916e17 | ||
![]() |
12f3f8a7f6 | ||
![]() |
9120741719 | ||
![]() |
efdb5cf076 | ||
![]() |
ae8c4a4adf | ||
![]() |
f9b6da0e78 | ||
![]() |
f5a9c328e9 | ||
![]() |
65a29e85ee | ||
![]() |
f0383bffad | ||
![]() |
a7438de239 | ||
![]() |
7f81575245 | ||
![]() |
c05a1b1f26 | ||
![]() |
f976e8cc98 | ||
![]() |
07122eefec | ||
![]() |
69fa792cae | ||
![]() |
30738e1123 | ||
![]() |
50b6da0c1c | ||
![]() |
0c0a351fa5 | ||
![]() |
36736e64cc | ||
![]() |
50e9d72dc4 | ||
![]() |
87c6ebb135 | ||
![]() |
4527d8db6f | ||
![]() |
ed9c7440d2 | ||
![]() |
fec6497976 | ||
![]() |
f56c6faf65 | ||
![]() |
1d9a3fd480 | ||
![]() |
fff267071d | ||
![]() |
ec8d935acc | ||
![]() |
08b0af5075 | ||
![]() |
b0576e8c54 | ||
![]() |
5b9de45a89 | ||
![]() |
2996b25039 | ||
![]() |
09c56c4493 | ||
![]() |
d9d7d9be54 | ||
![]() |
d95f8c5f55 | ||
![]() |
ceb388e371 | ||
![]() |
888c1bdb5b | ||
![]() |
a5da31eb07 | ||
![]() |
bbff2fc3f8 | ||
![]() |
c391966fbb | ||
![]() |
24ea41ce7a | ||
![]() |
d0eed09f6f | ||
![]() |
5e4f858c8e | ||
![]() |
bdbdf8bb7e | ||
![]() |
30e2da05a1 | ||
![]() |
2fe4a355fd | ||
![]() |
da7427b771 | ||
![]() |
e18b69bfa1 | ||
![]() |
05bd3ea8b9 | ||
![]() |
7735322151 |
1
AUTHORS
1
AUTHORS
@ -66,6 +66,7 @@ Pieter Hintjens <ph@imatix.com>
|
|||||||
Piotr Trojanek <piotr.trojanek@gmail.com>
|
Piotr Trojanek <piotr.trojanek@gmail.com>
|
||||||
Robert G. Jakabosky <bobby@sharedrealm.com>
|
Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||||
Sebastian Otaegui <feniix@gmail.com>
|
Sebastian Otaegui <feniix@gmail.com>
|
||||||
|
Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de>
|
||||||
Steven McCoy <steven.mccoy@miru.hk>
|
Steven McCoy <steven.mccoy@miru.hk>
|
||||||
Stuart Webster <sw_webster@hotmail.com>
|
Stuart Webster <sw_webster@hotmail.com>
|
||||||
Tamara Kustarova <kustarova.tamara@gmail.com>
|
Tamara Kustarova <kustarova.tamara@gmail.com>
|
||||||
|
@ -15,7 +15,32 @@ set(PYTHON_EXECUTABLE c:/cygwin/bin/python2.6.exe CACHE FILEPATH "Python interpr
|
|||||||
# TODO: Replace with FindAsciidoc.cmake
|
# TODO: Replace with FindAsciidoc.cmake
|
||||||
set(ASCIIDOC_EXECUTABLE c:/cygwin/bin/asciidoc CACHE FILEPATH "AsciiDoc executable")
|
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 121)
|
||||||
|
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_COMPILER}-mt-${OPENPGM_VERSION_MAJOR}_${OPENPGM_VERSION_MINOR}_${OPENPGM_VERSION_MICRO}.lib
|
||||||
|
debug libpgm${_zmq_COMPILER}-mt-gd-${OPENPGM_VERSION_MAJOR}_${OPENPGM_VERSION_MINOR}_${OPENPGM_VERSION_MICRO}.lib)
|
||||||
|
endif (WITH_OPENPGM)
|
||||||
|
|
||||||
mark_as_advanced(PYTHON_EXECUTABLE ASCIIDOC_EXECUTABLE)
|
mark_as_advanced(PYTHON_EXECUTABLE ASCIIDOC_EXECUTABLE)
|
||||||
|
|
||||||
@ -160,28 +185,13 @@ if(WITH_OPENPGM)
|
|||||||
add_definitions(
|
add_definitions(
|
||||||
-DZMQ_HAVE_OPENPGM
|
-DZMQ_HAVE_OPENPGM
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
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(
|
link_directories(
|
||||||
${OPENPGM_LIBRARYDIR}
|
${OPENPGM_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
set(OPTIONAL_LIBRARIES ${OPENPGM_LIBRARIES})
|
||||||
endif(WITH_OPENPGM)
|
endif(WITH_OPENPGM)
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
@ -207,11 +217,11 @@ add_custom_command(
|
|||||||
)
|
)
|
||||||
list(APPEND sources ${CMAKE_BINARY_DIR}/platform.hpp)
|
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)
|
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)
|
set (nsis-template ${CMAKE_SOURCE_DIR}/cmake/NSIS.template32.in)
|
||||||
endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
endif (CMAKE_CL_64)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_BINARY_DIR}/NSIS.template.in
|
OUTPUT ${CMAKE_BINARY_DIR}/NSIS.template.in
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
@ -253,17 +263,20 @@ endforeach (txt ${docs})
|
|||||||
# output
|
# output
|
||||||
|
|
||||||
add_library(libzmq SHARED ${sources} ${html-docs} ${CMAKE_BINARY_DIR}/NSIS.template.in)
|
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_COMPILER}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}"
|
||||||
|
DEBUG_POSTFIX "${_zmq_COMPILER}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}")
|
||||||
|
|
||||||
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")
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
install (FILES ${CMAKE_BINARY_DIR}/lib/libzmq${_zmq_COMPILER}-mt-gd.dll DESTINATION bin COMPONENT SDK)
|
install (TARGETS libzmq RUNTIME 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-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}.pdb 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")
|
else (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
install (TARGETS libzmq RUNTIME DESTINATION bin COMPONENT Runtime)
|
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")
|
endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
install (FILES ${headers} DESTINATION include COMPONENT SDK)
|
install (FILES ${headers} DESTINATION include COMPONENT SDK)
|
||||||
|
|
||||||
@ -296,18 +309,29 @@ endif (WITH_DOC)
|
|||||||
|
|
||||||
include (InstallRequiredSystemLibraries)
|
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
|
set (CPACK_INSTALL_CMAKE_PROJECTS
|
||||||
"${CMAKE_SOURCE_DIR}/build64;ZeroMQ;ALL;/"
|
"${CMAKE_SOURCE_DIR}/build/x64/v110;ZeroMQ;ALL;/"
|
||||||
"${CMAKE_SOURCE_DIR}/debug64;ZeroMQ;ALL;/"
|
"${CMAKE_SOURCE_DIR}/debug/x64/v110;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/build/x64/v100;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/debug/x64/v100;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/build/x64/v90;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/debug/x64/v90;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
|
set (CPACK_INSTALL_CMAKE_PROJECTS
|
||||||
"${CMAKE_SOURCE_DIR}/build;ZeroMQ;ALL;/"
|
"${CMAKE_SOURCE_DIR}/build/x86/v110;ZeroMQ;ALL;/"
|
||||||
"${CMAKE_SOURCE_DIR}/debug;ZeroMQ;ALL;/"
|
"${CMAKE_SOURCE_DIR}/debug/x86/v110;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/build/x86/v100;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/debug/x86/v100;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/build/x86/v90;ZeroMQ;ALL;/"
|
||||||
|
"${CMAKE_SOURCE_DIR}/debug/x86/v90;ZeroMQ;ALL;/"
|
||||||
)
|
)
|
||||||
endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
endif (CMAKE_CL_64)
|
||||||
|
|
||||||
set (CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}")
|
set (CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}")
|
||||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "ZeroMQ lightweight messaging kernel")
|
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "ZeroMQ lightweight messaging kernel")
|
||||||
set (CPACK_PACKAGE_VENDOR "Miru")
|
set (CPACK_PACKAGE_VENDOR "Miru")
|
||||||
|
7
INSTALL
7
INSTALL
@ -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
|
This file is free documentation; the Free Software Foundation gives
|
||||||
unlimited permission to copy, distribute and modify it.
|
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
|
Basic Installation
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
40
NEWS
40
NEWS
@ -1,3 +1,43 @@
|
|||||||
|
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-456 ZMQ_XPUB_VERBOSE does not propagate in a tree of XPUB/XSUB devices
|
||||||
|
* 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
|
0MQ version 3.2.1 (RC2), released on 2012/10/15
|
||||||
===============================================
|
===============================================
|
||||||
|
|
||||||
|
@ -11,12 +11,15 @@ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
|||||||
BuildRequires: gcc, make, gcc-c++, libstdc++-devel
|
BuildRequires: gcc, make, gcc-c++, libstdc++-devel
|
||||||
Requires: libstdc++
|
Requires: libstdc++
|
||||||
|
|
||||||
%if %{?rhel}%{!?rhel:0} >= 6
|
%if 0%{?rhel}
|
||||||
|
%if 0%{?rhel} == 6
|
||||||
BuildRequires: libuuid-devel
|
BuildRequires: libuuid-devel
|
||||||
Requires: libuuid
|
Requires: libuuid
|
||||||
%elseif %{?rhel}%{!?rhel:0} >= 5
|
%endif
|
||||||
|
%if 0%{?rhel} == 5
|
||||||
BuildRequires: e2fsprogs-devel
|
BuildRequires: e2fsprogs-devel
|
||||||
Requires: e2fsprogs
|
Requires: e2fsprogs
|
||||||
|
%endif
|
||||||
%else
|
%else
|
||||||
BuildRequires: uuid-devel
|
BuildRequires: uuid-devel
|
||||||
Requires: uuid
|
Requires: uuid
|
||||||
@ -57,7 +60,7 @@ This package contains ZeroMQ related development libraries and header files.
|
|||||||
|
|
||||||
%build
|
%build
|
||||||
%ifarch pentium3 pentium4 athlon i386 i486 i586 i686 x86_64
|
%ifarch pentium3 pentium4 athlon i386 i486 i586 i686 x86_64
|
||||||
%configure --with-pgm
|
%configure --with-pgm --with-pic --with-gnu-ld
|
||||||
%else
|
%else
|
||||||
%configure
|
%configure
|
||||||
%endif
|
%endif
|
||||||
@ -87,17 +90,10 @@ This package contains ZeroMQ related development libraries and header files.
|
|||||||
%doc AUTHORS ChangeLog COPYING COPYING.LESSER NEWS README
|
%doc AUTHORS ChangeLog COPYING COPYING.LESSER NEWS README
|
||||||
|
|
||||||
# libraries
|
# libraries
|
||||||
%{_libdir}/libzmq.so.1
|
%{_libdir}/libzmq.so.3
|
||||||
%{_libdir}/libzmq.so.1.0.0
|
%{_libdir}/libzmq.so.3.0.0
|
||||||
|
|
||||||
%attr(0755,root,root) %{_bindir}/zmq_forwarder
|
|
||||||
%attr(0755,root,root) %{_bindir}/zmq_queue
|
|
||||||
%attr(0755,root,root) %{_bindir}/zmq_streamer
|
|
||||||
|
|
||||||
%{_mandir}/man7/zmq.7.gz
|
%{_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
|
%files devel
|
||||||
%defattr(-,root,root,-)
|
%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_bind.3.gz
|
||||||
%{_mandir}/man3/zmq_close.3.gz
|
%{_mandir}/man3/zmq_close.3.gz
|
||||||
%{_mandir}/man3/zmq_connect.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_errno.3.gz
|
||||||
%{_mandir}/man3/zmq_getsockopt.3.gz
|
%{_mandir}/man3/zmq_getsockopt.3.gz
|
||||||
%{_mandir}/man3/zmq_init.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_init_size.3.gz
|
||||||
%{_mandir}/man3/zmq_msg_move.3.gz
|
%{_mandir}/man3/zmq_msg_move.3.gz
|
||||||
%{_mandir}/man3/zmq_msg_size.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_poll.3.gz
|
||||||
|
%{_mandir}/man3/zmq_proxy.3.gz
|
||||||
%{_mandir}/man3/zmq_recv.3.gz
|
%{_mandir}/man3/zmq_recv.3.gz
|
||||||
%{_mandir}/man3/zmq_recvmsg.3.gz
|
%{_mandir}/man3/zmq_recvmsg.3.gz
|
||||||
%{_mandir}/man3/zmq_send.3.gz
|
%{_mandir}/man3/zmq_send.3.gz
|
||||||
%{_mandir}/man3/zmq_sendmsg.3.gz
|
%{_mandir}/man3/zmq_sendmsg.3.gz
|
||||||
%{_mandir}/man3/zmq_setsockopt.3.gz
|
%{_mandir}/man3/zmq_setsockopt.3.gz
|
||||||
%{_mandir}/man3/zmq_socket.3.gz
|
%{_mandir}/man3/zmq_socket.3.gz
|
||||||
|
%{_mandir}/man3/zmq_socket_monitor.3.gz
|
||||||
%{_mandir}/man3/zmq_strerror.3.gz
|
%{_mandir}/man3/zmq_strerror.3.gz
|
||||||
%{_mandir}/man3/zmq_term.3.gz
|
%{_mandir}/man3/zmq_term.3.gz
|
||||||
%{_mandir}/man3/zmq_version.3.gz
|
%{_mandir}/man3/zmq_version.3.gz
|
||||||
|
%{_mandir}/man3/zmq_unbind.3.gz
|
||||||
%{_mandir}/man7/zmq_epgm.7.gz
|
%{_mandir}/man7/zmq_epgm.7.gz
|
||||||
%{_mandir}/man7/zmq_inproc.7.gz
|
%{_mandir}/man7/zmq_inproc.7.gz
|
||||||
%{_mandir}/man7/zmq_ipc.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
|
%{_mandir}/man7/zmq_tcp.7.gz
|
||||||
|
|
||||||
%changelog
|
%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
|
* Fri Apr 8 2011 Mikko Koppanen <mikko@kuut.io> 3.0.0-1
|
||||||
- Update dependencies and packaged files
|
- Update dependencies and packaged files
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ Var AR_RegFlags
|
|||||||
|
|
||||||
ClearErrors
|
ClearErrors
|
||||||
;Reading component status from registry
|
;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}"
|
IfErrors "default_${SecName}"
|
||||||
;Status will stay default if registry value not found
|
;Status will stay default if registry value not found
|
||||||
;(component was never installed)
|
;(component was never installed)
|
||||||
@ -108,13 +108,13 @@ Var AR_RegFlags
|
|||||||
;Section is not selected:
|
;Section is not selected:
|
||||||
;Calling Section uninstall macro and writing zero installed flag
|
;Calling Section uninstall macro and writing zero installed flag
|
||||||
!insertmacro "Remove_${${SecName}}"
|
!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
|
"Installed" 0
|
||||||
Goto "exit_${SecName}"
|
Goto "exit_${SecName}"
|
||||||
|
|
||||||
"leave_${SecName}:"
|
"leave_${SecName}:"
|
||||||
;Section is selected:
|
;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
|
"Installed" 1
|
||||||
|
|
||||||
"exit_${SecName}:"
|
"exit_${SecName}:"
|
||||||
@ -494,7 +494,7 @@ Function ConditionalAddToRegisty
|
|||||||
Pop $0
|
Pop $0
|
||||||
Pop $1
|
Pop $1
|
||||||
StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
|
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"
|
"$1" "$0"
|
||||||
;MessageBox MB_OK "Set Registry: '$1' to '$0'"
|
;MessageBox MB_OK "Set Registry: '$1' to '$0'"
|
||||||
DetailPrint "Set install registry entry: '$1' to '$0'"
|
DetailPrint "Set install registry entry: '$1' to '$0'"
|
||||||
@ -810,17 +810,17 @@ FunctionEnd
|
|||||||
|
|
||||||
Section "Uninstall"
|
Section "Uninstall"
|
||||||
ReadRegStr $START_MENU SHCTX \
|
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"
|
;MessageBox MB_OK "Start menu is in: $START_MENU"
|
||||||
ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \
|
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 \
|
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 \
|
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"
|
;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
|
||||||
ReadRegStr $INSTALL_DESKTOP SHCTX \
|
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 "
|
;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "
|
||||||
|
|
||||||
@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
|
@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
|
||||||
@ -837,7 +837,7 @@ Section "Uninstall"
|
|||||||
|
|
||||||
;Remove the uninstaller itself.
|
;Remove the uninstaller itself.
|
||||||
Delete "$INSTDIR\Uninstall.exe"
|
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.
|
;Remove the installation directory if it is empty.
|
||||||
RMDir "$INSTDIR"
|
RMDir "$INSTDIR"
|
||||||
|
@ -10,7 +10,7 @@ AC_INIT([zeromq],[m4_esyscmd([./version.sh])],[zeromq-dev@lists.zeromq.org])
|
|||||||
|
|
||||||
AC_CONFIG_AUX_DIR(config)
|
AC_CONFIG_AUX_DIR(config)
|
||||||
AC_CONFIG_MACRO_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)
|
AM_INIT_AUTOMAKE(tar-ustar dist-zip foreign)
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
|
@ -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_ctx_new.3 zmq_ctx_destroy.3 zmq_ctx_get.3 zmq_ctx_set.3 \
|
||||||
zmq_init.3 zmq_term.3 \
|
zmq_msg_init.3 zmq_msg_init_data.3 zmq_msg_init_size.3 \
|
||||||
zmq_msg_close.3 zmq_msg_copy.3 zmq_msg_data.3 zmq_msg_init.3 \
|
zmq_msg_move.3 zmq_msg_copy.3 zmq_msg_size.3 zmq_msg_data.3 zmq_msg_close.3 \
|
||||||
zmq_msg_init_data.3 zmq_msg_init_size.3 zmq_msg_move.3 zmq_msg_size.3 \
|
|
||||||
zmq_msg_send.3 zmq_msg_recv.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_send.3 zmq_recv.3 \
|
||||||
zmq_socket_monitor.3 zmq_strerror.3 zmq_version.3 zmq_getsockopt.3 zmq_errno.3 \
|
zmq_msg_get.3 zmq_msg_set.3 zmq_msg_more.3 \
|
||||||
zmq_sendmsg.3 zmq_recvmsg.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
|
MAN7 = zmq.7 zmq_tcp.7 zmq_pgm.7 zmq_epgm.7 zmq_inproc.7 zmq_ipc.7
|
||||||
|
|
||||||
MAN_DOC = $(MAN1) $(MAN3) $(MAN7)
|
MAN_DOC = $(MAN1) $(MAN3) $(MAN7)
|
||||||
|
@ -4,7 +4,7 @@ zmq_bind(3)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
zmq_bind - accept connections on a socket
|
zmq_bind - accept incoming connections on a socket
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@ -14,34 +14,41 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
The _zmq_bind()_ function shall create an endpoint for accepting connections
|
The _zmq_bind()_ function binds the 'socket' to a local 'endpoint' and then
|
||||||
and bind it to the socket referenced by the 'socket' argument.
|
accepts incoming connections on that endpoint.
|
||||||
|
|
||||||
The 'endpoint' argument is a string consisting of two parts as follows:
|
The 'endpoint' is a string consisting of a 'transport'`://` followed by an
|
||||||
'transport'`://`'address'. The 'transport' part specifies the underlying
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
||||||
transport protocol to use. The meaning of the 'address' part is specific to
|
'address' specifies the transport-specific address to bind to.
|
||||||
the underlying transport protocol selected.
|
|
||||||
|
|
||||||
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]
|
'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]
|
'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
|
Every 0MQ socket type except 'ZMQ_PAIR' supports one-to-many and many-to-one
|
||||||
of 'ZMQ_PAIR' sockets every ZeroMQ socket type supports being bound with
|
semantics. The precise semantics depend on the socket type and are defined in
|
||||||
_zmq_bind()_ as a singular endpoint or connecting with _zmq_connect()_ as one
|
linkzmq:zmq_socket[3].
|
||||||
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
|
The 'ipc' and 'tcp' transports accept wildcard addresses: see linkzmq:zmq_ipc[7]
|
||||||
a description of the exact semantics involved when connecting or binding a socket
|
and linkzmq:zmq_tcp[7] for details.
|
||||||
to multiple endpoints.
|
|
||||||
|
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
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
The _zmq_bind()_ function shall return zero if successful. Otherwise it shall
|
The _zmq_bind()_ function returns zero if successful. Otherwise it returns
|
||||||
return `-1` and set 'errno' to one of the values defined below.
|
`-1` and sets 'errno' to one of the values defined below.
|
||||||
|
|
||||||
|
|
||||||
ERRORS
|
ERRORS
|
||||||
@ -91,5 +98,5 @@ linkzmq:zmq[7]
|
|||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
|
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
|
||||||
Martin Lucina <mato@kotelna.sk>.
|
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.
|
||||||
|
@ -4,7 +4,7 @@ zmq_connect(3)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
zmq_connect - connect a socket
|
zmq_connect - create outgoing connection from socket
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@ -14,42 +14,43 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
The _zmq_connect()_ function shall connect the socket referenced by the
|
The _zmq_connect()_ function connects the 'socket' to an 'endpoint' and then
|
||||||
'socket' argument to the endpoint specified by the 'endpoint' argument.
|
accepts incoming connections on that endpoint.
|
||||||
|
|
||||||
The 'endpoint' argument is a string consisting of two parts as follows:
|
The 'endpoint' is a string consisting of a 'transport'`://` followed by an
|
||||||
'transport'`://`'address'. The 'transport' part specifies the underlying
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
||||||
transport protocol to use. The meaning of the 'address' part is specific to
|
'address' specifies the transport-specific address to connect to.
|
||||||
the underlying transport protocol selected.
|
|
||||||
|
|
||||||
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]
|
'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]
|
'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
|
Every 0MQ socket type except 'ZMQ_PAIR' supports one-to-many and many-to-one
|
||||||
of 'ZMQ_PAIR' sockets every ZeroMQ socket type supports being bound with
|
semantics. The precise semantics depend on the socket type and are defined in
|
||||||
_zmq_bind()_ as a singular endpoint or connecting with _zmq_connect()_ as one
|
linkzmq:zmq_socket[3].
|
||||||
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.
|
|
||||||
|
|
||||||
NOTE: The connection will not be performed immediately but as needed by 0MQ.
|
NOTE: for most transports and socket types the connection is not performed
|
||||||
Thus a successful invocation of _zmq_connect()_ does not indicate that a
|
immediately but as needed by 0MQ. Thus a successful call to _zmq_connect()_
|
||||||
physical connection was or can actually be established. Because of this, for most
|
does not mean that the connection was or could actually be established.
|
||||||
socket types the order in which a listening socket is bound and a connecting socket
|
Because of this, for most transports and socket types the order in which
|
||||||
is connected does not matter. However, for inproc:// scheme sockets, the zmq_bind()
|
a 'server' socket is bound and a 'client' socket is connected to it does not
|
||||||
must be executed before any sockets zmq_connect() to that endpoint. Refer to
|
matter. The first exception is when using the inproc:// transport: you must
|
||||||
linkzmq:zmq_inproc[7] for more details.
|
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
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
The _zmq_connect()_ function shall return zero if successful. Otherwise it
|
The _zmq_connect()_ function returns zero if successful. Otherwise it returns
|
||||||
shall return `-1` and set 'errno' to one of the values defined below.
|
`-1` and sets 'errno' to one of the values defined below.
|
||||||
|
|
||||||
|
|
||||||
ERRORS
|
ERRORS
|
||||||
@ -93,5 +94,5 @@ linkzmq:zmq[7]
|
|||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
|
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
|
||||||
Martin Lucina <mato@kotelna.sk>.
|
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.
|
||||||
|
@ -34,6 +34,8 @@ The endpoint supplied is invalid.
|
|||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*ENOTSOCK*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was invalid.
|
The provided 'socket' was invalid.
|
||||||
|
*ENOENT*::
|
||||||
|
The provided endpoint is not connected.
|
||||||
|
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
|
@ -117,6 +117,7 @@ Option value unit:: N/A (bitmap)
|
|||||||
Default value:: 0
|
Default value:: 0
|
||||||
Applicable socket types:: N/A
|
Applicable socket types:: N/A
|
||||||
|
|
||||||
|
|
||||||
ZMQ_IDENTITY: Set socket identity
|
ZMQ_IDENTITY: Set socket identity
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The 'ZMQ_IDENTITY' option shall retrieve the identity of the specified 'socket'.
|
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
|
ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The option shall retrieve limit for the inbound messages. If a peer sends
|
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
|
a message larger than ZMQ_MAXMSGSIZE it is disconnected. Value of -1 means
|
||||||
'no limit'.
|
'no limit'.
|
||||||
@ -284,7 +284,6 @@ Applicable socket types:: all
|
|||||||
|
|
||||||
ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets
|
ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The option shall retrieve time-to-live used for outbound 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.
|
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
|
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`,
|
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
|
_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
|
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
|
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`,
|
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
|
_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.
|
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
|
ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Retrieve the underlying native socket type. A value of `1` will use IPv4
|
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
|
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
|
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.
|
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
|
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.
|
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
|
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
|
Default value:: N/A
|
||||||
Applicable socket types:: all
|
Applicable socket types:: all
|
||||||
|
|
||||||
|
|
||||||
ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set
|
ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The 'ZMQ_LAST_ENDPOINT' option shall retrieve the last endpoint bound for
|
The 'ZMQ_LAST_ENDPOINT' option shall retrieve the last endpoint bound for
|
||||||
@ -426,6 +422,7 @@ Option value unit:: N/A
|
|||||||
Default value:: NULL
|
Default value:: NULL
|
||||||
Applicable socket types:: all, when binding TCP or IPC transports
|
Applicable socket types:: all, when binding TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
|
ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'SO_KEEPALIVE' socket option(where supported by OS).
|
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)
|
Default value:: -1 (leave to OS default)
|
||||||
Applicable socket types:: all, when using TCP transports.
|
Applicable socket types:: all, when using TCP transports.
|
||||||
|
|
||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
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).
|
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)
|
Default value:: -1 (leave to OS default)
|
||||||
Applicable socket types:: all, when using TCP transports.
|
Applicable socket types:: all, when using TCP transports.
|
||||||
|
|
||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
|
ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'TCP_KEEPCNT' socket option(where supported by OS).
|
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)
|
Default value:: -1 (leave to OS default)
|
||||||
Applicable socket types:: all, when using TCP transports.
|
Applicable socket types:: all, when using TCP transports.
|
||||||
|
|
||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
|
ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'TCP_KEEPINTVL' socket option(where supported by OS).
|
Override 'TCP_KEEPINTVL' socket option(where supported by OS).
|
||||||
|
@ -20,11 +20,12 @@ linkzmq:zmq_init[3] for details.
|
|||||||
|
|
||||||
ADDRESSING
|
ADDRESSING
|
||||||
----------
|
----------
|
||||||
A 0MQ address string consists of two parts as follows:
|
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
|
||||||
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
||||||
transport protocol to use, and for the in-process transport shall be set to
|
'address' specifies the transport-specific address to connect to.
|
||||||
`inproc`. The meaning of the 'endpoint' part for the in-process transport is
|
|
||||||
defined below.
|
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
|
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.
|
as the 'socket' being connected.
|
||||||
|
|
||||||
|
|
||||||
WIRE FORMAT
|
|
||||||
-----------
|
|
||||||
Not applicable.
|
|
||||||
|
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
.Assigning a local address to a socket
|
.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");
|
rc = zmq_bind(socket, "inproc://#1");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
/* Assign the in-process name "my-endpoint" */
|
// Assign the in-process name "my-endpoint"
|
||||||
rc = zmq_bind(socket, "inproc://my-endpoint");
|
rc = zmq_bind(socket, "inproc://my-endpoint");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
|
|
||||||
.Connecting a socket
|
.Connecting a socket
|
||||||
----
|
----
|
||||||
/* Connect to the in-process name "#1" */
|
// Connect to the in-process name "#1"
|
||||||
rc = zmq_connect(socket, "inproc://#1");
|
rc = zmq_connect(socket, "inproc://#1");
|
||||||
assert (rc == 0);
|
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");
|
rc = zmq_connect(socket, "inproc://my-endpoint");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
@ -85,5 +81,5 @@ linkzmq:zmq[7]
|
|||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
|
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
|
||||||
Martin Lucina <mato@kotelna.sk>.
|
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.
|
||||||
|
@ -18,22 +18,31 @@ systems that provide UNIX domain sockets.
|
|||||||
|
|
||||||
ADDRESSING
|
ADDRESSING
|
||||||
----------
|
----------
|
||||||
A 0MQ address string consists of two parts as follows:
|
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
|
||||||
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
||||||
transport protocol to use, and for the inter-process transport shall be set to
|
'address' specifies the transport-specific address to connect to.
|
||||||
`ipc`. The meaning of the 'endpoint' part for the inter-process transport is
|
|
||||||
defined below.
|
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
|
Binding a socket
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
When assigning a local address to a 'socket' using _zmq_bind()_ with the 'ipc'
|
When binding a 'socket' to a local address using _zmq_bind()_ with the 'ipc'
|
||||||
transport, the 'endpoint' shall be interpreted as an arbitrary string
|
transport, the 'endpoint' shall be interpreted as an arbitrary string
|
||||||
identifying the 'pathname' to create. The 'pathname' must be unique within the
|
identifying the 'pathname' to create. The 'pathname' must be unique within the
|
||||||
operating system namespace used by the 'ipc' implementation, and must fulfill
|
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
|
any restrictions placed by the operating system on the format and length of a
|
||||||
'pathname'.
|
'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
|
Connecting a socket
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
When connecting a 'socket' to a peer address using _zmq_connect()_ with the
|
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()_.
|
'socket' with _zmq_bind()_.
|
||||||
|
|
||||||
|
|
||||||
WIRE FORMAT
|
|
||||||
-----------
|
|
||||||
Not applicable.
|
|
||||||
|
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
.Assigning a local address to a socket
|
.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");
|
rc = zmq_bind(socket, "ipc:///tmp/feeds/0");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
|
|
||||||
.Connecting a socket
|
.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");
|
rc = zmq_connect(socket, "ipc:///tmp/feeds/0");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
@ -71,10 +75,11 @@ linkzmq:zmq_connect[3]
|
|||||||
linkzmq:zmq_inproc[7]
|
linkzmq:zmq_inproc[7]
|
||||||
linkzmq:zmq_tcp[7]
|
linkzmq:zmq_tcp[7]
|
||||||
linkzmq:zmq_pgm[7]
|
linkzmq:zmq_pgm[7]
|
||||||
|
linkzmq:zmq_getsockopt[3]
|
||||||
linkzmq:zmq[7]
|
linkzmq:zmq[7]
|
||||||
|
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
|
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
|
||||||
Martin Lucina <mato@kotelna.sk>.
|
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.
|
||||||
|
@ -17,8 +17,8 @@ DESCRIPTION
|
|||||||
-----------
|
-----------
|
||||||
0MQ implements two variants of PGM, the standard protocol where PGM datagrams
|
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'
|
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
|
transport) and "Encapsulated PGM" or EPGM where PGM datagrams are encapsulated
|
||||||
UDP datagrams (the 'epgm' transport).
|
inside UDP datagrams (the 'epgm' transport).
|
||||||
|
|
||||||
The 'pgm' and 'epgm' transports can only be used with the 'ZMQ_PUB' and
|
The 'pgm' and 'epgm' transports can only be used with the 'ZMQ_PUB' and
|
||||||
'ZMQ_SUB' socket types.
|
'ZMQ_SUB' socket types.
|
||||||
@ -36,12 +36,12 @@ not require any special privileges.
|
|||||||
|
|
||||||
ADDRESSING
|
ADDRESSING
|
||||||
----------
|
----------
|
||||||
A 0MQ address string consists of two parts as follows:
|
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
|
||||||
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
||||||
transport protocol to use. For the standard PGM protocol, 'transport' shall be
|
'address' specifies the transport-specific address to connect to.
|
||||||
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'
|
For the PGM transport, the transport is `pgm`, and for the EPGM protocol the
|
||||||
transport is defined below.
|
transport is `epgm`. The meaning of the 'address' part is defined below.
|
||||||
|
|
||||||
|
|
||||||
Connecting a socket
|
Connecting a socket
|
||||||
@ -134,14 +134,14 @@ EXAMPLE
|
|||||||
-------
|
-------
|
||||||
.Connecting a socket
|
.Connecting a socket
|
||||||
----
|
----
|
||||||
/* Connecting to the multicast address 239.192.1.1, port 5555, */
|
// Connecting to the multicast address 239.192.1.1, port 5555,
|
||||||
/* using the first Ethernet network interface on Linux */
|
// using the first Ethernet network interface on Linux
|
||||||
/* and the Encapsulated PGM protocol */
|
// and the Encapsulated PGM protocol
|
||||||
rc = zmq_connect(socket, "epgm://eth0;239.192.1.1:5555");
|
rc = zmq_connect(socket, "epgm://eth0;239.192.1.1:5555");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
/* Connecting to the multicast address 239.192.1.1, port 5555, */
|
// Connecting to the multicast address 239.192.1.1, port 5555,
|
||||||
/* using the network interface with the address 192.168.1.1 */
|
// using the network interface with the address 192.168.1.1
|
||||||
/* and the standard PGM protocol */
|
// and the standard PGM protocol
|
||||||
rc = zmq_connect(socket, "pgm://192.168.1.1;239.192.1.1:5555");
|
rc = zmq_connect(socket, "pgm://192.168.1.1;239.192.1.1:5555");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
@ -158,5 +158,5 @@ linkzmq:zmq[7]
|
|||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
|
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
|
||||||
Martin Lucina <mato@kotelna.sk>.
|
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.
|
||||||
|
@ -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()_
|
are no messages available on the specified 'socket', the _zmq_recvmsg()_
|
||||||
function shall fail with 'errno' set to EAGAIN.
|
function shall fail with 'errno' set to EAGAIN.
|
||||||
|
|
||||||
|
NOTE: this API method is deprecated in favor of zmq_msg_recv(3).
|
||||||
|
|
||||||
|
|
||||||
Multi-part messages
|
Multi-part messages
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -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
|
message has been transmitted to the network, only that it has been queued on
|
||||||
the 'socket' and 0MQ has assumed responsibility for the message.
|
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
|
Multi-part messages
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -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
|
in linkzmq:zmq_socket[3] for details on the exact action taken for each socket
|
||||||
type.
|
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]
|
[horizontal]
|
||||||
Option value type:: int
|
Option value type:: int
|
||||||
Option value unit:: messages
|
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
|
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
|
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. A value of `1` returns an 'EHOSTUNREACH' error code if the message
|
||||||
routed.
|
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.
|
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Option value type:: int
|
Option value type:: int
|
||||||
|
@ -58,8 +58,8 @@ general _messaging pattern_ which is built from related socket types.
|
|||||||
|
|
||||||
Request-reply pattern
|
Request-reply pattern
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
The request-reply pattern is used for sending requests from a _client_ to one
|
The request-reply pattern is used for sending requests from a ZMQ_REQ _client_
|
||||||
or more instances of a _service_, and receiving subsequent replies to each
|
to one or more ZMQ_REP _services_, and receiving subsequent replies to each
|
||||||
request sent.
|
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
|
request sent is round-robined among all _services_, and each reply received is
|
||||||
matched with the last issued request.
|
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
|
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
|
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.
|
messages are not discarded.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
@ -84,7 +84,7 @@ Direction:: Bidirectional
|
|||||||
Send/receive pattern:: Send, Receive, Send, Receive, ...
|
Send/receive pattern:: Send, Receive, Send, Receive, ...
|
||||||
Outgoing routing strategy:: Round-robin
|
Outgoing routing strategy:: Round-robin
|
||||||
Incoming routing strategy:: Last peer
|
Incoming routing strategy:: Last peer
|
||||||
ZMQ_HWM option action:: Block
|
Action in mute state:: Block
|
||||||
|
|
||||||
|
|
||||||
ZMQ_REP
|
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
|
is routed to the _client_ that issued the last request. If the original
|
||||||
requester doesn't exist any more the reply is silently discarded.
|
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
|
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]
|
[horizontal]
|
||||||
.Summary of ZMQ_REP characteristics
|
.Summary of ZMQ_REP characteristics
|
||||||
@ -107,7 +107,7 @@ Direction:: Bidirectional
|
|||||||
Send/receive pattern:: Receive, Send, Receive, Send, ...
|
Send/receive pattern:: Receive, Send, Receive, Send, ...
|
||||||
Incoming routing strategy:: Fair-queued
|
Incoming routing strategy:: Fair-queued
|
||||||
Outgoing routing strategy:: Last peer
|
Outgoing routing strategy:: Last peer
|
||||||
ZMQ_HWM option action:: Drop
|
Action in mute state:: Drop
|
||||||
|
|
||||||
|
|
||||||
ZMQ_DEALER
|
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
|
request/reply sockets. Each message sent is round-robined among all connected
|
||||||
peers, and each message received is fair-queued from all connected peers.
|
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
|
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
|
state ends or at least one peer becomes available for sending; messages are not
|
||||||
discarded.
|
discarded.
|
||||||
|
|
||||||
@ -130,12 +130,12 @@ Deprecated alias: 'ZMQ_XREQ'.
|
|||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
.Summary of ZMQ_DEALER characteristics
|
.Summary of ZMQ_DEALER characteristics
|
||||||
Compatible peer sockets:: 'ZMQ_ROUTER', 'ZMQ_REP'
|
Compatible peer sockets:: 'ZMQ_ROUTER', 'ZMQ_REP', 'ZMQ_DEALER'
|
||||||
Direction:: Bidirectional
|
Direction:: Bidirectional
|
||||||
Send/receive pattern:: Unrestricted
|
Send/receive pattern:: Unrestricted
|
||||||
Outgoing routing strategy:: Round-robin
|
Outgoing routing strategy:: Round-robin
|
||||||
Incoming routing strategy:: Fair-queued
|
Incoming routing strategy:: Fair-queued
|
||||||
ZMQ_HWM option action:: Block
|
Action in mute state:: Block
|
||||||
|
|
||||||
|
|
||||||
ZMQ_ROUTER
|
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'
|
the message shall be silently discarded by default, unless 'ZMQ_ROUTER_BEHAVIOR'
|
||||||
socket option is set to '1'.
|
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
|
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.
|
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
|
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]
|
[horizontal]
|
||||||
.Summary of ZMQ_ROUTER characteristics
|
.Summary of ZMQ_ROUTER characteristics
|
||||||
Compatible peer sockets:: 'ZMQ_DEALER', 'ZMQ_REQ'
|
Compatible peer sockets:: 'ZMQ_DEALER', 'ZMQ_REQ', 'ZMQ_ROUTER'
|
||||||
Direction:: Bidirectional
|
Direction:: Bidirectional
|
||||||
Send/receive pattern:: Unrestricted
|
Send/receive pattern:: Unrestricted
|
||||||
Outgoing routing strategy:: See text
|
Outgoing routing strategy:: See text
|
||||||
Incoming routing strategy:: Fair-queued
|
Incoming routing strategy:: Fair-queued
|
||||||
ZMQ_HWM option action:: Drop
|
Action in mute state:: Drop
|
||||||
|
|
||||||
|
|
||||||
Publish-subscribe pattern
|
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.
|
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.
|
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
|
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.
|
ends. The _zmq_send()_ function shall never block for this socket type.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
@ -198,7 +198,7 @@ Direction:: Unidirectional
|
|||||||
Send/receive pattern:: Send only
|
Send/receive pattern:: Send only
|
||||||
Incoming routing strategy:: N/A
|
Incoming routing strategy:: N/A
|
||||||
Outgoing routing strategy:: Fan out
|
Outgoing routing strategy:: Fan out
|
||||||
ZMQ_HWM option action:: Drop
|
Action in mute state:: Drop
|
||||||
|
|
||||||
|
|
||||||
ZMQ_SUB
|
ZMQ_SUB
|
||||||
@ -216,7 +216,7 @@ Direction:: Unidirectional
|
|||||||
Send/receive pattern:: Receive only
|
Send/receive pattern:: Receive only
|
||||||
Incoming routing strategy:: Fair-queued
|
Incoming routing strategy:: Fair-queued
|
||||||
Outgoing routing strategy:: N/A
|
Outgoing routing strategy:: N/A
|
||||||
ZMQ_HWM option action:: Drop
|
Action in mute state:: Drop
|
||||||
|
|
||||||
|
|
||||||
ZMQ_XPUB
|
ZMQ_XPUB
|
||||||
@ -233,7 +233,7 @@ Direction:: Unidirectional
|
|||||||
Send/receive pattern:: Send messages, receive subscriptions
|
Send/receive pattern:: Send messages, receive subscriptions
|
||||||
Incoming routing strategy:: N/A
|
Incoming routing strategy:: N/A
|
||||||
Outgoing routing strategy:: Fan out
|
Outgoing routing strategy:: Fan out
|
||||||
ZMQ_HWM option action:: Drop
|
Action in mute state:: Drop
|
||||||
|
|
||||||
|
|
||||||
ZMQ_XSUB
|
ZMQ_XSUB
|
||||||
@ -249,7 +249,7 @@ Direction:: Unidirectional
|
|||||||
Send/receive pattern:: Receive messages, send subscriptions
|
Send/receive pattern:: Receive messages, send subscriptions
|
||||||
Incoming routing strategy:: Fair-queued
|
Incoming routing strategy:: Fair-queued
|
||||||
Outgoing routing strategy:: N/A
|
Outgoing routing strategy:: N/A
|
||||||
ZMQ_HWM option action:: Drop
|
Action in mute state:: Drop
|
||||||
|
|
||||||
|
|
||||||
Pipeline pattern
|
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
|
downstream _nodes_. The _zmq_recv()_ function is not implemented for this
|
||||||
socket type.
|
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
|
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
|
_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.
|
becomes available for sending; messages are not discarded.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
@ -280,7 +280,7 @@ Direction:: Unidirectional
|
|||||||
Send/receive pattern:: Send only
|
Send/receive pattern:: Send only
|
||||||
Incoming routing strategy:: N/A
|
Incoming routing strategy:: N/A
|
||||||
Outgoing routing strategy:: Round-robin
|
Outgoing routing strategy:: Round-robin
|
||||||
ZMQ_HWM option action:: Block
|
Action in mute state:: Block
|
||||||
|
|
||||||
|
|
||||||
ZMQ_PULL
|
ZMQ_PULL
|
||||||
@ -297,7 +297,7 @@ Direction:: Unidirectional
|
|||||||
Send/receive pattern:: Receive only
|
Send/receive pattern:: Receive only
|
||||||
Incoming routing strategy:: Fair-queued
|
Incoming routing strategy:: Fair-queued
|
||||||
Outgoing routing strategy:: N/A
|
Outgoing routing strategy:: N/A
|
||||||
ZMQ_HWM option action:: Block
|
Action in mute state:: Block
|
||||||
|
|
||||||
|
|
||||||
Exclusive pair pattern
|
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
|
time. No message routing or filtering is performed on messages sent over a
|
||||||
'ZMQ_PAIR' socket.
|
'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
|
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
|
any linkzmq:zmq_send[3] operations on the socket shall block until the peer
|
||||||
becomes available for sending; messages are not discarded.
|
becomes available for sending; messages are not discarded.
|
||||||
@ -330,7 +330,7 @@ Direction:: Bidirectional
|
|||||||
Send/receive pattern:: Unrestricted
|
Send/receive pattern:: Unrestricted
|
||||||
Incoming routing strategy:: N/A
|
Incoming routing strategy:: N/A
|
||||||
Outgoing routing strategy:: N/A
|
Outgoing routing strategy:: N/A
|
||||||
ZMQ_HWM option action:: Block
|
Action in mute state:: Block
|
||||||
|
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
|
111
doc/zmq_tcp.txt
111
doc/zmq_tcp.txt
@ -16,10 +16,12 @@ your first choice.
|
|||||||
|
|
||||||
ADDRESSING
|
ADDRESSING
|
||||||
----------
|
----------
|
||||||
A 0MQ address string consists of two parts as follows:
|
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
|
||||||
'transport'`://`'endpoint'. The 'transport' part specifies the underlying
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
||||||
transport protocol to use, and for the TCP transport shall be set to `tcp`.
|
'address' specifies the transport-specific address to connect to.
|
||||||
The meaning of the 'endpoint' part for the TCP transport is defined below.
|
|
||||||
|
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
|
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 wild-card `*`, meaning all available interfaces.
|
||||||
* The primary IPv4 or IPv6 address assigned to the interface, in its numeric
|
* The primary IPv4 or IPv6 address assigned to the interface, in its numeric
|
||||||
representation.
|
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
|
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:
|
A 'peer address' may be specified by either of the following:
|
||||||
|
|
||||||
* The DNS name of the peer.
|
* The DNS name of the peer.
|
||||||
* The IPv4 or IPv6 address of the peer, in it's numeric representation.
|
* The IPv4 or IPv6 address of the peer, in its 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 ...
|
|
||||||
+-+-+-+-+-+-+-+ ...
|
|
||||||
....
|
|
||||||
|
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
.Assigning a local address to a socket
|
.Assigning a local address to a socket
|
||||||
----
|
----
|
||||||
/* TCP port 5555 on all available interfaces */
|
// TCP port 5555 on all available interfaces
|
||||||
rc = zmq_bind(socket, "tcp://*:5555");
|
rc = zmq_bind(socket, "tcp:/// :5555");
|
||||||
assert (rc == 0);
|
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");
|
rc = zmq_bind(socket, "tcp://127.0.0.1:5555");
|
||||||
assert (rc == 0);
|
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");
|
rc = zmq_bind(socket, "tcp://eth0:5555");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
|
|
||||||
.Connecting a socket
|
.Connecting a socket
|
||||||
----
|
----
|
||||||
/* Connecting using an IP address */
|
// Connecting using an IP address
|
||||||
rc = zmq_connect(socket, "tcp://192.168.1.1:5555");
|
rc = zmq_connect(socket, "tcp://192.168.1.1:5555");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
/* Connecting using a DNS name */
|
// Connecting using a DNS name
|
||||||
rc = zmq_connect(socket, "tcp://server1:5555");
|
rc = zmq_connect(socket, "tcp://server1:5555");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
----
|
----
|
||||||
@ -158,5 +97,5 @@ linkzmq:zmq[7]
|
|||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
This 0MQ manual page was written by Martin Sustrik <sustrik@250bpm.com> and
|
This 0MQ manual page was written by Pieter Hintjens <ph@imatix.com>,
|
||||||
Martin Lucina <mato@kotelna.sk>.
|
Martin Sustrik <sustrik@250bpm.com> and Martin Lucina <mato@kotelna.sk>.
|
||||||
|
@ -60,7 +60,7 @@ extern "C" {
|
|||||||
/* Version macros for compile-time API version detection */
|
/* Version macros for compile-time API version detection */
|
||||||
#define ZMQ_VERSION_MAJOR 3
|
#define ZMQ_VERSION_MAJOR 3
|
||||||
#define ZMQ_VERSION_MINOR 2
|
#define ZMQ_VERSION_MINOR 2
|
||||||
#define ZMQ_VERSION_PATCH 1
|
#define ZMQ_VERSION_PATCH 3
|
||||||
|
|
||||||
#define ZMQ_MAKE_VERSION(major, minor, patch) \
|
#define ZMQ_MAKE_VERSION(major, minor, patch) \
|
||||||
((major) * 10000 + (minor) * 100 + (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 */
|
/* Deprecated aliases */
|
||||||
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
|
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
|
||||||
|
#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY
|
||||||
#define ZMQ_ROUTER_BEHAVIOR 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);
|
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);
|
ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture);
|
||||||
|
|
||||||
// Deprecated aliases
|
/* Deprecated aliases */
|
||||||
#define ZMQ_STREAMER 1
|
#define ZMQ_STREAMER 1
|
||||||
#define ZMQ_FORWARDER 2
|
#define ZMQ_FORWARDER 2
|
||||||
#define ZMQ_QUEUE 3
|
#define ZMQ_QUEUE 3
|
||||||
// Deprecated method
|
/* Deprecated method */
|
||||||
ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend);
|
ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend);
|
||||||
|
|
||||||
#undef ZMQ_EXPORT
|
#undef ZMQ_EXPORT
|
||||||
|
@ -23,6 +23,12 @@ libzmq_la_SOURCES = \
|
|||||||
err.hpp \
|
err.hpp \
|
||||||
fd.hpp \
|
fd.hpp \
|
||||||
fq.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_object.hpp \
|
||||||
io_thread.hpp \
|
io_thread.hpp \
|
||||||
ip.hpp \
|
ip.hpp \
|
||||||
@ -134,7 +140,10 @@ libzmq_la_SOURCES = \
|
|||||||
router.cpp \
|
router.cpp \
|
||||||
dealer.cpp \
|
dealer.cpp \
|
||||||
v1_decoder.cpp \
|
v1_decoder.cpp \
|
||||||
|
v1_decoder.hpp \
|
||||||
v1_encoder.cpp \
|
v1_encoder.cpp \
|
||||||
|
v1_encoder.hpp \
|
||||||
|
v1_protocol.hpp \
|
||||||
xsub.cpp \
|
xsub.cpp \
|
||||||
zmq.cpp \
|
zmq.cpp \
|
||||||
zmq_utils.cpp
|
zmq_utils.cpp
|
||||||
|
@ -57,11 +57,6 @@ void zmq::decoder_t::set_msg_sink (i_msg_sink *msg_sink_)
|
|||||||
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 ()
|
bool zmq::decoder_t::one_byte_size_ready ()
|
||||||
{
|
{
|
||||||
// First byte of size is read. If it is 0xff read 8-byte size.
|
// First byte of size is read. If it is 0xff read 8-byte size.
|
||||||
|
@ -143,6 +143,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:
|
protected:
|
||||||
|
|
||||||
// Prototype of state machine action. Action should return false if
|
// Prototype of state machine action. Action should return false if
|
||||||
@ -166,13 +192,13 @@ namespace zmq
|
|||||||
next = NULL;
|
next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// Next step. If set to NULL, it means that associated data stream
|
// 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
|
// is dead. Note that there can be still data in the process in such
|
||||||
// case.
|
// case.
|
||||||
step_t next;
|
step_t next;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Where to store the read data.
|
// Where to store the read data.
|
||||||
unsigned char *read_pos;
|
unsigned char *read_pos;
|
||||||
|
|
||||||
@ -199,10 +225,6 @@ namespace zmq
|
|||||||
// Set the receiver of decoded messages.
|
// Set the receiver of decoded messages.
|
||||||
void set_msg_sink (i_msg_sink *msg_sink_);
|
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:
|
private:
|
||||||
|
|
||||||
bool one_byte_size_ready ();
|
bool one_byte_size_ready ();
|
||||||
|
@ -126,6 +126,11 @@ namespace zmq
|
|||||||
*size_ = pos;
|
*size_ = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool has_data ()
|
||||||
|
{
|
||||||
|
return to_write > 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Prototype of state machine action.
|
// Prototype of state machine action.
|
||||||
|
@ -140,9 +140,10 @@ void zmq::epoll_t::loop ()
|
|||||||
// Wait for events.
|
// Wait for events.
|
||||||
int n = epoll_wait (epoll_fd, &ev_buf [0], max_io_events,
|
int n = epoll_wait (epoll_fd, &ev_buf [0], max_io_events,
|
||||||
timeout ? timeout : -1);
|
timeout ? timeout : -1);
|
||||||
if (n == -1 && errno == EINTR)
|
if (n == -1) {
|
||||||
|
errno_assert (errno == EINTR);
|
||||||
continue;
|
continue;
|
||||||
errno_assert (n != -1);
|
}
|
||||||
|
|
||||||
for (int i = 0; i < n; i ++) {
|
for (int i = 0; i < n; i ++) {
|
||||||
poll_entry_t *pe = ((poll_entry_t*) ev_buf [i].data.ptr);
|
poll_entry_t *pe = ((poll_entry_t*) ev_buf [i].data.ptr);
|
||||||
|
@ -40,7 +40,7 @@ namespace zmq
|
|||||||
|
|
||||||
virtual size_t process_buffer (unsigned char *data_, size_t size_) = 0;
|
virtual size_t process_buffer (unsigned char *data_, size_t size_) = 0;
|
||||||
|
|
||||||
virtual bool stalled () const = 0;
|
virtual bool stalled () = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ namespace zmq
|
|||||||
virtual void get_data (unsigned char **data_, size_t *size_,
|
virtual void get_data (unsigned char **data_, size_t *size_,
|
||||||
int *offset_ = NULL) = 0;
|
int *offset_ = NULL) = 0;
|
||||||
|
|
||||||
|
virtual bool has_data () = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ void zmq::ipc_connecter_t::out_event ()
|
|||||||
// Shut the connecter down.
|
// Shut the connecter down.
|
||||||
terminate ();
|
terminate ();
|
||||||
|
|
||||||
socket->event_connected (endpoint.c_str(), fd);
|
socket->event_connected (endpoint, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::ipc_connecter_t::timer_event (int id_)
|
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.
|
// 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 = add_fd (s);
|
||||||
handle_valid = true;
|
handle_valid = true;
|
||||||
set_pollout (handle);
|
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.
|
// 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();
|
int rc_ivl = get_new_reconnect_ivl();
|
||||||
add_timer (rc_ivl, reconnect_timer_id);
|
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;
|
timer_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ int zmq::ipc_connecter_t::close ()
|
|||||||
zmq_assert (s != retired_fd);
|
zmq_assert (s != retired_fd);
|
||||||
int rc = ::close (s);
|
int rc = ::close (s);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
socket->event_closed (endpoint.c_str(), s);
|
socket->event_closed (endpoint, s);
|
||||||
s = retired_fd;
|
s = retired_fd;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ void zmq::ipc_listener_t::in_event ()
|
|||||||
// If connection was reset by the peer in the meantime, just ignore it.
|
// If connection was reset by the peer in the meantime, just ignore it.
|
||||||
// TODO: Handle specific errors like ENFILE/EMFILE etc.
|
// TODO: Handle specific errors like ENFILE/EMFILE etc.
|
||||||
if (fd == retired_fd) {
|
if (fd == retired_fd) {
|
||||||
socket->event_accept_failed (endpoint.c_str(), zmq_errno());
|
socket->event_accept_failed (endpoint, zmq_errno());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ void zmq::ipc_listener_t::in_event ()
|
|||||||
session->inc_seqnum ();
|
session->inc_seqnum ();
|
||||||
launch_child (session);
|
launch_child (session);
|
||||||
send_attach (session, engine, false);
|
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_)
|
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)
|
if (rc != 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
socket->event_listening (endpoint.c_str(), s);
|
socket->event_listening (endpoint, s);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -178,12 +178,12 @@ int zmq::ipc_listener_t::close ()
|
|||||||
if (has_file && !filename.empty ()) {
|
if (has_file && !filename.empty ()) {
|
||||||
rc = ::unlink(filename.c_str ());
|
rc = ::unlink(filename.c_str ());
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
socket->event_close_failed (endpoint.c_str(), zmq_errno());
|
socket->event_close_failed (endpoint, zmq_errno());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
socket->event_closed (endpoint.c_str(), s);
|
socket->event_closed (endpoint, s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,9 +163,10 @@ void zmq::kqueue_t::loop ()
|
|||||||
timespec ts = {timeout / 1000, (timeout % 1000) * 1000000};
|
timespec ts = {timeout / 1000, (timeout % 1000) * 1000000};
|
||||||
int n = kevent (kqueue_fd, NULL, 0, &ev_buf [0], max_io_events,
|
int n = kevent (kqueue_fd, NULL, 0, &ev_buf [0], max_io_events,
|
||||||
timeout ? &ts: NULL);
|
timeout ? &ts: NULL);
|
||||||
if (n == -1 && errno == EINTR)
|
if (n == -1) {
|
||||||
|
errno_assert (errno == EINTR);
|
||||||
continue;
|
continue;
|
||||||
errno_assert (n != -1);
|
}
|
||||||
|
|
||||||
for (int i = 0; i < n; i ++) {
|
for (int i = 0; i < n; i ++) {
|
||||||
poll_entry_t *pe = (poll_entry_t*) ev_buf [i].udata;
|
poll_entry_t *pe = (poll_entry_t*) ev_buf [i].udata;
|
||||||
|
@ -35,6 +35,11 @@ zmq::mailbox_t::mailbox_t ()
|
|||||||
zmq::mailbox_t::~mailbox_t ()
|
zmq::mailbox_t::~mailbox_t ()
|
||||||
{
|
{
|
||||||
// TODO: Retrieve and deallocate commands inside the cpipe.
|
// 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 ()
|
zmq::fd_t zmq::mailbox_t::get_fd ()
|
||||||
|
@ -283,7 +283,14 @@ bool zmq::msg_t::rm_refs (int refs_)
|
|||||||
|
|
||||||
// The only message type that needs special care are long messages.
|
// The only message type that needs special care are long messages.
|
||||||
if (!u.lmsg.content->refcnt.sub (refs_)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,10 +338,11 @@ int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
|
|||||||
goto err_abort;
|
goto err_abort;
|
||||||
|
|
||||||
// Expedited Forwarding PHB for network elements, no ECN.
|
// Expedited Forwarding PHB for network elements, no ECN.
|
||||||
|
// Ignore return value due to varied runtime support.
|
||||||
const int dscp = 0x2e << 2;
|
const int dscp = 0x2e << 2;
|
||||||
if (AF_INET6 != sa_family && !pgm_setsockopt (sock,
|
if (AF_INET6 != sa_family)
|
||||||
IPPROTO_PGM, PGM_TOS, &dscp, sizeof (dscp)))
|
pgm_setsockopt (sock, IPPROTO_PGM, PGM_TOS,
|
||||||
goto err_abort;
|
&dscp, sizeof (dscp));
|
||||||
|
|
||||||
const int nonblocking = 1;
|
const int nonblocking = 1;
|
||||||
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NOBLOCK,
|
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NOBLOCK,
|
||||||
|
@ -125,10 +125,10 @@ void zmq::poll_t::loop ()
|
|||||||
|
|
||||||
// Wait for events.
|
// Wait for events.
|
||||||
int rc = poll (&pollset [0], pollset.size (), timeout ? timeout : -1);
|
int rc = poll (&pollset [0], pollset.size (), timeout ? timeout : -1);
|
||||||
if (rc == -1 && errno == EINTR)
|
if (rc == -1) {
|
||||||
|
errno_assert (errno == EINTR);
|
||||||
continue;
|
continue;
|
||||||
errno_assert (rc != -1);
|
}
|
||||||
|
|
||||||
|
|
||||||
// If there are no events (i.e. it's a timeout) there's no point
|
// If there are no events (i.e. it's a timeout) there's no point
|
||||||
// in checking the pollset.
|
// in checking the pollset.
|
||||||
|
@ -19,13 +19,42 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "../include/zmq.h"
|
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
#include "proxy.hpp"
|
#include "proxy.hpp"
|
||||||
#include "socket_base.hpp"
|
|
||||||
#include "likely.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"
|
#include "err.hpp"
|
||||||
|
|
||||||
|
// zmq.h must be included *after* poll.h for AIX to build properly
|
||||||
|
#include "../include/zmq.h"
|
||||||
|
|
||||||
|
|
||||||
int zmq::proxy (
|
int zmq::proxy (
|
||||||
class socket_base_t *frontend_,
|
class socket_base_t *frontend_,
|
||||||
class socket_base_t *backend_,
|
class socket_base_t *backend_,
|
||||||
|
@ -162,7 +162,7 @@ int zmq::router_t::xsend (msg_t *msg_, int flags_)
|
|||||||
else
|
else
|
||||||
if (mandatory) {
|
if (mandatory) {
|
||||||
more_out = false;
|
more_out = false;
|
||||||
errno = EAGAIN;
|
errno = EHOSTUNREACH;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,9 +168,10 @@ void zmq::select_t::loop ()
|
|||||||
#else
|
#else
|
||||||
int rc = select (maxfd + 1, &readfds, &writefds, &exceptfds,
|
int rc = select (maxfd + 1, &readfds, &writefds, &exceptfds,
|
||||||
timeout ? &tv : NULL);
|
timeout ? &tv : NULL);
|
||||||
if (rc == -1 && errno == EINTR)
|
if (rc == -1) {
|
||||||
|
errno_assert (errno == EINTR);
|
||||||
continue;
|
continue;
|
||||||
errno_assert (rc != -1);
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If there are no events (i.e. it's a timeout) there's no point
|
// If there are no events (i.e. it's a timeout) there's no point
|
||||||
|
@ -223,7 +223,7 @@ void zmq::session_base_t::clean_pipes ()
|
|||||||
msg_t msg;
|
msg_t msg;
|
||||||
int rc = msg.init ();
|
int rc = msg.init ();
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
if (!pull_msg (&msg)) {
|
if (pull_msg (&msg) != 0) {
|
||||||
zmq_assert (!incomplete_in);
|
zmq_assert (!incomplete_in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,10 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
|
|||||||
brc = SetEvent (sync);
|
brc = SetEvent (sync);
|
||||||
win_assert (brc != 0);
|
win_assert (brc != 0);
|
||||||
|
|
||||||
|
// Release the kernel object
|
||||||
|
brc = CloseHandle (sync);
|
||||||
|
win_assert (brc != 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#elif defined ZMQ_HAVE_OPENVMS
|
#elif defined ZMQ_HAVE_OPENVMS
|
||||||
|
@ -357,7 +357,7 @@ int zmq::socket_base_t::bind (const char *addr_)
|
|||||||
int rc = listener->set_address (address.c_str ());
|
int rc = listener->set_address (address.c_str ());
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
delete listener;
|
delete listener;
|
||||||
event_bind_failed (addr_, zmq_errno());
|
event_bind_failed (address, zmq_errno());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ int zmq::socket_base_t::bind (const char *addr_)
|
|||||||
int rc = listener->set_address (address.c_str ());
|
int rc = listener->set_address (address.c_str ());
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
delete listener;
|
delete listener;
|
||||||
event_bind_failed (addr_, zmq_errno());
|
event_bind_failed (address, zmq_errno());
|
||||||
return -1;
|
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 total HWM for an inproc connection should be the sum of
|
||||||
// the binder's HWM and the connector's HWM.
|
// the binder's HWM and the connector's HWM.
|
||||||
int sndhwm;
|
int sndhwm = 0;
|
||||||
int rcvhwm;
|
if (options.sndhwm != 0 && peer.options.rcvhwm != 0)
|
||||||
if (options.sndhwm == 0 || peer.options.rcvhwm == 0)
|
|
||||||
sndhwm = 0;
|
|
||||||
else
|
|
||||||
sndhwm = options.sndhwm + peer.options.rcvhwm;
|
sndhwm = options.sndhwm + peer.options.rcvhwm;
|
||||||
if (options.rcvhwm == 0 || peer.options.sndhwm == 0)
|
int rcvhwm = 0;
|
||||||
rcvhwm = 0;
|
if (options.rcvhwm != 0 && peer.options.sndhwm != 0)
|
||||||
else
|
|
||||||
rcvhwm = options.rcvhwm + peer.options.sndhwm;
|
rcvhwm = options.rcvhwm + peer.options.sndhwm;
|
||||||
|
|
||||||
// Create a bi-directional pipe to connect the peers.
|
// 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
|
// Save last endpoint URI
|
||||||
options.last_endpoint.assign (addr_);
|
options.last_endpoint.assign (addr_);
|
||||||
|
|
||||||
|
// remember inproc connections for disconnect
|
||||||
|
inprocs.insert (inprocs_t::value_type (std::string (addr_), pipes[0]));
|
||||||
|
|
||||||
return 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
|
#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 ();
|
paddr->resolved.ipc_addr = new (std::nothrow) ipc_address_t ();
|
||||||
alloc_assert (paddr->resolved.ipc_addr);
|
alloc_assert (paddr->resolved.ipc_addr);
|
||||||
int rc = paddr->resolved.ipc_addr->resolve (address.c_str ());
|
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))
|
if (unlikely (rc != 0))
|
||||||
return -1;
|
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.
|
// 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_));
|
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;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (endpoints_t::iterator it = range.first; it != range.second; ++it)
|
for (endpoints_t::iterator it = range.first; it != range.second; ++it)
|
||||||
term_child (it->second);
|
term_child (it->second);
|
||||||
@ -677,11 +705,6 @@ int zmq::socket_base_t::recv (msg_t *msg_, int flags_)
|
|||||||
return -1;
|
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
|
// Once every inbound_poll_rate messages check for signals and process
|
||||||
// incoming commands. This happens only if we are not polling altogether
|
// incoming commands. This happens only if we are not polling altogether
|
||||||
// because there are messages available all the time. If poll occurs,
|
// 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;
|
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 we have the message, return immediately.
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
extract_flags (msg_);
|
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.
|
// Notify the specific socket type about the pipe termination.
|
||||||
xterminated (pipe_);
|
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
|
// Remove the pipe from the list of attached pipes and confirm its
|
||||||
// termination if we are already shutting down.
|
// termination if we are already shutting down.
|
||||||
pipes.erase (pipe_);
|
pipes.erase (pipe_);
|
||||||
@ -1033,7 +1069,6 @@ int zmq::socket_base_t::monitor (const char *addr_, int events_)
|
|||||||
|
|
||||||
// Register events to monitor
|
// Register events to monitor
|
||||||
monitor_events = events_;
|
monitor_events = events_;
|
||||||
|
|
||||||
monitor_socket = zmq_socket (get_ctx (), ZMQ_PAIR);
|
monitor_socket = zmq_socket (get_ctx (), ZMQ_PAIR);
|
||||||
if (monitor_socket == NULL)
|
if (monitor_socket == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1051,115 +1086,145 @@ int zmq::socket_base_t::monitor (const char *addr_, int events_)
|
|||||||
return rc;
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_CONNECTED)) return;
|
|
||||||
event.event = ZMQ_EVENT_CONNECTED;
|
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_;
|
event.data.connected.fd = fd_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_CONNECT_DELAYED)) return;
|
|
||||||
event.event = ZMQ_EVENT_CONNECT_DELAYED;
|
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_;
|
event.data.connect_delayed.err = err_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_CONNECT_RETRIED)) return;
|
|
||||||
event.event = ZMQ_EVENT_CONNECT_RETRIED;
|
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_;
|
event.data.connect_retried.interval = interval_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_LISTENING)) return;
|
|
||||||
event.event = ZMQ_EVENT_LISTENING;
|
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_;
|
event.data.listening.fd = fd_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_BIND_FAILED)) return;
|
|
||||||
event.event = ZMQ_EVENT_BIND_FAILED;
|
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_;
|
event.data.bind_failed.err = err_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_ACCEPTED)) return;
|
|
||||||
event.event = ZMQ_EVENT_ACCEPTED;
|
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_;
|
event.data.accepted.fd = fd_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_ACCEPT_FAILED)) return;
|
|
||||||
event.event = ZMQ_EVENT_ACCEPT_FAILED;
|
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_;
|
event.data.accept_failed.err= err_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_CLOSED)) return;
|
|
||||||
event.event = ZMQ_EVENT_CLOSED;
|
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_;
|
event.data.closed.fd = fd_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_CLOSE_FAILED)) return;
|
|
||||||
event.event = ZMQ_EVENT_CLOSE_FAILED;
|
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_;
|
event.data.close_failed.err = err_;
|
||||||
monitor_event (event);
|
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;
|
zmq_event_t event;
|
||||||
if (!(monitor_events & ZMQ_EVENT_DISCONNECTED)) return;
|
|
||||||
event.event = ZMQ_EVENT_DISCONNECTED;
|
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_;
|
event.data.disconnected.fd = fd_;
|
||||||
monitor_event (event);
|
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_)
|
void zmq::socket_base_t::monitor_event (zmq_event_t event_)
|
||||||
{
|
{
|
||||||
|
if (monitor_socket) {
|
||||||
zmq_msg_t msg;
|
zmq_msg_t msg;
|
||||||
if (!monitor_socket) return;
|
void *event_data = malloc (sizeof (event_));
|
||||||
zmq_msg_init_size (&msg, sizeof (event_));
|
alloc_assert (event_data);
|
||||||
memcpy (zmq_msg_data (&msg), &event_, sizeof (event_));
|
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_sendmsg (monitor_socket, &msg, 0);
|
||||||
zmq_msg_close (&msg);
|
zmq_msg_close (&msg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void zmq::socket_base_t::stop_monitor()
|
void zmq::socket_base_t::stop_monitor()
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,11 @@
|
|||||||
#include "clock.hpp"
|
#include "clock.hpp"
|
||||||
#include "pipe.hpp"
|
#include "pipe.hpp"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void zmq_free_event (void *data, void *hint);
|
||||||
|
}
|
||||||
|
|
||||||
namespace zmq
|
namespace zmq
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -104,16 +109,16 @@ namespace zmq
|
|||||||
|
|
||||||
int monitor(const char *endpoint_, int events_);
|
int monitor(const char *endpoint_, int events_);
|
||||||
|
|
||||||
void event_connected(const char *addr_, int fd_);
|
void event_connected (std::string &addr_, int fd_);
|
||||||
void event_connect_delayed(const char *addr_, int err_);
|
void event_connect_delayed (std::string &addr_, int err_);
|
||||||
void event_connect_retried(const char *addr_, int interval_);
|
void event_connect_retried (std::string &addr_, int interval_);
|
||||||
void event_listening(const char *addr_, int fd_);
|
void event_listening (std::string &addr_, int fd_);
|
||||||
void event_bind_failed(const char *addr_, int err_);
|
void event_bind_failed (std::string &addr_, int err_);
|
||||||
void event_accepted(const char *addr_, int fd_);
|
void event_accepted (std::string &addr_, int fd_);
|
||||||
void event_accept_failed(const char *addr_, int err_);
|
void event_accept_failed (std::string &addr_, int err_);
|
||||||
void event_closed(const char *addr_, int fd_);
|
void event_closed (std::string &addr_, int fd_);
|
||||||
void event_close_failed(const char *addr_, int fd_);
|
void event_close_failed (std::string &addr_, int fd_);
|
||||||
void event_disconnected(const char *addr_, int fd_);
|
void event_disconnected (std::string &addr_, int fd_);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -151,6 +156,9 @@ namespace zmq
|
|||||||
// Socket event data dispath
|
// Socket event data dispath
|
||||||
void monitor_event (zmq_event_t data_);
|
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
|
// Monitor socket cleanup
|
||||||
void stop_monitor ();
|
void stop_monitor ();
|
||||||
|
|
||||||
@ -162,6 +170,10 @@ namespace zmq
|
|||||||
typedef std::multimap <std::string, own_t *> endpoints_t;
|
typedef std::multimap <std::string, own_t *> endpoints_t;
|
||||||
endpoints_t endpoints;
|
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
|
// To be called after processing commands or invoking any command
|
||||||
// handlers explicitly. If required, it will deallocate the socket.
|
// handlers explicitly. If required, it will deallocate the socket.
|
||||||
void check_destroy ();
|
void check_destroy ();
|
||||||
@ -240,3 +252,4 @@ namespace zmq
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -50,10 +50,10 @@
|
|||||||
|
|
||||||
zmq::stream_engine_t::stream_engine_t (fd_t fd_, const options_t &options_, const std::string &endpoint_) :
|
zmq::stream_engine_t::stream_engine_t (fd_t fd_, const options_t &options_, const std::string &endpoint_) :
|
||||||
s (fd_),
|
s (fd_),
|
||||||
|
io_enabled (false),
|
||||||
inpos (NULL),
|
inpos (NULL),
|
||||||
insize (0),
|
insize (0),
|
||||||
decoder (NULL),
|
decoder (NULL),
|
||||||
input_error (false),
|
|
||||||
outpos (NULL),
|
outpos (NULL),
|
||||||
outsize (0),
|
outsize (0),
|
||||||
encoder (NULL),
|
encoder (NULL),
|
||||||
@ -63,6 +63,7 @@ zmq::stream_engine_t::stream_engine_t (fd_t fd_, const options_t &options_, cons
|
|||||||
options (options_),
|
options (options_),
|
||||||
endpoint (endpoint_),
|
endpoint (endpoint_),
|
||||||
plugged (false),
|
plugged (false),
|
||||||
|
terminating (false),
|
||||||
socket (NULL)
|
socket (NULL)
|
||||||
{
|
{
|
||||||
// Put the socket into non-blocking mode.
|
// 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.
|
// Connect to I/O threads poller object.
|
||||||
io_object_t::plug (io_thread_);
|
io_object_t::plug (io_thread_);
|
||||||
handle = add_fd (s);
|
handle = add_fd (s);
|
||||||
|
io_enabled = true;
|
||||||
|
|
||||||
// Send the 'length' and 'flags' fields of the identity message.
|
// Send the 'length' and 'flags' fields of the identity message.
|
||||||
// The 'length' field is encoded in the long format.
|
// The 'length' field is encoded in the long format.
|
||||||
@ -153,7 +155,10 @@ void zmq::stream_engine_t::unplug ()
|
|||||||
plugged = false;
|
plugged = false;
|
||||||
|
|
||||||
// Cancel all fd subscriptions.
|
// Cancel all fd subscriptions.
|
||||||
|
if (io_enabled) {
|
||||||
rm_fd (handle);
|
rm_fd (handle);
|
||||||
|
io_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Disconnect from I/O threads poller object.
|
// Disconnect from I/O threads poller object.
|
||||||
io_object_t::unplug ();
|
io_object_t::unplug ();
|
||||||
@ -168,6 +173,11 @@ void zmq::stream_engine_t::unplug ()
|
|||||||
|
|
||||||
void zmq::stream_engine_t::terminate ()
|
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 ();
|
unplug ();
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
@ -225,9 +235,10 @@ void zmq::stream_engine_t::in_event ()
|
|||||||
// waiting for input events and postpone the termination
|
// waiting for input events and postpone the termination
|
||||||
// until after the session has accepted the message.
|
// until after the session has accepted the message.
|
||||||
if (disconnection) {
|
if (disconnection) {
|
||||||
input_error = true;
|
if (decoder->stalled ()) {
|
||||||
if (decoder->stalled ())
|
rm_fd (handle);
|
||||||
reset_pollin (handle);
|
io_enabled = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
error ();
|
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 write buffer is empty, try to read new data from the encoder.
|
||||||
if (!outsize) {
|
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;
|
outpos = NULL;
|
||||||
zmq_assert (encoder);
|
|
||||||
encoder->get_data (&outpos, &outsize);
|
encoder->get_data (&outpos, &outsize);
|
||||||
|
|
||||||
// If there is no data to send, stop polling for output.
|
// 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.
|
// this is necessary to prevent losing incomming messages.
|
||||||
if (nbytes == -1) {
|
if (nbytes == -1) {
|
||||||
reset_pollout (handle);
|
reset_pollout (handle);
|
||||||
|
if (unlikely (terminating))
|
||||||
|
terminate ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +292,10 @@ void zmq::stream_engine_t::out_event ()
|
|||||||
if (unlikely (handshaking))
|
if (unlikely (handshaking))
|
||||||
if (outsize == 0)
|
if (outsize == 0)
|
||||||
reset_pollout (handle);
|
reset_pollout (handle);
|
||||||
|
|
||||||
|
if (unlikely (terminating))
|
||||||
|
if (outsize == 0)
|
||||||
|
terminate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::stream_engine_t::activate_out ()
|
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 ()
|
void zmq::stream_engine_t::activate_in ()
|
||||||
{
|
{
|
||||||
if (input_error) {
|
if (unlikely (!io_enabled)) {
|
||||||
// There was an input error but the engine could not
|
// There was an input error but the engine could not
|
||||||
// be terminated (due to the stalled decoder).
|
// be terminated (due to the stalled decoder).
|
||||||
// Flush the pending message and terminate the engine now.
|
// 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 ()
|
void zmq::stream_engine_t::error ()
|
||||||
{
|
{
|
||||||
zmq_assert (session);
|
zmq_assert (session);
|
||||||
socket->event_disconnected (endpoint.c_str(), s);
|
socket->event_disconnected (endpoint, s);
|
||||||
session->detach ();
|
session->detach ();
|
||||||
unplug ();
|
unplug ();
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -96,12 +96,14 @@ namespace zmq
|
|||||||
// Preamble (10 bytes) + version (1 byte) + socket type (1 byte).
|
// Preamble (10 bytes) + version (1 byte) + socket type (1 byte).
|
||||||
const static size_t greeting_size = 12;
|
const static size_t greeting_size = 12;
|
||||||
|
|
||||||
|
// True iff we are registered with an I/O poller.
|
||||||
|
bool io_enabled;
|
||||||
|
|
||||||
handle_t handle;
|
handle_t handle;
|
||||||
|
|
||||||
unsigned char *inpos;
|
unsigned char *inpos;
|
||||||
size_t insize;
|
size_t insize;
|
||||||
i_decoder *decoder;
|
i_decoder *decoder;
|
||||||
bool input_error;
|
|
||||||
|
|
||||||
unsigned char *outpos;
|
unsigned char *outpos;
|
||||||
size_t outsize;
|
size_t outsize;
|
||||||
@ -133,6 +135,7 @@ namespace zmq
|
|||||||
std::string endpoint;
|
std::string endpoint;
|
||||||
|
|
||||||
bool plugged;
|
bool plugged;
|
||||||
|
bool terminating;
|
||||||
|
|
||||||
// Socket
|
// Socket
|
||||||
zmq::socket_base_t *socket;
|
zmq::socket_base_t *socket;
|
||||||
|
@ -136,7 +136,7 @@ void zmq::tcp_connecter_t::out_event ()
|
|||||||
// Shut the connecter down.
|
// Shut the connecter down.
|
||||||
terminate ();
|
terminate ();
|
||||||
|
|
||||||
socket->event_connected (endpoint.c_str(), fd);
|
socket->event_connected (endpoint, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::tcp_connecter_t::timer_event (int id_)
|
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.
|
// 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 = add_fd (s);
|
||||||
handle_valid = true;
|
handle_valid = true;
|
||||||
set_pollout (handle);
|
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.
|
// 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();
|
int rc_ivl = get_new_reconnect_ivl();
|
||||||
add_timer (rc_ivl, reconnect_timer_id);
|
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;
|
timer_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +253,7 @@ int zmq::tcp_connecter_t::open ()
|
|||||||
|
|
||||||
zmq::fd_t zmq::tcp_connecter_t::connect ()
|
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;
|
int err = 0;
|
||||||
#if defined ZMQ_HAVE_HPUX
|
#if defined ZMQ_HAVE_HPUX
|
||||||
int len = sizeof (err);
|
int len = sizeof (err);
|
||||||
@ -267,9 +268,13 @@ zmq::fd_t zmq::tcp_connecter_t::connect ()
|
|||||||
#ifdef ZMQ_HAVE_WINDOWS
|
#ifdef ZMQ_HAVE_WINDOWS
|
||||||
zmq_assert (rc == 0);
|
zmq_assert (rc == 0);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
if (err == WSAECONNREFUSED || err == WSAETIMEDOUT ||
|
if (err == WSAECONNREFUSED ||
|
||||||
err == WSAECONNABORTED || err == WSAEHOSTUNREACH ||
|
err == WSAETIMEDOUT ||
|
||||||
err == WSAENETUNREACH || err == WSAENETDOWN)
|
err == WSAECONNABORTED ||
|
||||||
|
err == WSAEHOSTUNREACH ||
|
||||||
|
err == WSAENETUNREACH ||
|
||||||
|
err == WSAENETDOWN ||
|
||||||
|
err == WSAEINVAL)
|
||||||
return retired_fd;
|
return retired_fd;
|
||||||
wsa_assert_no (err);
|
wsa_assert_no (err);
|
||||||
}
|
}
|
||||||
@ -281,9 +286,14 @@ zmq::fd_t zmq::tcp_connecter_t::connect ()
|
|||||||
err = errno;
|
err = errno;
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
errno = err;
|
errno = err;
|
||||||
errno_assert (errno == ECONNREFUSED || errno == ECONNRESET ||
|
errno_assert (
|
||||||
errno == ETIMEDOUT || errno == EHOSTUNREACH ||
|
errno == ECONNREFUSED ||
|
||||||
errno == ENETUNREACH || errno == ENETDOWN);
|
errno == ECONNRESET ||
|
||||||
|
errno == ETIMEDOUT ||
|
||||||
|
errno == EHOSTUNREACH ||
|
||||||
|
errno == ENETUNREACH ||
|
||||||
|
errno == ENETDOWN ||
|
||||||
|
errno == EINVAL);
|
||||||
return retired_fd;
|
return retired_fd;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -304,6 +314,6 @@ void zmq::tcp_connecter_t::close ()
|
|||||||
int rc = ::close (s);
|
int rc = ::close (s);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
#endif
|
#endif
|
||||||
socket->event_closed (endpoint.c_str(), s);
|
socket->event_closed (endpoint, s);
|
||||||
s = retired_fd;
|
s = retired_fd;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ void zmq::tcp_listener_t::in_event ()
|
|||||||
// If connection was reset by the peer in the meantime, just ignore it.
|
// If connection was reset by the peer in the meantime, just ignore it.
|
||||||
// TODO: Handle specific errors like ENFILE/EMFILE etc.
|
// TODO: Handle specific errors like ENFILE/EMFILE etc.
|
||||||
if (fd == retired_fd) {
|
if (fd == retired_fd) {
|
||||||
socket->event_accept_failed (endpoint.c_str(), zmq_errno());
|
socket->event_accept_failed (endpoint, zmq_errno());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ void zmq::tcp_listener_t::in_event ()
|
|||||||
session->inc_seqnum ();
|
session->inc_seqnum ();
|
||||||
launch_child (session);
|
launch_child (session);
|
||||||
send_attach (session, engine, false);
|
send_attach (session, engine, false);
|
||||||
socket->event_accepted (endpoint.c_str(), fd);
|
socket->event_accepted (endpoint, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::tcp_listener_t::close ()
|
void zmq::tcp_listener_t::close ()
|
||||||
@ -121,7 +121,7 @@ void zmq::tcp_listener_t::close ()
|
|||||||
int rc = ::close (s);
|
int rc = ::close (s);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
#endif
|
#endif
|
||||||
socket->event_closed (endpoint.c_str(), s);
|
socket->event_closed (endpoint, s);
|
||||||
s = retired_fd;
|
s = retired_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
|
|||||||
goto error;
|
goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
socket->event_listening (endpoint.c_str(), s);
|
socket->event_listening (endpoint, s);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -58,11 +58,6 @@ void zmq::v1_decoder_t::set_msg_sink (i_msg_sink *msg_sink_)
|
|||||||
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 ()
|
bool zmq::v1_decoder_t::flags_ready ()
|
||||||
{
|
{
|
||||||
msg_flags = 0;
|
msg_flags = 0;
|
||||||
|
@ -44,8 +44,6 @@ namespace zmq
|
|||||||
// i_decoder interface.
|
// i_decoder interface.
|
||||||
virtual void set_msg_sink (i_msg_sink *msg_sink_);
|
virtual void set_msg_sink (i_msg_sink *msg_sink_);
|
||||||
|
|
||||||
virtual bool stalled () const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool flags_ready ();
|
bool flags_ready ();
|
||||||
|
@ -70,8 +70,8 @@ void zmq::xpub_t::xread_activated (pipe_t *pipe_)
|
|||||||
unique = subscriptions.add (data + 1, size - 1, pipe_);
|
unique = subscriptions.add (data + 1, size - 1, pipe_);
|
||||||
|
|
||||||
// If the subscription is not a duplicate store it so that it can be
|
// If the subscription is not a duplicate store it so that it can be
|
||||||
// passed to used on next recv call.
|
// passed to used on next recv call. (Unsubscribe is not verbose.)
|
||||||
if (options.type == ZMQ_XPUB && (unique || verbose))
|
if (options.type == ZMQ_XPUB && (unique || (*data && verbose)))
|
||||||
pending.push_back (blob_t (data, size));
|
pending.push_back (blob_t (data, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
src/zmq.cpp
49
src/zmq.cpp
@ -674,12 +674,12 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
|
|||||||
int nevents = 0;
|
int nevents = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
// Compute the timeout for the subsequent poll.
|
// Compute the timeout for the subsequent poll.
|
||||||
int timeout;
|
int timeout;
|
||||||
if (first_pass)
|
if (first_pass)
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
else if (timeout_ < 0)
|
else
|
||||||
|
if (timeout_ < 0)
|
||||||
timeout = -1;
|
timeout = -1;
|
||||||
else
|
else
|
||||||
timeout = end - now;
|
timeout = end - now;
|
||||||
@ -694,7 +694,6 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
|
|||||||
errno_assert (rc >= 0);
|
errno_assert (rc >= 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for the events.
|
// Check for the events.
|
||||||
for (int i = 0; i != nitems_; i++) {
|
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;
|
timeout.tv_usec = 0;
|
||||||
ptimeout = &timeout;
|
ptimeout = &timeout;
|
||||||
}
|
}
|
||||||
else if (timeout_ < 0)
|
else
|
||||||
|
if (timeout_ < 0)
|
||||||
ptimeout = NULL;
|
ptimeout = NULL;
|
||||||
else {
|
else {
|
||||||
timeout.tv_sec = (long) ((end - now) / 1000);
|
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);
|
(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
|
// 0MQ utils - to be used by perf tests
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -17,7 +17,9 @@ noinst_PROGRAMS = test_pair_inproc \
|
|||||||
test_last_endpoint \
|
test_last_endpoint \
|
||||||
test_term_endpoint \
|
test_term_endpoint \
|
||||||
test_monitor \
|
test_monitor \
|
||||||
test_router_mandatory
|
test_router_mandatory \
|
||||||
|
test_disconnect_inproc
|
||||||
|
|
||||||
|
|
||||||
if !ON_MINGW
|
if !ON_MINGW
|
||||||
noinst_PROGRAMS += test_shutdown_stress \
|
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_last_endpoint_SOURCES = test_last_endpoint.cpp
|
||||||
test_term_endpoint_SOURCES = test_term_endpoint.cpp
|
test_term_endpoint_SOURCES = test_term_endpoint.cpp
|
||||||
test_monitor_SOURCES = test_monitor.cpp
|
test_monitor_SOURCES = test_monitor.cpp
|
||||||
|
test_disconnect_inproc_SOURCES = test_disconnect_inproc.cpp
|
||||||
test_router_mandatory_SOURCES = test_router_mandatory.cpp
|
test_router_mandatory_SOURCES = test_router_mandatory.cpp
|
||||||
|
|
||||||
if !ON_MINGW
|
if !ON_MINGW
|
||||||
|
@ -19,119 +19,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../include/zmq.h"
|
#include "../include/zmq.h"
|
||||||
|
#include "../include/zmq_utils.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
#include <assert.h>
|
#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)
|
int main (void)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "test_connect_delay running...\n");
|
fprintf (stderr, "test_connect_delay running...\n");
|
||||||
@ -140,11 +37,19 @@ int main (void)
|
|||||||
char buffer[16];
|
char buffer[16];
|
||||||
int seen = 0;
|
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();
|
void *context = zmq_ctx_new();
|
||||||
assert (context);
|
assert (context);
|
||||||
void *to = zmq_socket(context, ZMQ_PULL);
|
void *to = zmq_socket(context, ZMQ_PULL);
|
||||||
assert (to);
|
assert (to);
|
||||||
|
|
||||||
|
// Bind the one valid receiver
|
||||||
val = 0;
|
val = 0;
|
||||||
rc = zmq_setsockopt(to, ZMQ_LINGER, &val, sizeof(val));
|
rc = zmq_setsockopt(to, ZMQ_LINGER, &val, sizeof(val));
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
@ -157,11 +62,15 @@ int main (void)
|
|||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof(val));
|
zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof(val));
|
||||||
|
// This pipe will not connect
|
||||||
rc = zmq_connect (from, "tcp://localhost:5556");
|
rc = zmq_connect (from, "tcp://localhost:5556");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
// This pipe will
|
||||||
rc = zmq_connect (from, "tcp://localhost:5555");
|
rc = zmq_connect (from, "tcp://localhost:5555");
|
||||||
assert (rc == 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)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
std::string message("message ");
|
std::string message("message ");
|
||||||
@ -170,7 +79,11 @@ int main (void)
|
|||||||
assert(rc >= 0);
|
assert(rc >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1);
|
// Sleep to allow the messages to be delivered
|
||||||
|
zmq_sleep (1);
|
||||||
|
|
||||||
|
// We now consume from the connected pipe
|
||||||
|
// - we should see just 5
|
||||||
seen = 0;
|
seen = 0;
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
@ -191,9 +104,17 @@ int main (void)
|
|||||||
rc = zmq_ctx_destroy(context);
|
rc = zmq_ctx_destroy(context);
|
||||||
assert (rc == 0);
|
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();
|
context = zmq_ctx_new();
|
||||||
fprintf (stderr, " Rerunning with DELAY_ATTACH_ON_CONNECT\n");
|
fprintf (stderr, " Rerunning with DELAY_ATTACH_ON_CONNECT\n");
|
||||||
|
|
||||||
|
// Bind the valid socket
|
||||||
to = zmq_socket (context, ZMQ_PULL);
|
to = zmq_socket (context, ZMQ_PULL);
|
||||||
assert (to);
|
assert (to);
|
||||||
rc = zmq_bind (to, "tcp://*:5560");
|
rc = zmq_bind (to, "tcp://*:5560");
|
||||||
@ -211,16 +132,19 @@ int main (void)
|
|||||||
rc = zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof(val));
|
rc = zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof(val));
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Set the key flag
|
||||||
val = 1;
|
val = 1;
|
||||||
rc = zmq_setsockopt (from, ZMQ_DELAY_ATTACH_ON_CONNECT, &val, sizeof(val));
|
rc = zmq_setsockopt (from, ZMQ_DELAY_ATTACH_ON_CONNECT, &val, sizeof(val));
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Connect to the invalid socket
|
||||||
rc = zmq_connect (from, "tcp://localhost:5561");
|
rc = zmq_connect (from, "tcp://localhost:5561");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
// Connect to the valid socket
|
||||||
rc = zmq_connect (from, "tcp://localhost:5560");
|
rc = zmq_connect (from, "tcp://localhost:5560");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Send 10 messages, all should be routed to the connected pipe
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
std::string message("message ");
|
std::string message("message ");
|
||||||
@ -229,13 +153,16 @@ int main (void)
|
|||||||
assert (rc >= 0);
|
assert (rc >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1);
|
// Sleep to allow the messages to be delivered
|
||||||
|
zmq_sleep (1);
|
||||||
|
|
||||||
|
// Send 10 messages, all should arrive.
|
||||||
seen = 0;
|
seen = 0;
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
memset(&buffer, 0, sizeof(buffer));
|
memset(&buffer, 0, sizeof(buffer));
|
||||||
rc = zmq_recv (to, &buffer, sizeof(buffer), ZMQ_DONTWAIT);
|
rc = zmq_recv (to, &buffer, sizeof(buffer), ZMQ_DONTWAIT);
|
||||||
|
// If there is a failed delivery, assert!
|
||||||
assert (rc != -1);
|
assert (rc != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,15 +175,86 @@ int main (void)
|
|||||||
rc = zmq_ctx_destroy(context);
|
rc = zmq_ctx_destroy(context);
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// TEST 3
|
||||||
|
// This time we want to validate that the same blocking behaviour
|
||||||
|
// occurs with an existing connection that is broken. We will send
|
||||||
|
// messaages to a connected pipe, disconnect and verify the messages
|
||||||
|
// block. Then we reconnect and verify messages flow again.
|
||||||
|
context = zmq_ctx_new();
|
||||||
|
void *context2 = zmq_ctx_new();
|
||||||
fprintf (stderr, " Running DELAY_ATTACH_ON_CONNECT with disconnect\n");
|
fprintf (stderr, " Running DELAY_ATTACH_ON_CONNECT with disconnect\n");
|
||||||
|
|
||||||
pthread_t serv, work;
|
to = zmq_socket (context2, ZMQ_PULL);
|
||||||
|
assert (to);
|
||||||
rc = pthread_create (&serv, NULL, server, NULL);
|
rc = zmq_bind (to, "tcp://*:5560");
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
rc = pthread_create (&work, NULL, worker, NULL);
|
val = 0;
|
||||||
|
rc = zmq_setsockopt (to, ZMQ_LINGER, &val, sizeof(val));
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
pthread_exit(NULL);
|
// Create a socket pushing
|
||||||
|
from = zmq_socket (context, ZMQ_PUSH);
|
||||||
|
assert (from);
|
||||||
|
|
||||||
|
val = 0;
|
||||||
|
rc = zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof(val));
|
||||||
|
assert (rc == 0);
|
||||||
|
val = 1;
|
||||||
|
rc = zmq_setsockopt (from, ZMQ_DELAY_ATTACH_ON_CONNECT, &val, sizeof(val));
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Connect to the valid socket socket
|
||||||
|
rc = zmq_connect (from, "tcp://localhost:5560");
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Allow connections to stabilise
|
||||||
|
zmq_sleep(1);
|
||||||
|
|
||||||
|
// Send a message, should succeed
|
||||||
|
std::string message("message ");
|
||||||
|
rc = zmq_send (from, message.data(), message.size(), 0);
|
||||||
|
assert (rc >= 0);
|
||||||
|
|
||||||
|
rc = zmq_close (to);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_ctx_destroy(context2);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Give time to process disconnect
|
||||||
|
zmq_sleep(1);
|
||||||
|
|
||||||
|
// Send a message, should fail
|
||||||
|
rc = zmq_send (from, message.data(), message.size(), ZMQ_DONTWAIT);
|
||||||
|
assert (rc == -1);
|
||||||
|
|
||||||
|
context2 = zmq_ctx_new();
|
||||||
|
to = zmq_socket (context2, ZMQ_PULL);
|
||||||
|
assert (to);
|
||||||
|
rc = zmq_bind (to, "tcp://*:5560");
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
val = 0;
|
||||||
|
rc = zmq_setsockopt (to, ZMQ_LINGER, &val, sizeof(val));
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
// Allow connections to stabilise
|
||||||
|
zmq_sleep(1);
|
||||||
|
|
||||||
|
// After the reconnect, should succeed
|
||||||
|
rc = zmq_send (from, message.data(), message.size(), 0);
|
||||||
|
assert (rc >= 0);
|
||||||
|
|
||||||
|
rc = zmq_close (to);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_close (from);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_ctx_destroy(context);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_ctx_destroy(context2);
|
||||||
|
assert (rc == 0);
|
||||||
}
|
}
|
120
tests/test_disconnect_inproc.cpp
Normal file
120
tests/test_disconnect_inproc.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#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);
|
||||||
|
int msgSize = zmq_msg_size(&msg);
|
||||||
|
char* buffer = (char*)zmq_msg_data(&msg);
|
||||||
|
|
||||||
|
if (buffer[0] == 0) {
|
||||||
|
assert(isSubscribed);
|
||||||
|
printf("unsubscribing from '%s'\n", strndup(buffer + 1, msgSize - 1));
|
||||||
|
isSubscribed = false;
|
||||||
|
} else {
|
||||||
|
assert(!isSubscribed);
|
||||||
|
printf("subscribing on '%s'\n", strndup(buffer + 1, msgSize - 1));
|
||||||
|
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);
|
||||||
|
int msgSize = zmq_msg_size(&msg);
|
||||||
|
char* buffer = (char*)zmq_msg_data(&msg);
|
||||||
|
|
||||||
|
printf("received on subscriber '%s'\n", strndup(buffer, msgSize));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -49,6 +49,12 @@ int main (void)
|
|||||||
do_bind_and_verify (sb, "tcp://127.0.0.1:5561");
|
do_bind_and_verify (sb, "tcp://127.0.0.1:5561");
|
||||||
do_bind_and_verify (sb, "ipc:///tmp/testep");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ int main (void)
|
|||||||
|
|
||||||
// Send a message and check that it fails
|
// Send a message and check that it fails
|
||||||
rc = zmq_send (sa, "UNKNOWN", 7, ZMQ_SNDMORE | ZMQ_DONTWAIT);
|
rc = zmq_send (sa, "UNKNOWN", 7, ZMQ_SNDMORE | ZMQ_DONTWAIT);
|
||||||
assert (rc == -1 && errno == EAGAIN);
|
assert (rc == -1 && errno == EHOSTUNREACH);
|
||||||
|
|
||||||
rc = zmq_close (sa);
|
rc = zmq_close (sa);
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user