libzmq 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +703 -0
- data/README.md +31 -0
- data/lib/libzmq.rb +17 -0
- data/lib/libzmq/ffi-rzmq.rb +3 -0
- data/libzmq/Makefile +5 -0
- data/libzmq/extconf.rb +24 -0
- data/libzmq/zeromq-2.1.7/AUTHORS +92 -0
- data/libzmq/zeromq-2.1.7/COPYING +674 -0
- data/libzmq/zeromq-2.1.7/COPYING.LESSER +206 -0
- data/libzmq/zeromq-2.1.7/ChangeLog +15620 -0
- data/libzmq/zeromq-2.1.7/INSTALL +237 -0
- data/libzmq/zeromq-2.1.7/MAINTAINERS +56 -0
- data/libzmq/zeromq-2.1.7/Makefile.am +42 -0
- data/libzmq/zeromq-2.1.7/Makefile.in +779 -0
- data/libzmq/zeromq-2.1.7/NEWS +275 -0
- data/libzmq/zeromq-2.1.7/README +39 -0
- data/libzmq/zeromq-2.1.7/acinclude.m4 +582 -0
- data/libzmq/zeromq-2.1.7/aclocal.m4 +1206 -0
- data/libzmq/zeromq-2.1.7/autogen.sh +45 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/Makefile.am +8 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/Makefile.in +390 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/c_local_lat/c_local_lat.vcproj +176 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/c_local_thr/c_local_thr.vcproj +176 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/c_remote_lat/c_remote_lat.vcproj +176 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/c_remote_thr/c_remote_thr.vcproj +176 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/libzmq/libzmq.vcproj +783 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/msvc.sln +89 -0
- data/libzmq/zeromq-2.1.7/builds/msvc/platform.hpp +32 -0
- data/libzmq/zeromq-2.1.7/builds/redhat/zeromq.spec.in +139 -0
- data/libzmq/zeromq-2.1.7/config/compile +143 -0
- data/libzmq/zeromq-2.1.7/config/config.guess +1502 -0
- data/libzmq/zeromq-2.1.7/config/config.sub +1714 -0
- data/libzmq/zeromq-2.1.7/config/depcomp +630 -0
- data/libzmq/zeromq-2.1.7/config/install-sh +520 -0
- data/libzmq/zeromq-2.1.7/config/libtool.m4 +7377 -0
- data/libzmq/zeromq-2.1.7/config/ltmain.sh +8413 -0
- data/libzmq/zeromq-2.1.7/config/ltoptions.m4 +368 -0
- data/libzmq/zeromq-2.1.7/config/ltsugar.m4 +123 -0
- data/libzmq/zeromq-2.1.7/config/ltversion.m4 +23 -0
- data/libzmq/zeromq-2.1.7/config/lt~obsolete.m4 +92 -0
- data/libzmq/zeromq-2.1.7/config/missing +376 -0
- data/libzmq/zeromq-2.1.7/configure +21645 -0
- data/libzmq/zeromq-2.1.7/configure.in +380 -0
- data/libzmq/zeromq-2.1.7/doc/Makefile.am +46 -0
- data/libzmq/zeromq-2.1.7/doc/Makefile.in +546 -0
- data/libzmq/zeromq-2.1.7/doc/asciidoc.conf +56 -0
- data/libzmq/zeromq-2.1.7/doc/zmq.7 +242 -0
- data/libzmq/zeromq-2.1.7/doc/zmq.html +846 -0
- data/libzmq/zeromq-2.1.7/doc/zmq.txt +218 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_bind.3 +166 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_bind.html +746 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_bind.txt +91 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_close.3 +81 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_close.html +645 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_close.txt +52 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_connect.3 +161 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_connect.html +732 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_connect.txt +89 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_cpp.7 +410 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_cpp.html +765 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_cpp.txt +212 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_device.3 +140 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_device.html +736 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_device.txt +138 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_epgm.7 +209 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_epgm.html +749 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_epgm.txt +162 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_errno.3 +78 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_errno.html +634 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_errno.txt +50 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_getsockopt.3 +944 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_getsockopt.html +1713 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_getsockopt.txt +407 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_init.3 +71 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_init.html +635 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_init.txt +51 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_inproc.7 +115 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_inproc.html +669 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_inproc.txt +89 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_ipc.7 +109 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_ipc.html +662 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_ipc.txt +80 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_close.3 +81 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_close.html +647 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_close.txt +55 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_copy.3 +95 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_copy.html +656 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_copy.txt +57 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_data.3 +76 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_data.html +633 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_data.txt +48 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init.3 +110 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init.html +656 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init.txt +65 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_data.3 +138 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_data.html +678 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_data.txt +83 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_size.3 +97 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_size.html +656 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_size.txt +58 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_move.3 +79 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_move.html +645 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_move.txt +52 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_size.3 +76 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_size.html +633 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_msg_size.txt +48 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_pgm.7 +209 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_pgm.html +749 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_pgm.txt +162 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_poll.3 +204 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_poll.html +755 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_poll.txt +132 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_recv.3 +172 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_recv.html +746 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_recv.txt +121 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_send.3 +185 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_send.html +755 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_send.txt +120 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_setsockopt.3 +878 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_setsockopt.html +1603 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_setsockopt.txt +382 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_socket.3 +779 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_socket.html +1424 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_socket.txt +342 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_strerror.3 +78 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_strerror.html +634 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_strerror.txt +55 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_tcp.7 +244 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_tcp.html +755 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_tcp.txt +162 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_term.3 +135 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_term.html +672 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_term.txt +65 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_version.3 +78 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_version.html +632 -0
- data/libzmq/zeromq-2.1.7/doc/zmq_version.txt +53 -0
- data/libzmq/zeromq-2.1.7/foreign/openpgm/Makefile.am +8 -0
- data/libzmq/zeromq-2.1.7/foreign/openpgm/Makefile.in +588 -0
- data/libzmq/zeromq-2.1.7/foreign/openpgm/libpgm-5.1.115~dfsg.tar.gz +0 -0
- data/libzmq/zeromq-2.1.7/foreign/xmlParser/xmlParser.cpp +2923 -0
- data/libzmq/zeromq-2.1.7/foreign/xmlParser/xmlParser.hpp +762 -0
- data/libzmq/zeromq-2.1.7/include/zmq.h +269 -0
- data/libzmq/zeromq-2.1.7/include/zmq.hpp +301 -0
- data/libzmq/zeromq-2.1.7/include/zmq_utils.h +64 -0
- data/libzmq/zeromq-2.1.7/perf/Makefile.am +21 -0
- data/libzmq/zeromq-2.1.7/perf/Makefile.in +566 -0
- data/libzmq/zeromq-2.1.7/perf/inproc_lat.cpp +232 -0
- data/libzmq/zeromq-2.1.7/perf/inproc_thr.cpp +246 -0
- data/libzmq/zeromq-2.1.7/perf/local_lat.cpp +108 -0
- data/libzmq/zeromq-2.1.7/perf/local_thr.cpp +138 -0
- data/libzmq/zeromq-2.1.7/perf/remote_lat.cpp +121 -0
- data/libzmq/zeromq-2.1.7/perf/remote_thr.cpp +104 -0
- data/libzmq/zeromq-2.1.7/src/Makefile.am +155 -0
- data/libzmq/zeromq-2.1.7/src/Makefile.in +1320 -0
- data/libzmq/zeromq-2.1.7/src/array.hpp +147 -0
- data/libzmq/zeromq-2.1.7/src/atomic_counter.hpp +164 -0
- data/libzmq/zeromq-2.1.7/src/atomic_ptr.hpp +159 -0
- data/libzmq/zeromq-2.1.7/src/blob.hpp +34 -0
- data/libzmq/zeromq-2.1.7/src/clock.cpp +118 -0
- data/libzmq/zeromq-2.1.7/src/clock.hpp +60 -0
- data/libzmq/zeromq-2.1.7/src/command.cpp +39 -0
- data/libzmq/zeromq-2.1.7/src/command.hpp +147 -0
- data/libzmq/zeromq-2.1.7/src/config.hpp +88 -0
- data/libzmq/zeromq-2.1.7/src/connect_session.cpp +119 -0
- data/libzmq/zeromq-2.1.7/src/connect_session.hpp +65 -0
- data/libzmq/zeromq-2.1.7/src/ctx.cpp +322 -0
- data/libzmq/zeromq-2.1.7/src/ctx.hpp +159 -0
- data/libzmq/zeromq-2.1.7/src/decoder.cpp +129 -0
- data/libzmq/zeromq-2.1.7/src/decoder.hpp +207 -0
- data/libzmq/zeromq-2.1.7/src/device.cpp +120 -0
- data/libzmq/zeromq-2.1.7/src/device.hpp +32 -0
- data/libzmq/zeromq-2.1.7/src/devpoll.cpp +190 -0
- data/libzmq/zeromq-2.1.7/src/devpoll.hpp +100 -0
- data/libzmq/zeromq-2.1.7/src/dist.cpp +200 -0
- data/libzmq/zeromq-2.1.7/src/dist.hpp +90 -0
- data/libzmq/zeromq-2.1.7/src/encoder.cpp +90 -0
- data/libzmq/zeromq-2.1.7/src/encoder.hpp +184 -0
- data/libzmq/zeromq-2.1.7/src/epoll.cpp +177 -0
- data/libzmq/zeromq-2.1.7/src/epoll.hpp +96 -0
- data/libzmq/zeromq-2.1.7/src/err.cpp +238 -0
- data/libzmq/zeromq-2.1.7/src/err.hpp +145 -0
- data/libzmq/zeromq-2.1.7/src/fd.hpp +45 -0
- data/libzmq/zeromq-2.1.7/src/fq.cpp +164 -0
- data/libzmq/zeromq-2.1.7/src/fq.hpp +80 -0
- data/libzmq/zeromq-2.1.7/src/i_engine.hpp +53 -0
- data/libzmq/zeromq-2.1.7/src/i_inout.hpp +50 -0
- data/libzmq/zeromq-2.1.7/src/i_poll_events.hpp +46 -0
- data/libzmq/zeromq-2.1.7/src/io_object.cpp +107 -0
- data/libzmq/zeromq-2.1.7/src/io_object.hpp +78 -0
- data/libzmq/zeromq-2.1.7/src/io_thread.cpp +109 -0
- data/libzmq/zeromq-2.1.7/src/io_thread.hpp +88 -0
- data/libzmq/zeromq-2.1.7/src/ip.cpp +339 -0
- data/libzmq/zeromq-2.1.7/src/ip.hpp +68 -0
- data/libzmq/zeromq-2.1.7/src/kqueue.cpp +194 -0
- data/libzmq/zeromq-2.1.7/src/kqueue.hpp +103 -0
- data/libzmq/zeromq-2.1.7/src/lb.cpp +174 -0
- data/libzmq/zeromq-2.1.7/src/lb.hpp +79 -0
- data/libzmq/zeromq-2.1.7/src/libzmq.pc.in +10 -0
- data/libzmq/zeromq-2.1.7/src/likely.hpp +33 -0
- data/libzmq/zeromq-2.1.7/src/mailbox.cpp +382 -0
- data/libzmq/zeromq-2.1.7/src/mailbox.hpp +62 -0
- data/libzmq/zeromq-2.1.7/src/msg_content.hpp +52 -0
- data/libzmq/zeromq-2.1.7/src/mutex.hpp +121 -0
- data/libzmq/zeromq-2.1.7/src/named_session.cpp +85 -0
- data/libzmq/zeromq-2.1.7/src/named_session.hpp +57 -0
- data/libzmq/zeromq-2.1.7/src/object.cpp +467 -0
- data/libzmq/zeromq-2.1.7/src/object.hpp +127 -0
- data/libzmq/zeromq-2.1.7/src/options.cpp +336 -0
- data/libzmq/zeromq-2.1.7/src/options.hpp +87 -0
- data/libzmq/zeromq-2.1.7/src/own.cpp +214 -0
- data/libzmq/zeromq-2.1.7/src/own.hpp +140 -0
- data/libzmq/zeromq-2.1.7/src/pair.cpp +180 -0
- data/libzmq/zeromq-2.1.7/src/pair.hpp +76 -0
- data/libzmq/zeromq-2.1.7/src/pgm_receiver.cpp +259 -0
- data/libzmq/zeromq-2.1.7/src/pgm_receiver.hpp +129 -0
- data/libzmq/zeromq-2.1.7/src/pgm_sender.cpp +215 -0
- data/libzmq/zeromq-2.1.7/src/pgm_sender.hpp +105 -0
- data/libzmq/zeromq-2.1.7/src/pgm_socket.cpp +705 -0
- data/libzmq/zeromq-2.1.7/src/pgm_socket.hpp +118 -0
- data/libzmq/zeromq-2.1.7/src/pipe.cpp +409 -0
- data/libzmq/zeromq-2.1.7/src/pipe.hpp +214 -0
- data/libzmq/zeromq-2.1.7/src/platform.hpp.in +228 -0
- data/libzmq/zeromq-2.1.7/src/poll.cpp +180 -0
- data/libzmq/zeromq-2.1.7/src/poll.hpp +104 -0
- data/libzmq/zeromq-2.1.7/src/poller.hpp +73 -0
- data/libzmq/zeromq-2.1.7/src/poller_base.cpp +99 -0
- data/libzmq/zeromq-2.1.7/src/poller_base.hpp +84 -0
- data/libzmq/zeromq-2.1.7/src/pub.cpp +31 -0
- data/libzmq/zeromq-2.1.7/src/pub.hpp +44 -0
- data/libzmq/zeromq-2.1.7/src/pull.cpp +61 -0
- data/libzmq/zeromq-2.1.7/src/pull.hpp +60 -0
- data/libzmq/zeromq-2.1.7/src/push.cpp +62 -0
- data/libzmq/zeromq-2.1.7/src/push.hpp +59 -0
- data/libzmq/zeromq-2.1.7/src/reaper.cpp +121 -0
- data/libzmq/zeromq-2.1.7/src/reaper.hpp +77 -0
- data/libzmq/zeromq-2.1.7/src/rep.cpp +131 -0
- data/libzmq/zeromq-2.1.7/src/rep.hpp +59 -0
- data/libzmq/zeromq-2.1.7/src/req.cpp +121 -0
- data/libzmq/zeromq-2.1.7/src/req.hpp +58 -0
- data/libzmq/zeromq-2.1.7/src/select.cpp +211 -0
- data/libzmq/zeromq-2.1.7/src/select.hpp +116 -0
- data/libzmq/zeromq-2.1.7/src/semaphore.hpp +189 -0
- data/libzmq/zeromq-2.1.7/src/session.cpp +347 -0
- data/libzmq/zeromq-2.1.7/src/session.hpp +150 -0
- data/libzmq/zeromq-2.1.7/src/socket_base.cpp +811 -0
- data/libzmq/zeromq-2.1.7/src/socket_base.hpp +207 -0
- data/libzmq/zeromq-2.1.7/src/stdint.hpp +63 -0
- data/libzmq/zeromq-2.1.7/src/sub.cpp +75 -0
- data/libzmq/zeromq-2.1.7/src/sub.hpp +50 -0
- data/libzmq/zeromq-2.1.7/src/swap.cpp +325 -0
- data/libzmq/zeromq-2.1.7/src/swap.hpp +123 -0
- data/libzmq/zeromq-2.1.7/src/tcp_connecter.cpp +310 -0
- data/libzmq/zeromq-2.1.7/src/tcp_connecter.hpp +81 -0
- data/libzmq/zeromq-2.1.7/src/tcp_listener.cpp +371 -0
- data/libzmq/zeromq-2.1.7/src/tcp_listener.hpp +73 -0
- data/libzmq/zeromq-2.1.7/src/tcp_socket.cpp +228 -0
- data/libzmq/zeromq-2.1.7/src/tcp_socket.hpp +72 -0
- data/libzmq/zeromq-2.1.7/src/thread.cpp +97 -0
- data/libzmq/zeromq-2.1.7/src/thread.hpp +78 -0
- data/libzmq/zeromq-2.1.7/src/transient_session.cpp +41 -0
- data/libzmq/zeromq-2.1.7/src/transient_session.hpp +52 -0
- data/libzmq/zeromq-2.1.7/src/trie.cpp +181 -0
- data/libzmq/zeromq-2.1.7/src/trie.hpp +59 -0
- data/libzmq/zeromq-2.1.7/src/uuid.cpp +233 -0
- data/libzmq/zeromq-2.1.7/src/uuid.hpp +111 -0
- data/libzmq/zeromq-2.1.7/src/windows.hpp +79 -0
- data/libzmq/zeromq-2.1.7/src/wire.hpp +99 -0
- data/libzmq/zeromq-2.1.7/src/xpub.cpp +76 -0
- data/libzmq/zeromq-2.1.7/src/xpub.hpp +61 -0
- data/libzmq/zeromq-2.1.7/src/xrep.cpp +337 -0
- data/libzmq/zeromq-2.1.7/src/xrep.hpp +116 -0
- data/libzmq/zeromq-2.1.7/src/xreq.cpp +74 -0
- data/libzmq/zeromq-2.1.7/src/xreq.hpp +65 -0
- data/libzmq/zeromq-2.1.7/src/xsub.cpp +172 -0
- data/libzmq/zeromq-2.1.7/src/xsub.hpp +80 -0
- data/libzmq/zeromq-2.1.7/src/ypipe.hpp +209 -0
- data/libzmq/zeromq-2.1.7/src/yqueue.hpp +198 -0
- data/libzmq/zeromq-2.1.7/src/zmq.cpp +798 -0
- data/libzmq/zeromq-2.1.7/src/zmq_connecter.cpp +166 -0
- data/libzmq/zeromq-2.1.7/src/zmq_connecter.hpp +92 -0
- data/libzmq/zeromq-2.1.7/src/zmq_engine.cpp +220 -0
- data/libzmq/zeromq-2.1.7/src/zmq_engine.hpp +87 -0
- data/libzmq/zeromq-2.1.7/src/zmq_init.cpp +216 -0
- data/libzmq/zeromq-2.1.7/src/zmq_init.hpp +93 -0
- data/libzmq/zeromq-2.1.7/src/zmq_listener.cpp +78 -0
- data/libzmq/zeromq-2.1.7/src/zmq_listener.hpp +67 -0
- data/libzmq/zeromq-2.1.7/tests/Makefile.am +30 -0
- data/libzmq/zeromq-2.1.7/tests/Makefile.in +713 -0
- data/libzmq/zeromq-2.1.7/tests/test_hwm.cpp +68 -0
- data/libzmq/zeromq-2.1.7/tests/test_pair_inproc.cpp +31 -0
- data/libzmq/zeromq-2.1.7/tests/test_pair_ipc.cpp +31 -0
- data/libzmq/zeromq-2.1.7/tests/test_pair_tcp.cpp +31 -0
- data/libzmq/zeromq-2.1.7/tests/test_reqrep_inproc.cpp +31 -0
- data/libzmq/zeromq-2.1.7/tests/test_reqrep_ipc.cpp +31 -0
- data/libzmq/zeromq-2.1.7/tests/test_reqrep_tcp.cpp +31 -0
- data/libzmq/zeromq-2.1.7/tests/test_shutdown_stress.cpp +87 -0
- data/libzmq/zeromq-2.1.7/tests/testutil.hpp +130 -0
- data/libzmq/zeromq-2.1.7/version.sh +21 -0
- data/libzmq/zeromq-2.1.7/zeromq.spec +139 -0
- metadata +348 -0
@@ -0,0 +1,215 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2007-2011 iMatix Corporation
|
3
|
+
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
|
4
|
+
|
5
|
+
This file is part of 0MQ.
|
6
|
+
|
7
|
+
0MQ is free software; you can redistribute it and/or modify it under
|
8
|
+
the terms of the GNU Lesser General Public License as published by
|
9
|
+
the Free Software Foundation; either version 3 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
0MQ is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU Lesser General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Lesser General Public License
|
18
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
*/
|
20
|
+
|
21
|
+
#include "platform.hpp"
|
22
|
+
|
23
|
+
#if defined ZMQ_HAVE_OPENPGM
|
24
|
+
|
25
|
+
#ifdef ZMQ_HAVE_WINDOWS
|
26
|
+
#include "windows.hpp"
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#include <stdlib.h>
|
30
|
+
|
31
|
+
#include "io_thread.hpp"
|
32
|
+
#include "pgm_sender.hpp"
|
33
|
+
#include "err.hpp"
|
34
|
+
#include "wire.hpp"
|
35
|
+
#include "stdint.hpp"
|
36
|
+
|
37
|
+
zmq::pgm_sender_t::pgm_sender_t (io_thread_t *parent_,
|
38
|
+
const options_t &options_) :
|
39
|
+
io_object_t (parent_),
|
40
|
+
has_tx_timer (false),
|
41
|
+
has_rx_timer (false),
|
42
|
+
encoder (0),
|
43
|
+
pgm_socket (false, options_),
|
44
|
+
options (options_),
|
45
|
+
out_buffer (NULL),
|
46
|
+
out_buffer_size (0),
|
47
|
+
write_size (0)
|
48
|
+
{
|
49
|
+
}
|
50
|
+
|
51
|
+
int zmq::pgm_sender_t::init (bool udp_encapsulation_, const char *network_)
|
52
|
+
{
|
53
|
+
int rc = pgm_socket.init (udp_encapsulation_, network_);
|
54
|
+
if (rc != 0)
|
55
|
+
return rc;
|
56
|
+
|
57
|
+
out_buffer_size = pgm_socket.get_max_tsdu_size ();
|
58
|
+
out_buffer = (unsigned char*) malloc (out_buffer_size);
|
59
|
+
alloc_assert (out_buffer);
|
60
|
+
|
61
|
+
return rc;
|
62
|
+
}
|
63
|
+
|
64
|
+
void zmq::pgm_sender_t::plug (io_thread_t *io_thread_, i_inout *inout_)
|
65
|
+
{
|
66
|
+
// Alocate 2 fds for PGM socket.
|
67
|
+
int downlink_socket_fd = 0;
|
68
|
+
int uplink_socket_fd = 0;
|
69
|
+
int rdata_notify_fd = 0;
|
70
|
+
int pending_notify_fd = 0;
|
71
|
+
|
72
|
+
encoder.set_inout (inout_);
|
73
|
+
|
74
|
+
// Fill fds from PGM transport and add them to the poller.
|
75
|
+
pgm_socket.get_sender_fds (&downlink_socket_fd, &uplink_socket_fd,
|
76
|
+
&rdata_notify_fd, &pending_notify_fd);
|
77
|
+
|
78
|
+
handle = add_fd (downlink_socket_fd);
|
79
|
+
uplink_handle = add_fd (uplink_socket_fd);
|
80
|
+
rdata_notify_handle = add_fd (rdata_notify_fd);
|
81
|
+
pending_notify_handle = add_fd (pending_notify_fd);
|
82
|
+
|
83
|
+
// Set POLLIN. We wont never want to stop polling for uplink = we never
|
84
|
+
// want to stop porocess NAKs.
|
85
|
+
set_pollin (uplink_handle);
|
86
|
+
set_pollin (rdata_notify_handle);
|
87
|
+
set_pollin (pending_notify_handle);
|
88
|
+
|
89
|
+
// Set POLLOUT for downlink_socket_handle.
|
90
|
+
set_pollout (handle);
|
91
|
+
}
|
92
|
+
|
93
|
+
void zmq::pgm_sender_t::unplug ()
|
94
|
+
{
|
95
|
+
if (has_rx_timer) {
|
96
|
+
cancel_timer (rx_timer_id);
|
97
|
+
has_rx_timer = false;
|
98
|
+
}
|
99
|
+
|
100
|
+
if (has_tx_timer) {
|
101
|
+
cancel_timer (tx_timer_id);
|
102
|
+
has_tx_timer = false;
|
103
|
+
}
|
104
|
+
|
105
|
+
rm_fd (handle);
|
106
|
+
rm_fd (uplink_handle);
|
107
|
+
rm_fd (rdata_notify_handle);
|
108
|
+
rm_fd (pending_notify_handle);
|
109
|
+
encoder.set_inout (NULL);
|
110
|
+
}
|
111
|
+
|
112
|
+
void zmq::pgm_sender_t::terminate ()
|
113
|
+
{
|
114
|
+
unplug ();
|
115
|
+
delete this;
|
116
|
+
}
|
117
|
+
|
118
|
+
void zmq::pgm_sender_t::activate_out ()
|
119
|
+
{
|
120
|
+
set_pollout (handle);
|
121
|
+
out_event ();
|
122
|
+
}
|
123
|
+
|
124
|
+
void zmq::pgm_sender_t::activate_in ()
|
125
|
+
{
|
126
|
+
zmq_assert (false);
|
127
|
+
}
|
128
|
+
|
129
|
+
zmq::pgm_sender_t::~pgm_sender_t ()
|
130
|
+
{
|
131
|
+
if (out_buffer) {
|
132
|
+
free (out_buffer);
|
133
|
+
out_buffer = NULL;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
void zmq::pgm_sender_t::in_event ()
|
138
|
+
{
|
139
|
+
if (has_rx_timer) {
|
140
|
+
cancel_timer (rx_timer_id);
|
141
|
+
has_rx_timer = false;
|
142
|
+
}
|
143
|
+
|
144
|
+
// In-event on sender side means NAK or SPMR receiving from some peer.
|
145
|
+
pgm_socket.process_upstream ();
|
146
|
+
if (errno == ENOMEM || errno == EBUSY) {
|
147
|
+
const long timeout = pgm_socket.get_rx_timeout ();
|
148
|
+
add_timer (timeout, rx_timer_id);
|
149
|
+
has_rx_timer = true;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
void zmq::pgm_sender_t::out_event ()
|
154
|
+
{
|
155
|
+
// POLLOUT event from send socket. If write buffer is empty,
|
156
|
+
// try to read new data from the encoder.
|
157
|
+
if (write_size == 0) {
|
158
|
+
|
159
|
+
// First two bytes (sizeof uint16_t) are used to store message
|
160
|
+
// offset in following steps. Note that by passing our buffer to
|
161
|
+
// the get data function we prevent it from returning its own buffer.
|
162
|
+
unsigned char *bf = out_buffer + sizeof (uint16_t);
|
163
|
+
size_t bfsz = out_buffer_size - sizeof (uint16_t);
|
164
|
+
int offset = -1;
|
165
|
+
encoder.get_data (&bf, &bfsz, &offset);
|
166
|
+
|
167
|
+
// If there are no data to write stop polling for output.
|
168
|
+
if (!bfsz) {
|
169
|
+
reset_pollout (handle);
|
170
|
+
return;
|
171
|
+
}
|
172
|
+
|
173
|
+
// Put offset information in the buffer.
|
174
|
+
write_size = bfsz + sizeof (uint16_t);
|
175
|
+
put_uint16 (out_buffer, offset == -1 ? 0xffff : (uint16_t) offset);
|
176
|
+
}
|
177
|
+
|
178
|
+
if (has_tx_timer) {
|
179
|
+
cancel_timer (tx_timer_id);
|
180
|
+
has_tx_timer = false;
|
181
|
+
}
|
182
|
+
|
183
|
+
// Send the data.
|
184
|
+
size_t nbytes = pgm_socket.send (out_buffer, write_size);
|
185
|
+
|
186
|
+
// We can write either all data or 0 which means rate limit reached.
|
187
|
+
if (nbytes == write_size) {
|
188
|
+
write_size = 0;
|
189
|
+
} else {
|
190
|
+
zmq_assert (nbytes == 0);
|
191
|
+
|
192
|
+
if (errno == ENOMEM) {
|
193
|
+
const long timeout = pgm_socket.get_tx_timeout ();
|
194
|
+
add_timer (timeout, tx_timer_id);
|
195
|
+
has_tx_timer = true;
|
196
|
+
} else
|
197
|
+
zmq_assert (errno == EBUSY);
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
void zmq::pgm_sender_t::timer_event (int token)
|
202
|
+
{
|
203
|
+
// Timer cancels on return by poller_base.
|
204
|
+
if (token == rx_timer_id) {
|
205
|
+
has_rx_timer = false;
|
206
|
+
in_event ();
|
207
|
+
} else if (token == tx_timer_id) {
|
208
|
+
has_tx_timer = false;
|
209
|
+
out_event ();
|
210
|
+
} else
|
211
|
+
zmq_assert (false);
|
212
|
+
}
|
213
|
+
|
214
|
+
#endif
|
215
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2007-2011 iMatix Corporation
|
3
|
+
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
|
4
|
+
|
5
|
+
This file is part of 0MQ.
|
6
|
+
|
7
|
+
0MQ is free software; you can redistribute it and/or modify it under
|
8
|
+
the terms of the GNU Lesser General Public License as published by
|
9
|
+
the Free Software Foundation; either version 3 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
0MQ is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU Lesser General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Lesser General Public License
|
18
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
*/
|
20
|
+
|
21
|
+
#ifndef __ZMQ_PGM_SENDER_HPP_INCLUDED__
|
22
|
+
#define __ZMQ_PGM_SENDER_HPP_INCLUDED__
|
23
|
+
|
24
|
+
#include "platform.hpp"
|
25
|
+
|
26
|
+
#if defined ZMQ_HAVE_OPENPGM
|
27
|
+
|
28
|
+
#ifdef ZMQ_HAVE_WINDOWS
|
29
|
+
#include "windows.hpp"
|
30
|
+
#endif
|
31
|
+
|
32
|
+
#include "stdint.hpp"
|
33
|
+
#include "io_object.hpp"
|
34
|
+
#include "i_engine.hpp"
|
35
|
+
#include "options.hpp"
|
36
|
+
#include "pgm_socket.hpp"
|
37
|
+
#include "encoder.hpp"
|
38
|
+
|
39
|
+
namespace zmq
|
40
|
+
{
|
41
|
+
|
42
|
+
class pgm_sender_t : public io_object_t, public i_engine
|
43
|
+
{
|
44
|
+
|
45
|
+
public:
|
46
|
+
|
47
|
+
pgm_sender_t (class io_thread_t *parent_, const options_t &options_);
|
48
|
+
~pgm_sender_t ();
|
49
|
+
|
50
|
+
int init (bool udp_encapsulation_, const char *network_);
|
51
|
+
|
52
|
+
// i_engine interface implementation.
|
53
|
+
void plug (class io_thread_t *io_thread_, struct i_inout *inout_);
|
54
|
+
void unplug ();
|
55
|
+
void terminate ();
|
56
|
+
void activate_in ();
|
57
|
+
void activate_out ();
|
58
|
+
|
59
|
+
// i_poll_events interface implementation.
|
60
|
+
void in_event ();
|
61
|
+
void out_event ();
|
62
|
+
void timer_event (int token);
|
63
|
+
|
64
|
+
private:
|
65
|
+
|
66
|
+
// TX and RX timeout timer ID's.
|
67
|
+
enum {tx_timer_id = 0xa0, rx_timer_id = 0xa1};
|
68
|
+
|
69
|
+
// Timers are running.
|
70
|
+
bool has_tx_timer;
|
71
|
+
bool has_rx_timer;
|
72
|
+
|
73
|
+
// Message encoder.
|
74
|
+
encoder_t encoder;
|
75
|
+
|
76
|
+
// PGM socket.
|
77
|
+
pgm_socket_t pgm_socket;
|
78
|
+
|
79
|
+
// Socket options.
|
80
|
+
options_t options;
|
81
|
+
|
82
|
+
// Poll handle associated with PGM socket.
|
83
|
+
handle_t handle;
|
84
|
+
handle_t uplink_handle;
|
85
|
+
handle_t rdata_notify_handle;
|
86
|
+
handle_t pending_notify_handle;
|
87
|
+
|
88
|
+
// Output buffer from pgm_socket.
|
89
|
+
unsigned char *out_buffer;
|
90
|
+
|
91
|
+
// Output buffer size.
|
92
|
+
size_t out_buffer_size;
|
93
|
+
|
94
|
+
// Number of bytes in the buffer to be written to the socket.
|
95
|
+
// If zero, there are no data to be sent.
|
96
|
+
size_t write_size;
|
97
|
+
|
98
|
+
pgm_sender_t (const pgm_sender_t&);
|
99
|
+
const pgm_sender_t &operator = (const pgm_sender_t&);
|
100
|
+
};
|
101
|
+
|
102
|
+
}
|
103
|
+
#endif
|
104
|
+
|
105
|
+
#endif
|
@@ -0,0 +1,705 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2007-2011 iMatix Corporation
|
3
|
+
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
|
4
|
+
|
5
|
+
This file is part of 0MQ.
|
6
|
+
|
7
|
+
0MQ is free software; you can redistribute it and/or modify it under
|
8
|
+
the terms of the GNU Lesser General Public License as published by
|
9
|
+
the Free Software Foundation; either version 3 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
0MQ is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU Lesser General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Lesser General Public License
|
18
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
*/
|
20
|
+
|
21
|
+
#include "platform.hpp"
|
22
|
+
|
23
|
+
#ifdef ZMQ_HAVE_OPENPGM
|
24
|
+
|
25
|
+
#ifdef ZMQ_HAVE_WINDOWS
|
26
|
+
#include "windows.hpp"
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#ifdef ZMQ_HAVE_LINUX
|
30
|
+
#include <poll.h>
|
31
|
+
#endif
|
32
|
+
|
33
|
+
#include <stdlib.h>
|
34
|
+
#include <string.h>
|
35
|
+
#include <string>
|
36
|
+
|
37
|
+
#include "options.hpp"
|
38
|
+
#include "pgm_socket.hpp"
|
39
|
+
#include "config.hpp"
|
40
|
+
#include "err.hpp"
|
41
|
+
#include "uuid.hpp"
|
42
|
+
#include "stdint.hpp"
|
43
|
+
|
44
|
+
#ifndef MSG_ERRQUEUE
|
45
|
+
#define MSG_ERRQUEUE 0x2000
|
46
|
+
#endif
|
47
|
+
|
48
|
+
zmq::pgm_socket_t::pgm_socket_t (bool receiver_, const options_t &options_) :
|
49
|
+
sock (NULL),
|
50
|
+
options (options_),
|
51
|
+
receiver (receiver_),
|
52
|
+
pgm_msgv (NULL),
|
53
|
+
pgm_msgv_len (0),
|
54
|
+
nbytes_rec (0),
|
55
|
+
nbytes_processed (0),
|
56
|
+
pgm_msgv_processed (0)
|
57
|
+
{
|
58
|
+
}
|
59
|
+
|
60
|
+
// Create, bind and connect PGM socket.
|
61
|
+
// network_ of the form <interface & multicast group decls>:<IP port>
|
62
|
+
// e.g. eth0;239.192.0.1:7500
|
63
|
+
// link-local;224.250.0.1,224.250.0.2;224.250.0.3:8000
|
64
|
+
// ;[fe80::1%en0]:7500
|
65
|
+
int zmq::pgm_socket_t::init (bool udp_encapsulation_, const char *network_)
|
66
|
+
{
|
67
|
+
// Can not open transport before destroying old one.
|
68
|
+
zmq_assert (sock == NULL);
|
69
|
+
|
70
|
+
// Parse port number, start from end for IPv6
|
71
|
+
const char *port_delim = strrchr (network_, ':');
|
72
|
+
if (!port_delim) {
|
73
|
+
errno = EINVAL;
|
74
|
+
return -1;
|
75
|
+
}
|
76
|
+
|
77
|
+
uint16_t port_number = atoi (port_delim + 1);
|
78
|
+
|
79
|
+
char network [256];
|
80
|
+
if (port_delim - network_ >= (int) sizeof (network) - 1) {
|
81
|
+
errno = EINVAL;
|
82
|
+
return -1;
|
83
|
+
}
|
84
|
+
memset (network, '\0', sizeof (network));
|
85
|
+
memcpy (network, network_, port_delim - network_);
|
86
|
+
|
87
|
+
// Validate socket options
|
88
|
+
// Data rate is in [B/s]. options.rate is in [kb/s].
|
89
|
+
if (options.rate <= 0) {
|
90
|
+
errno = EINVAL;
|
91
|
+
return -1;
|
92
|
+
}
|
93
|
+
// Recovery interval [s] or [ms] - based on the user's call
|
94
|
+
if ((options.recovery_ivl <= 0) && (options.recovery_ivl_msec <= 0)) {
|
95
|
+
errno = EINVAL;
|
96
|
+
return -1;
|
97
|
+
}
|
98
|
+
|
99
|
+
// Zero counter used in msgrecv.
|
100
|
+
nbytes_rec = 0;
|
101
|
+
nbytes_processed = 0;
|
102
|
+
pgm_msgv_processed = 0;
|
103
|
+
|
104
|
+
pgm_error_t *pgm_error = NULL;
|
105
|
+
struct pgm_addrinfo_t hints, *res = NULL;
|
106
|
+
sa_family_t sa_family;
|
107
|
+
|
108
|
+
memset (&hints, 0, sizeof (hints));
|
109
|
+
hints.ai_family = AF_UNSPEC;
|
110
|
+
if (!pgm_getaddrinfo (network, NULL, &res, &pgm_error)) {
|
111
|
+
|
112
|
+
// Invalid parameters don't set pgm_error_t.
|
113
|
+
zmq_assert (pgm_error != NULL);
|
114
|
+
if (pgm_error->domain == PGM_ERROR_DOMAIN_IF && (
|
115
|
+
|
116
|
+
// NB: cannot catch EAI_BADFLAGS.
|
117
|
+
pgm_error->code != PGM_ERROR_SERVICE &&
|
118
|
+
pgm_error->code != PGM_ERROR_SOCKTNOSUPPORT))
|
119
|
+
|
120
|
+
// User, host, or network configuration or transient error.
|
121
|
+
goto err_abort;
|
122
|
+
|
123
|
+
// Fatal OpenPGM internal error.
|
124
|
+
zmq_assert (false);
|
125
|
+
}
|
126
|
+
|
127
|
+
zmq_assert (res != NULL);
|
128
|
+
|
129
|
+
// Pick up detected IP family.
|
130
|
+
sa_family = res->ai_send_addrs[0].gsr_group.ss_family;
|
131
|
+
|
132
|
+
// Create IP/PGM or UDP/PGM socket.
|
133
|
+
if (udp_encapsulation_) {
|
134
|
+
if (!pgm_socket (&sock, sa_family, SOCK_SEQPACKET, IPPROTO_UDP,
|
135
|
+
&pgm_error)) {
|
136
|
+
|
137
|
+
// Invalid parameters don't set pgm_error_t.
|
138
|
+
zmq_assert (pgm_error != NULL);
|
139
|
+
if (pgm_error->domain == PGM_ERROR_DOMAIN_SOCKET && (
|
140
|
+
pgm_error->code != PGM_ERROR_BADF &&
|
141
|
+
pgm_error->code != PGM_ERROR_FAULT &&
|
142
|
+
pgm_error->code != PGM_ERROR_NOPROTOOPT &&
|
143
|
+
pgm_error->code != PGM_ERROR_FAILED))
|
144
|
+
|
145
|
+
// User, host, or network configuration or transient error.
|
146
|
+
goto err_abort;
|
147
|
+
|
148
|
+
// Fatal OpenPGM internal error.
|
149
|
+
zmq_assert (false);
|
150
|
+
}
|
151
|
+
|
152
|
+
// All options are of data type int
|
153
|
+
const int encapsulation_port = port_number;
|
154
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_UDP_ENCAP_UCAST_PORT,
|
155
|
+
&encapsulation_port, sizeof (encapsulation_port)))
|
156
|
+
goto err_abort;
|
157
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_UDP_ENCAP_MCAST_PORT,
|
158
|
+
&encapsulation_port, sizeof (encapsulation_port)))
|
159
|
+
goto err_abort;
|
160
|
+
}
|
161
|
+
else {
|
162
|
+
if (!pgm_socket (&sock, sa_family, SOCK_SEQPACKET, IPPROTO_PGM,
|
163
|
+
&pgm_error)) {
|
164
|
+
|
165
|
+
// Invalid parameters don't set pgm_error_t.
|
166
|
+
zmq_assert (pgm_error != NULL);
|
167
|
+
if (pgm_error->domain == PGM_ERROR_DOMAIN_SOCKET && (
|
168
|
+
pgm_error->code != PGM_ERROR_BADF &&
|
169
|
+
pgm_error->code != PGM_ERROR_FAULT &&
|
170
|
+
pgm_error->code != PGM_ERROR_NOPROTOOPT &&
|
171
|
+
pgm_error->code != PGM_ERROR_FAILED))
|
172
|
+
|
173
|
+
// User, host, or network configuration or transient error.
|
174
|
+
goto err_abort;
|
175
|
+
|
176
|
+
// Fatal OpenPGM internal error.
|
177
|
+
zmq_assert (false);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
{
|
182
|
+
const int rcvbuf = (int) options.rcvbuf,
|
183
|
+
sndbuf = (int) options.sndbuf,
|
184
|
+
max_tpdu = (int) pgm_max_tpdu;
|
185
|
+
if (rcvbuf) {
|
186
|
+
if (!pgm_setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
|
187
|
+
sizeof (rcvbuf)))
|
188
|
+
goto err_abort;
|
189
|
+
}
|
190
|
+
if (sndbuf) {
|
191
|
+
if (!pgm_setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &sndbuf,
|
192
|
+
sizeof (sndbuf)))
|
193
|
+
goto err_abort;
|
194
|
+
}
|
195
|
+
|
196
|
+
// Set maximum transport protocol data unit size (TPDU).
|
197
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_MTU, &max_tpdu,
|
198
|
+
sizeof (max_tpdu)))
|
199
|
+
goto err_abort;
|
200
|
+
}
|
201
|
+
|
202
|
+
if (receiver) {
|
203
|
+
const int recv_only = 1,
|
204
|
+
rxw_max_tpdu = (int) pgm_max_tpdu,
|
205
|
+
rxw_sqns = compute_sqns (rxw_max_tpdu),
|
206
|
+
peer_expiry = pgm_secs (300),
|
207
|
+
spmr_expiry = pgm_msecs (25),
|
208
|
+
nak_bo_ivl = pgm_msecs (50),
|
209
|
+
nak_rpt_ivl = pgm_msecs (200),
|
210
|
+
nak_rdata_ivl = pgm_msecs (200),
|
211
|
+
nak_data_retries = 50,
|
212
|
+
nak_ncf_retries = 50;
|
213
|
+
|
214
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_RECV_ONLY, &recv_only,
|
215
|
+
sizeof (recv_only)) ||
|
216
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_RXW_SQNS, &rxw_sqns,
|
217
|
+
sizeof (rxw_sqns)) ||
|
218
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_PEER_EXPIRY, &peer_expiry,
|
219
|
+
sizeof (peer_expiry)) ||
|
220
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_SPMR_EXPIRY, &spmr_expiry,
|
221
|
+
sizeof (spmr_expiry)) ||
|
222
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_BO_IVL, &nak_bo_ivl,
|
223
|
+
sizeof (nak_bo_ivl)) ||
|
224
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_RPT_IVL, &nak_rpt_ivl,
|
225
|
+
sizeof (nak_rpt_ivl)) ||
|
226
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_RDATA_IVL,
|
227
|
+
&nak_rdata_ivl, sizeof (nak_rdata_ivl)) ||
|
228
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_DATA_RETRIES,
|
229
|
+
&nak_data_retries, sizeof (nak_data_retries)) ||
|
230
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NAK_NCF_RETRIES,
|
231
|
+
&nak_ncf_retries, sizeof (nak_ncf_retries)))
|
232
|
+
goto err_abort;
|
233
|
+
} else {
|
234
|
+
const int send_only = 1,
|
235
|
+
max_rte = (int) ((options.rate * 1000) / 8),
|
236
|
+
txw_max_tpdu = (int) pgm_max_tpdu,
|
237
|
+
txw_sqns = compute_sqns (txw_max_tpdu),
|
238
|
+
ambient_spm = pgm_secs (30),
|
239
|
+
heartbeat_spm[] = { pgm_msecs (100),
|
240
|
+
pgm_msecs (100),
|
241
|
+
pgm_msecs (100),
|
242
|
+
pgm_msecs (100),
|
243
|
+
pgm_msecs (1300),
|
244
|
+
pgm_secs (7),
|
245
|
+
pgm_secs (16),
|
246
|
+
pgm_secs (25),
|
247
|
+
pgm_secs (30) };
|
248
|
+
|
249
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_SEND_ONLY,
|
250
|
+
&send_only, sizeof (send_only)) ||
|
251
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_ODATA_MAX_RTE,
|
252
|
+
&max_rte, sizeof (max_rte)) ||
|
253
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_TXW_SQNS,
|
254
|
+
&txw_sqns, sizeof (txw_sqns)) ||
|
255
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_AMBIENT_SPM,
|
256
|
+
&ambient_spm, sizeof (ambient_spm)) ||
|
257
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_HEARTBEAT_SPM,
|
258
|
+
&heartbeat_spm, sizeof (heartbeat_spm)))
|
259
|
+
goto err_abort;
|
260
|
+
}
|
261
|
+
|
262
|
+
// PGM transport GSI.
|
263
|
+
struct pgm_sockaddr_t addr;
|
264
|
+
|
265
|
+
memset (&addr, 0, sizeof(addr));
|
266
|
+
addr.sa_port = port_number;
|
267
|
+
addr.sa_addr.sport = DEFAULT_DATA_SOURCE_PORT;
|
268
|
+
|
269
|
+
if (options.identity.size () > 0) {
|
270
|
+
|
271
|
+
// Create gsi from identity.
|
272
|
+
if (!pgm_gsi_create_from_data (&addr.sa_addr.gsi,
|
273
|
+
options.identity.data (), options.identity.size ()))
|
274
|
+
goto err_abort;
|
275
|
+
} else {
|
276
|
+
|
277
|
+
// Generate random gsi.
|
278
|
+
std::string gsi_base = uuid_t ().to_string ();
|
279
|
+
if (!pgm_gsi_create_from_string (&addr.sa_addr.gsi,
|
280
|
+
gsi_base.c_str (), -1))
|
281
|
+
goto err_abort;
|
282
|
+
}
|
283
|
+
|
284
|
+
// Bind a transport to the specified network devices.
|
285
|
+
struct pgm_interface_req_t if_req;
|
286
|
+
memset (&if_req, 0, sizeof(if_req));
|
287
|
+
if_req.ir_interface = res->ai_recv_addrs[0].gsr_interface;
|
288
|
+
if_req.ir_scope_id = 0;
|
289
|
+
if (AF_INET6 == sa_family) {
|
290
|
+
struct sockaddr_in6 sa6;
|
291
|
+
memcpy (&sa6, &res->ai_recv_addrs[0].gsr_group, sizeof (sa6));
|
292
|
+
if_req.ir_scope_id = sa6.sin6_scope_id;
|
293
|
+
}
|
294
|
+
if (!pgm_bind3 (sock, &addr, sizeof (addr), &if_req, sizeof (if_req),
|
295
|
+
&if_req, sizeof (if_req), &pgm_error)) {
|
296
|
+
|
297
|
+
// Invalid parameters don't set pgm_error_t.
|
298
|
+
zmq_assert (pgm_error != NULL);
|
299
|
+
if ((pgm_error->domain == PGM_ERROR_DOMAIN_SOCKET ||
|
300
|
+
pgm_error->domain == PGM_ERROR_DOMAIN_IF) && (
|
301
|
+
pgm_error->code != PGM_ERROR_INVAL &&
|
302
|
+
pgm_error->code != PGM_ERROR_BADF &&
|
303
|
+
pgm_error->code != PGM_ERROR_FAULT))
|
304
|
+
|
305
|
+
// User, host, or network configuration or transient error.
|
306
|
+
goto err_abort;
|
307
|
+
|
308
|
+
// Fatal OpenPGM internal error.
|
309
|
+
zmq_assert (false);
|
310
|
+
}
|
311
|
+
|
312
|
+
// Join IP multicast groups.
|
313
|
+
for (unsigned i = 0; i < res->ai_recv_addrs_len; i++) {
|
314
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_JOIN_GROUP,
|
315
|
+
&res->ai_recv_addrs [i], sizeof (struct group_req)))
|
316
|
+
goto err_abort;
|
317
|
+
}
|
318
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_SEND_GROUP,
|
319
|
+
&res->ai_send_addrs [0], sizeof (struct group_req)))
|
320
|
+
goto err_abort;
|
321
|
+
|
322
|
+
pgm_freeaddrinfo (res);
|
323
|
+
res = NULL;
|
324
|
+
|
325
|
+
// Set IP level parameters.
|
326
|
+
{
|
327
|
+
const int nonblocking = 1,
|
328
|
+
multicast_loop = options.use_multicast_loop ? 1 : 0,
|
329
|
+
multicast_hops = 16,
|
330
|
+
|
331
|
+
// Expedited Forwarding PHB for network elements, no ECN.
|
332
|
+
dscp = 0x2e << 2;
|
333
|
+
|
334
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_MULTICAST_LOOP,
|
335
|
+
&multicast_loop, sizeof (multicast_loop)) ||
|
336
|
+
!pgm_setsockopt (sock, IPPROTO_PGM, PGM_MULTICAST_HOPS,
|
337
|
+
&multicast_hops, sizeof (multicast_hops)))
|
338
|
+
goto err_abort;
|
339
|
+
if (AF_INET6 != sa_family && !pgm_setsockopt (sock,
|
340
|
+
IPPROTO_PGM, PGM_TOS, &dscp, sizeof (dscp)))
|
341
|
+
goto err_abort;
|
342
|
+
if (!pgm_setsockopt (sock, IPPROTO_PGM, PGM_NOBLOCK,
|
343
|
+
&nonblocking, sizeof (nonblocking)))
|
344
|
+
goto err_abort;
|
345
|
+
}
|
346
|
+
|
347
|
+
// Connect PGM transport to start state machine.
|
348
|
+
if (!pgm_connect (sock, &pgm_error)) {
|
349
|
+
|
350
|
+
// Invalid parameters don't set pgm_error_t.
|
351
|
+
zmq_assert (pgm_error != NULL);
|
352
|
+
goto err_abort;
|
353
|
+
}
|
354
|
+
|
355
|
+
// For receiver transport preallocate pgm_msgv array.
|
356
|
+
if (receiver) {
|
357
|
+
zmq_assert (in_batch_size > 0);
|
358
|
+
size_t max_tsdu_size = get_max_tsdu_size ();
|
359
|
+
pgm_msgv_len = (int) in_batch_size / max_tsdu_size;
|
360
|
+
if ((int) in_batch_size % max_tsdu_size)
|
361
|
+
pgm_msgv_len++;
|
362
|
+
zmq_assert (pgm_msgv_len);
|
363
|
+
|
364
|
+
pgm_msgv = (pgm_msgv_t*) malloc (sizeof (pgm_msgv_t) * pgm_msgv_len);
|
365
|
+
alloc_assert (pgm_msgv);
|
366
|
+
}
|
367
|
+
|
368
|
+
return 0;
|
369
|
+
|
370
|
+
err_abort:
|
371
|
+
if (sock != NULL) {
|
372
|
+
pgm_close (sock, FALSE);
|
373
|
+
sock = NULL;
|
374
|
+
}
|
375
|
+
if (res != NULL) {
|
376
|
+
pgm_freeaddrinfo (res);
|
377
|
+
res = NULL;
|
378
|
+
}
|
379
|
+
if (pgm_error != NULL) {
|
380
|
+
pgm_error_free (pgm_error);
|
381
|
+
pgm_error = NULL;
|
382
|
+
}
|
383
|
+
errno = EINVAL;
|
384
|
+
return -1;
|
385
|
+
}
|
386
|
+
|
387
|
+
zmq::pgm_socket_t::~pgm_socket_t ()
|
388
|
+
{
|
389
|
+
if (pgm_msgv)
|
390
|
+
free (pgm_msgv);
|
391
|
+
if (sock)
|
392
|
+
pgm_close (sock, TRUE);
|
393
|
+
}
|
394
|
+
|
395
|
+
// Get receiver fds. receive_fd_ is signaled for incoming packets,
|
396
|
+
// waiting_pipe_fd_ is signaled for state driven events and data.
|
397
|
+
void zmq::pgm_socket_t::get_receiver_fds (int *receive_fd_,
|
398
|
+
int *waiting_pipe_fd_)
|
399
|
+
{
|
400
|
+
socklen_t socklen;
|
401
|
+
bool rc;
|
402
|
+
|
403
|
+
zmq_assert (receive_fd_);
|
404
|
+
zmq_assert (waiting_pipe_fd_);
|
405
|
+
|
406
|
+
socklen = sizeof (*receive_fd_);
|
407
|
+
rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_RECV_SOCK, receive_fd_,
|
408
|
+
&socklen);
|
409
|
+
zmq_assert (rc);
|
410
|
+
zmq_assert (socklen == sizeof (*receive_fd_));
|
411
|
+
|
412
|
+
socklen = sizeof (*waiting_pipe_fd_);
|
413
|
+
rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_PENDING_SOCK, waiting_pipe_fd_,
|
414
|
+
&socklen);
|
415
|
+
zmq_assert (rc);
|
416
|
+
zmq_assert (socklen == sizeof (*waiting_pipe_fd_));
|
417
|
+
}
|
418
|
+
|
419
|
+
// Get fds and store them into user allocated memory.
|
420
|
+
// send_fd is for non-blocking send wire notifications.
|
421
|
+
// receive_fd_ is for incoming back-channel protocol packets.
|
422
|
+
// rdata_notify_fd_ is raised for waiting repair transmissions.
|
423
|
+
// pending_notify_fd_ is for state driven events.
|
424
|
+
void zmq::pgm_socket_t::get_sender_fds (int *send_fd_, int *receive_fd_,
|
425
|
+
int *rdata_notify_fd_, int *pending_notify_fd_)
|
426
|
+
{
|
427
|
+
socklen_t socklen;
|
428
|
+
bool rc;
|
429
|
+
|
430
|
+
zmq_assert (send_fd_);
|
431
|
+
zmq_assert (receive_fd_);
|
432
|
+
zmq_assert (rdata_notify_fd_);
|
433
|
+
zmq_assert (pending_notify_fd_);
|
434
|
+
|
435
|
+
socklen = sizeof (*send_fd_);
|
436
|
+
rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_SEND_SOCK, send_fd_, &socklen);
|
437
|
+
zmq_assert (rc);
|
438
|
+
zmq_assert (socklen == sizeof (*receive_fd_));
|
439
|
+
|
440
|
+
socklen = sizeof (*receive_fd_);
|
441
|
+
rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_RECV_SOCK, receive_fd_,
|
442
|
+
&socklen);
|
443
|
+
zmq_assert (rc);
|
444
|
+
zmq_assert (socklen == sizeof (*receive_fd_));
|
445
|
+
|
446
|
+
socklen = sizeof (*rdata_notify_fd_);
|
447
|
+
rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_REPAIR_SOCK, rdata_notify_fd_,
|
448
|
+
&socklen);
|
449
|
+
zmq_assert (rc);
|
450
|
+
zmq_assert (socklen == sizeof (*rdata_notify_fd_));
|
451
|
+
|
452
|
+
socklen = sizeof (*pending_notify_fd_);
|
453
|
+
rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_PENDING_SOCK,
|
454
|
+
pending_notify_fd_, &socklen);
|
455
|
+
zmq_assert (rc);
|
456
|
+
zmq_assert (socklen == sizeof (*pending_notify_fd_));
|
457
|
+
}
|
458
|
+
|
459
|
+
// Send one APDU, transmit window owned memory.
|
460
|
+
// data_len_ must be less than one TPDU.
|
461
|
+
size_t zmq::pgm_socket_t::send (unsigned char *data_, size_t data_len_)
|
462
|
+
{
|
463
|
+
size_t nbytes = 0;
|
464
|
+
|
465
|
+
const int status = pgm_send (sock, data_, data_len_, &nbytes);
|
466
|
+
|
467
|
+
// We have to write all data as one packet.
|
468
|
+
if (nbytes > 0) {
|
469
|
+
zmq_assert (status == PGM_IO_STATUS_NORMAL);
|
470
|
+
zmq_assert ((ssize_t) nbytes == (ssize_t) data_len_);
|
471
|
+
} else {
|
472
|
+
zmq_assert (status == PGM_IO_STATUS_RATE_LIMITED ||
|
473
|
+
status == PGM_IO_STATUS_WOULD_BLOCK);
|
474
|
+
|
475
|
+
if (status == PGM_IO_STATUS_RATE_LIMITED)
|
476
|
+
errno = ENOMEM;
|
477
|
+
else
|
478
|
+
errno = EBUSY;
|
479
|
+
}
|
480
|
+
|
481
|
+
// Save return value.
|
482
|
+
last_tx_status = status;
|
483
|
+
|
484
|
+
return nbytes;
|
485
|
+
}
|
486
|
+
|
487
|
+
long zmq::pgm_socket_t::get_rx_timeout ()
|
488
|
+
{
|
489
|
+
if (last_rx_status != PGM_IO_STATUS_RATE_LIMITED &&
|
490
|
+
last_rx_status != PGM_IO_STATUS_TIMER_PENDING)
|
491
|
+
return -1;
|
492
|
+
|
493
|
+
struct timeval tv;
|
494
|
+
socklen_t optlen = sizeof (tv);
|
495
|
+
const bool rc = pgm_getsockopt (sock, IPPROTO_PGM,
|
496
|
+
last_rx_status == PGM_IO_STATUS_RATE_LIMITED ? PGM_RATE_REMAIN :
|
497
|
+
PGM_TIME_REMAIN, &tv, &optlen);
|
498
|
+
zmq_assert (rc);
|
499
|
+
|
500
|
+
const long timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
501
|
+
|
502
|
+
return timeout;
|
503
|
+
}
|
504
|
+
|
505
|
+
long zmq::pgm_socket_t::get_tx_timeout ()
|
506
|
+
{
|
507
|
+
if (last_tx_status != PGM_IO_STATUS_RATE_LIMITED)
|
508
|
+
return -1;
|
509
|
+
|
510
|
+
struct timeval tv;
|
511
|
+
socklen_t optlen = sizeof (tv);
|
512
|
+
const bool rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_RATE_REMAIN, &tv,
|
513
|
+
&optlen);
|
514
|
+
zmq_assert (rc);
|
515
|
+
|
516
|
+
const long timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
517
|
+
|
518
|
+
return timeout;
|
519
|
+
}
|
520
|
+
|
521
|
+
// Return max TSDU size without fragmentation from current PGM transport.
|
522
|
+
size_t zmq::pgm_socket_t::get_max_tsdu_size ()
|
523
|
+
{
|
524
|
+
int max_tsdu = 0;
|
525
|
+
socklen_t optlen = sizeof (max_tsdu);
|
526
|
+
|
527
|
+
bool rc = pgm_getsockopt (sock, IPPROTO_PGM, PGM_MSS, &max_tsdu, &optlen);
|
528
|
+
zmq_assert (rc);
|
529
|
+
zmq_assert (optlen == sizeof (max_tsdu));
|
530
|
+
return (size_t) max_tsdu;
|
531
|
+
}
|
532
|
+
|
533
|
+
// pgm_recvmsgv is called to fill the pgm_msgv array up to pgm_msgv_len.
|
534
|
+
// In subsequent calls data from pgm_msgv structure are returned.
|
535
|
+
ssize_t zmq::pgm_socket_t::receive (void **raw_data_, const pgm_tsi_t **tsi_)
|
536
|
+
{
|
537
|
+
size_t raw_data_len = 0;
|
538
|
+
|
539
|
+
// We just sent all data from pgm_transport_recvmsgv up
|
540
|
+
// and have to return 0 that another engine in this thread is scheduled.
|
541
|
+
if (nbytes_rec == nbytes_processed && nbytes_rec > 0) {
|
542
|
+
|
543
|
+
// Reset all the counters.
|
544
|
+
nbytes_rec = 0;
|
545
|
+
nbytes_processed = 0;
|
546
|
+
pgm_msgv_processed = 0;
|
547
|
+
errno = EAGAIN;
|
548
|
+
return 0;
|
549
|
+
}
|
550
|
+
|
551
|
+
// If we have are going first time or if we have processed all pgm_msgv_t
|
552
|
+
// structure previously read from the pgm socket.
|
553
|
+
if (nbytes_rec == nbytes_processed) {
|
554
|
+
|
555
|
+
// Check program flow.
|
556
|
+
zmq_assert (pgm_msgv_processed == 0);
|
557
|
+
zmq_assert (nbytes_processed == 0);
|
558
|
+
zmq_assert (nbytes_rec == 0);
|
559
|
+
|
560
|
+
// Receive a vector of Application Protocol Domain Unit's (APDUs)
|
561
|
+
// from the transport.
|
562
|
+
pgm_error_t *pgm_error = NULL;
|
563
|
+
|
564
|
+
const int status = pgm_recvmsgv (sock, pgm_msgv,
|
565
|
+
pgm_msgv_len, MSG_ERRQUEUE, &nbytes_rec, &pgm_error);
|
566
|
+
|
567
|
+
// Invalid parameters.
|
568
|
+
zmq_assert (status != PGM_IO_STATUS_ERROR);
|
569
|
+
|
570
|
+
last_rx_status = status;
|
571
|
+
|
572
|
+
// In a case when no ODATA/RDATA fired POLLIN event (SPM...)
|
573
|
+
// pgm_recvmsg returns PGM_IO_STATUS_TIMER_PENDING.
|
574
|
+
if (status == PGM_IO_STATUS_TIMER_PENDING) {
|
575
|
+
|
576
|
+
zmq_assert (nbytes_rec == 0);
|
577
|
+
|
578
|
+
// In case if no RDATA/ODATA caused POLLIN 0 is
|
579
|
+
// returned.
|
580
|
+
nbytes_rec = 0;
|
581
|
+
errno = EBUSY;
|
582
|
+
return 0;
|
583
|
+
}
|
584
|
+
|
585
|
+
// Send SPMR, NAK, ACK is rate limited.
|
586
|
+
if (status == PGM_IO_STATUS_RATE_LIMITED) {
|
587
|
+
|
588
|
+
zmq_assert (nbytes_rec == 0);
|
589
|
+
|
590
|
+
// In case if no RDATA/ODATA caused POLLIN 0 is returned.
|
591
|
+
nbytes_rec = 0;
|
592
|
+
errno = ENOMEM;
|
593
|
+
return 0;
|
594
|
+
}
|
595
|
+
|
596
|
+
// No peers and hence no incoming packets.
|
597
|
+
if (status == PGM_IO_STATUS_WOULD_BLOCK) {
|
598
|
+
|
599
|
+
zmq_assert (nbytes_rec == 0);
|
600
|
+
|
601
|
+
// In case if no RDATA/ODATA caused POLLIN 0 is returned.
|
602
|
+
nbytes_rec = 0;
|
603
|
+
errno = EAGAIN;
|
604
|
+
return 0;
|
605
|
+
}
|
606
|
+
|
607
|
+
// Data loss.
|
608
|
+
if (status == PGM_IO_STATUS_RESET) {
|
609
|
+
|
610
|
+
struct pgm_sk_buff_t* skb = pgm_msgv [0].msgv_skb [0];
|
611
|
+
|
612
|
+
// Save lost data TSI.
|
613
|
+
*tsi_ = &skb->tsi;
|
614
|
+
nbytes_rec = 0;
|
615
|
+
|
616
|
+
// In case of dala loss -1 is returned.
|
617
|
+
errno = EINVAL;
|
618
|
+
pgm_free_skb (skb);
|
619
|
+
return -1;
|
620
|
+
}
|
621
|
+
|
622
|
+
zmq_assert (status == PGM_IO_STATUS_NORMAL);
|
623
|
+
}
|
624
|
+
else
|
625
|
+
{
|
626
|
+
zmq_assert (pgm_msgv_processed <= pgm_msgv_len);
|
627
|
+
}
|
628
|
+
|
629
|
+
// Zero byte payloads are valid in PGM, but not 0MQ protocol.
|
630
|
+
zmq_assert (nbytes_rec > 0);
|
631
|
+
|
632
|
+
// Only one APDU per pgm_msgv_t structure is allowed.
|
633
|
+
zmq_assert (pgm_msgv [pgm_msgv_processed].msgv_len == 1);
|
634
|
+
|
635
|
+
struct pgm_sk_buff_t* skb =
|
636
|
+
pgm_msgv [pgm_msgv_processed].msgv_skb [0];
|
637
|
+
|
638
|
+
// Take pointers from pgm_msgv_t structure.
|
639
|
+
*raw_data_ = skb->data;
|
640
|
+
raw_data_len = skb->len;
|
641
|
+
|
642
|
+
// Save current TSI.
|
643
|
+
*tsi_ = &skb->tsi;
|
644
|
+
|
645
|
+
// Move the the next pgm_msgv_t structure.
|
646
|
+
pgm_msgv_processed++;
|
647
|
+
zmq_assert (pgm_msgv_processed <= pgm_msgv_len);
|
648
|
+
nbytes_processed +=raw_data_len;
|
649
|
+
|
650
|
+
return raw_data_len;
|
651
|
+
}
|
652
|
+
|
653
|
+
void zmq::pgm_socket_t::process_upstream ()
|
654
|
+
{
|
655
|
+
pgm_msgv_t dummy_msg;
|
656
|
+
|
657
|
+
size_t dummy_bytes = 0;
|
658
|
+
pgm_error_t *pgm_error = NULL;
|
659
|
+
|
660
|
+
const int status = pgm_recvmsgv (sock, &dummy_msg,
|
661
|
+
1, MSG_ERRQUEUE, &dummy_bytes, &pgm_error);
|
662
|
+
|
663
|
+
// Invalid parameters.
|
664
|
+
zmq_assert (status != PGM_IO_STATUS_ERROR);
|
665
|
+
|
666
|
+
// No data should be returned.
|
667
|
+
zmq_assert (dummy_bytes == 0 && (status == PGM_IO_STATUS_TIMER_PENDING ||
|
668
|
+
status == PGM_IO_STATUS_RATE_LIMITED ||
|
669
|
+
status == PGM_IO_STATUS_WOULD_BLOCK));
|
670
|
+
|
671
|
+
last_rx_status = status;
|
672
|
+
|
673
|
+
if (status == PGM_IO_STATUS_TIMER_PENDING)
|
674
|
+
errno = EBUSY;
|
675
|
+
else if (status == PGM_IO_STATUS_RATE_LIMITED)
|
676
|
+
errno = ENOMEM;
|
677
|
+
else
|
678
|
+
errno = EAGAIN;
|
679
|
+
}
|
680
|
+
|
681
|
+
int zmq::pgm_socket_t::compute_sqns (int tpdu_)
|
682
|
+
{
|
683
|
+
// Convert rate into B/ms.
|
684
|
+
uint64_t rate = ((uint64_t) options.rate) / 8;
|
685
|
+
|
686
|
+
// Get recovery interval in milliseconds.
|
687
|
+
uint64_t interval = options.recovery_ivl_msec >= 0 ?
|
688
|
+
options.recovery_ivl_msec :
|
689
|
+
options.recovery_ivl * 1000;
|
690
|
+
|
691
|
+
// Compute the size of the buffer in bytes.
|
692
|
+
uint64_t size = interval * rate;
|
693
|
+
|
694
|
+
// Translate the size into number of packets.
|
695
|
+
uint64_t sqns = size / tpdu_;
|
696
|
+
|
697
|
+
// Buffer should be able to contain at least one packet.
|
698
|
+
if (sqns == 0)
|
699
|
+
sqns = 1;
|
700
|
+
|
701
|
+
return (int) sqns;
|
702
|
+
}
|
703
|
+
|
704
|
+
#endif
|
705
|
+
|