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.
Files changed (300) hide show
  1. data/LICENSE +703 -0
  2. data/README.md +31 -0
  3. data/lib/libzmq.rb +17 -0
  4. data/lib/libzmq/ffi-rzmq.rb +3 -0
  5. data/libzmq/Makefile +5 -0
  6. data/libzmq/extconf.rb +24 -0
  7. data/libzmq/zeromq-2.1.7/AUTHORS +92 -0
  8. data/libzmq/zeromq-2.1.7/COPYING +674 -0
  9. data/libzmq/zeromq-2.1.7/COPYING.LESSER +206 -0
  10. data/libzmq/zeromq-2.1.7/ChangeLog +15620 -0
  11. data/libzmq/zeromq-2.1.7/INSTALL +237 -0
  12. data/libzmq/zeromq-2.1.7/MAINTAINERS +56 -0
  13. data/libzmq/zeromq-2.1.7/Makefile.am +42 -0
  14. data/libzmq/zeromq-2.1.7/Makefile.in +779 -0
  15. data/libzmq/zeromq-2.1.7/NEWS +275 -0
  16. data/libzmq/zeromq-2.1.7/README +39 -0
  17. data/libzmq/zeromq-2.1.7/acinclude.m4 +582 -0
  18. data/libzmq/zeromq-2.1.7/aclocal.m4 +1206 -0
  19. data/libzmq/zeromq-2.1.7/autogen.sh +45 -0
  20. data/libzmq/zeromq-2.1.7/builds/msvc/Makefile.am +8 -0
  21. data/libzmq/zeromq-2.1.7/builds/msvc/Makefile.in +390 -0
  22. data/libzmq/zeromq-2.1.7/builds/msvc/c_local_lat/c_local_lat.vcproj +176 -0
  23. data/libzmq/zeromq-2.1.7/builds/msvc/c_local_thr/c_local_thr.vcproj +176 -0
  24. data/libzmq/zeromq-2.1.7/builds/msvc/c_remote_lat/c_remote_lat.vcproj +176 -0
  25. data/libzmq/zeromq-2.1.7/builds/msvc/c_remote_thr/c_remote_thr.vcproj +176 -0
  26. data/libzmq/zeromq-2.1.7/builds/msvc/libzmq/libzmq.vcproj +783 -0
  27. data/libzmq/zeromq-2.1.7/builds/msvc/msvc.sln +89 -0
  28. data/libzmq/zeromq-2.1.7/builds/msvc/platform.hpp +32 -0
  29. data/libzmq/zeromq-2.1.7/builds/redhat/zeromq.spec.in +139 -0
  30. data/libzmq/zeromq-2.1.7/config/compile +143 -0
  31. data/libzmq/zeromq-2.1.7/config/config.guess +1502 -0
  32. data/libzmq/zeromq-2.1.7/config/config.sub +1714 -0
  33. data/libzmq/zeromq-2.1.7/config/depcomp +630 -0
  34. data/libzmq/zeromq-2.1.7/config/install-sh +520 -0
  35. data/libzmq/zeromq-2.1.7/config/libtool.m4 +7377 -0
  36. data/libzmq/zeromq-2.1.7/config/ltmain.sh +8413 -0
  37. data/libzmq/zeromq-2.1.7/config/ltoptions.m4 +368 -0
  38. data/libzmq/zeromq-2.1.7/config/ltsugar.m4 +123 -0
  39. data/libzmq/zeromq-2.1.7/config/ltversion.m4 +23 -0
  40. data/libzmq/zeromq-2.1.7/config/lt~obsolete.m4 +92 -0
  41. data/libzmq/zeromq-2.1.7/config/missing +376 -0
  42. data/libzmq/zeromq-2.1.7/configure +21645 -0
  43. data/libzmq/zeromq-2.1.7/configure.in +380 -0
  44. data/libzmq/zeromq-2.1.7/doc/Makefile.am +46 -0
  45. data/libzmq/zeromq-2.1.7/doc/Makefile.in +546 -0
  46. data/libzmq/zeromq-2.1.7/doc/asciidoc.conf +56 -0
  47. data/libzmq/zeromq-2.1.7/doc/zmq.7 +242 -0
  48. data/libzmq/zeromq-2.1.7/doc/zmq.html +846 -0
  49. data/libzmq/zeromq-2.1.7/doc/zmq.txt +218 -0
  50. data/libzmq/zeromq-2.1.7/doc/zmq_bind.3 +166 -0
  51. data/libzmq/zeromq-2.1.7/doc/zmq_bind.html +746 -0
  52. data/libzmq/zeromq-2.1.7/doc/zmq_bind.txt +91 -0
  53. data/libzmq/zeromq-2.1.7/doc/zmq_close.3 +81 -0
  54. data/libzmq/zeromq-2.1.7/doc/zmq_close.html +645 -0
  55. data/libzmq/zeromq-2.1.7/doc/zmq_close.txt +52 -0
  56. data/libzmq/zeromq-2.1.7/doc/zmq_connect.3 +161 -0
  57. data/libzmq/zeromq-2.1.7/doc/zmq_connect.html +732 -0
  58. data/libzmq/zeromq-2.1.7/doc/zmq_connect.txt +89 -0
  59. data/libzmq/zeromq-2.1.7/doc/zmq_cpp.7 +410 -0
  60. data/libzmq/zeromq-2.1.7/doc/zmq_cpp.html +765 -0
  61. data/libzmq/zeromq-2.1.7/doc/zmq_cpp.txt +212 -0
  62. data/libzmq/zeromq-2.1.7/doc/zmq_device.3 +140 -0
  63. data/libzmq/zeromq-2.1.7/doc/zmq_device.html +736 -0
  64. data/libzmq/zeromq-2.1.7/doc/zmq_device.txt +138 -0
  65. data/libzmq/zeromq-2.1.7/doc/zmq_epgm.7 +209 -0
  66. data/libzmq/zeromq-2.1.7/doc/zmq_epgm.html +749 -0
  67. data/libzmq/zeromq-2.1.7/doc/zmq_epgm.txt +162 -0
  68. data/libzmq/zeromq-2.1.7/doc/zmq_errno.3 +78 -0
  69. data/libzmq/zeromq-2.1.7/doc/zmq_errno.html +634 -0
  70. data/libzmq/zeromq-2.1.7/doc/zmq_errno.txt +50 -0
  71. data/libzmq/zeromq-2.1.7/doc/zmq_getsockopt.3 +944 -0
  72. data/libzmq/zeromq-2.1.7/doc/zmq_getsockopt.html +1713 -0
  73. data/libzmq/zeromq-2.1.7/doc/zmq_getsockopt.txt +407 -0
  74. data/libzmq/zeromq-2.1.7/doc/zmq_init.3 +71 -0
  75. data/libzmq/zeromq-2.1.7/doc/zmq_init.html +635 -0
  76. data/libzmq/zeromq-2.1.7/doc/zmq_init.txt +51 -0
  77. data/libzmq/zeromq-2.1.7/doc/zmq_inproc.7 +115 -0
  78. data/libzmq/zeromq-2.1.7/doc/zmq_inproc.html +669 -0
  79. data/libzmq/zeromq-2.1.7/doc/zmq_inproc.txt +89 -0
  80. data/libzmq/zeromq-2.1.7/doc/zmq_ipc.7 +109 -0
  81. data/libzmq/zeromq-2.1.7/doc/zmq_ipc.html +662 -0
  82. data/libzmq/zeromq-2.1.7/doc/zmq_ipc.txt +80 -0
  83. data/libzmq/zeromq-2.1.7/doc/zmq_msg_close.3 +81 -0
  84. data/libzmq/zeromq-2.1.7/doc/zmq_msg_close.html +647 -0
  85. data/libzmq/zeromq-2.1.7/doc/zmq_msg_close.txt +55 -0
  86. data/libzmq/zeromq-2.1.7/doc/zmq_msg_copy.3 +95 -0
  87. data/libzmq/zeromq-2.1.7/doc/zmq_msg_copy.html +656 -0
  88. data/libzmq/zeromq-2.1.7/doc/zmq_msg_copy.txt +57 -0
  89. data/libzmq/zeromq-2.1.7/doc/zmq_msg_data.3 +76 -0
  90. data/libzmq/zeromq-2.1.7/doc/zmq_msg_data.html +633 -0
  91. data/libzmq/zeromq-2.1.7/doc/zmq_msg_data.txt +48 -0
  92. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init.3 +110 -0
  93. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init.html +656 -0
  94. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init.txt +65 -0
  95. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_data.3 +138 -0
  96. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_data.html +678 -0
  97. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_data.txt +83 -0
  98. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_size.3 +97 -0
  99. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_size.html +656 -0
  100. data/libzmq/zeromq-2.1.7/doc/zmq_msg_init_size.txt +58 -0
  101. data/libzmq/zeromq-2.1.7/doc/zmq_msg_move.3 +79 -0
  102. data/libzmq/zeromq-2.1.7/doc/zmq_msg_move.html +645 -0
  103. data/libzmq/zeromq-2.1.7/doc/zmq_msg_move.txt +52 -0
  104. data/libzmq/zeromq-2.1.7/doc/zmq_msg_size.3 +76 -0
  105. data/libzmq/zeromq-2.1.7/doc/zmq_msg_size.html +633 -0
  106. data/libzmq/zeromq-2.1.7/doc/zmq_msg_size.txt +48 -0
  107. data/libzmq/zeromq-2.1.7/doc/zmq_pgm.7 +209 -0
  108. data/libzmq/zeromq-2.1.7/doc/zmq_pgm.html +749 -0
  109. data/libzmq/zeromq-2.1.7/doc/zmq_pgm.txt +162 -0
  110. data/libzmq/zeromq-2.1.7/doc/zmq_poll.3 +204 -0
  111. data/libzmq/zeromq-2.1.7/doc/zmq_poll.html +755 -0
  112. data/libzmq/zeromq-2.1.7/doc/zmq_poll.txt +132 -0
  113. data/libzmq/zeromq-2.1.7/doc/zmq_recv.3 +172 -0
  114. data/libzmq/zeromq-2.1.7/doc/zmq_recv.html +746 -0
  115. data/libzmq/zeromq-2.1.7/doc/zmq_recv.txt +121 -0
  116. data/libzmq/zeromq-2.1.7/doc/zmq_send.3 +185 -0
  117. data/libzmq/zeromq-2.1.7/doc/zmq_send.html +755 -0
  118. data/libzmq/zeromq-2.1.7/doc/zmq_send.txt +120 -0
  119. data/libzmq/zeromq-2.1.7/doc/zmq_setsockopt.3 +878 -0
  120. data/libzmq/zeromq-2.1.7/doc/zmq_setsockopt.html +1603 -0
  121. data/libzmq/zeromq-2.1.7/doc/zmq_setsockopt.txt +382 -0
  122. data/libzmq/zeromq-2.1.7/doc/zmq_socket.3 +779 -0
  123. data/libzmq/zeromq-2.1.7/doc/zmq_socket.html +1424 -0
  124. data/libzmq/zeromq-2.1.7/doc/zmq_socket.txt +342 -0
  125. data/libzmq/zeromq-2.1.7/doc/zmq_strerror.3 +78 -0
  126. data/libzmq/zeromq-2.1.7/doc/zmq_strerror.html +634 -0
  127. data/libzmq/zeromq-2.1.7/doc/zmq_strerror.txt +55 -0
  128. data/libzmq/zeromq-2.1.7/doc/zmq_tcp.7 +244 -0
  129. data/libzmq/zeromq-2.1.7/doc/zmq_tcp.html +755 -0
  130. data/libzmq/zeromq-2.1.7/doc/zmq_tcp.txt +162 -0
  131. data/libzmq/zeromq-2.1.7/doc/zmq_term.3 +135 -0
  132. data/libzmq/zeromq-2.1.7/doc/zmq_term.html +672 -0
  133. data/libzmq/zeromq-2.1.7/doc/zmq_term.txt +65 -0
  134. data/libzmq/zeromq-2.1.7/doc/zmq_version.3 +78 -0
  135. data/libzmq/zeromq-2.1.7/doc/zmq_version.html +632 -0
  136. data/libzmq/zeromq-2.1.7/doc/zmq_version.txt +53 -0
  137. data/libzmq/zeromq-2.1.7/foreign/openpgm/Makefile.am +8 -0
  138. data/libzmq/zeromq-2.1.7/foreign/openpgm/Makefile.in +588 -0
  139. data/libzmq/zeromq-2.1.7/foreign/openpgm/libpgm-5.1.115~dfsg.tar.gz +0 -0
  140. data/libzmq/zeromq-2.1.7/foreign/xmlParser/xmlParser.cpp +2923 -0
  141. data/libzmq/zeromq-2.1.7/foreign/xmlParser/xmlParser.hpp +762 -0
  142. data/libzmq/zeromq-2.1.7/include/zmq.h +269 -0
  143. data/libzmq/zeromq-2.1.7/include/zmq.hpp +301 -0
  144. data/libzmq/zeromq-2.1.7/include/zmq_utils.h +64 -0
  145. data/libzmq/zeromq-2.1.7/perf/Makefile.am +21 -0
  146. data/libzmq/zeromq-2.1.7/perf/Makefile.in +566 -0
  147. data/libzmq/zeromq-2.1.7/perf/inproc_lat.cpp +232 -0
  148. data/libzmq/zeromq-2.1.7/perf/inproc_thr.cpp +246 -0
  149. data/libzmq/zeromq-2.1.7/perf/local_lat.cpp +108 -0
  150. data/libzmq/zeromq-2.1.7/perf/local_thr.cpp +138 -0
  151. data/libzmq/zeromq-2.1.7/perf/remote_lat.cpp +121 -0
  152. data/libzmq/zeromq-2.1.7/perf/remote_thr.cpp +104 -0
  153. data/libzmq/zeromq-2.1.7/src/Makefile.am +155 -0
  154. data/libzmq/zeromq-2.1.7/src/Makefile.in +1320 -0
  155. data/libzmq/zeromq-2.1.7/src/array.hpp +147 -0
  156. data/libzmq/zeromq-2.1.7/src/atomic_counter.hpp +164 -0
  157. data/libzmq/zeromq-2.1.7/src/atomic_ptr.hpp +159 -0
  158. data/libzmq/zeromq-2.1.7/src/blob.hpp +34 -0
  159. data/libzmq/zeromq-2.1.7/src/clock.cpp +118 -0
  160. data/libzmq/zeromq-2.1.7/src/clock.hpp +60 -0
  161. data/libzmq/zeromq-2.1.7/src/command.cpp +39 -0
  162. data/libzmq/zeromq-2.1.7/src/command.hpp +147 -0
  163. data/libzmq/zeromq-2.1.7/src/config.hpp +88 -0
  164. data/libzmq/zeromq-2.1.7/src/connect_session.cpp +119 -0
  165. data/libzmq/zeromq-2.1.7/src/connect_session.hpp +65 -0
  166. data/libzmq/zeromq-2.1.7/src/ctx.cpp +322 -0
  167. data/libzmq/zeromq-2.1.7/src/ctx.hpp +159 -0
  168. data/libzmq/zeromq-2.1.7/src/decoder.cpp +129 -0
  169. data/libzmq/zeromq-2.1.7/src/decoder.hpp +207 -0
  170. data/libzmq/zeromq-2.1.7/src/device.cpp +120 -0
  171. data/libzmq/zeromq-2.1.7/src/device.hpp +32 -0
  172. data/libzmq/zeromq-2.1.7/src/devpoll.cpp +190 -0
  173. data/libzmq/zeromq-2.1.7/src/devpoll.hpp +100 -0
  174. data/libzmq/zeromq-2.1.7/src/dist.cpp +200 -0
  175. data/libzmq/zeromq-2.1.7/src/dist.hpp +90 -0
  176. data/libzmq/zeromq-2.1.7/src/encoder.cpp +90 -0
  177. data/libzmq/zeromq-2.1.7/src/encoder.hpp +184 -0
  178. data/libzmq/zeromq-2.1.7/src/epoll.cpp +177 -0
  179. data/libzmq/zeromq-2.1.7/src/epoll.hpp +96 -0
  180. data/libzmq/zeromq-2.1.7/src/err.cpp +238 -0
  181. data/libzmq/zeromq-2.1.7/src/err.hpp +145 -0
  182. data/libzmq/zeromq-2.1.7/src/fd.hpp +45 -0
  183. data/libzmq/zeromq-2.1.7/src/fq.cpp +164 -0
  184. data/libzmq/zeromq-2.1.7/src/fq.hpp +80 -0
  185. data/libzmq/zeromq-2.1.7/src/i_engine.hpp +53 -0
  186. data/libzmq/zeromq-2.1.7/src/i_inout.hpp +50 -0
  187. data/libzmq/zeromq-2.1.7/src/i_poll_events.hpp +46 -0
  188. data/libzmq/zeromq-2.1.7/src/io_object.cpp +107 -0
  189. data/libzmq/zeromq-2.1.7/src/io_object.hpp +78 -0
  190. data/libzmq/zeromq-2.1.7/src/io_thread.cpp +109 -0
  191. data/libzmq/zeromq-2.1.7/src/io_thread.hpp +88 -0
  192. data/libzmq/zeromq-2.1.7/src/ip.cpp +339 -0
  193. data/libzmq/zeromq-2.1.7/src/ip.hpp +68 -0
  194. data/libzmq/zeromq-2.1.7/src/kqueue.cpp +194 -0
  195. data/libzmq/zeromq-2.1.7/src/kqueue.hpp +103 -0
  196. data/libzmq/zeromq-2.1.7/src/lb.cpp +174 -0
  197. data/libzmq/zeromq-2.1.7/src/lb.hpp +79 -0
  198. data/libzmq/zeromq-2.1.7/src/libzmq.pc.in +10 -0
  199. data/libzmq/zeromq-2.1.7/src/likely.hpp +33 -0
  200. data/libzmq/zeromq-2.1.7/src/mailbox.cpp +382 -0
  201. data/libzmq/zeromq-2.1.7/src/mailbox.hpp +62 -0
  202. data/libzmq/zeromq-2.1.7/src/msg_content.hpp +52 -0
  203. data/libzmq/zeromq-2.1.7/src/mutex.hpp +121 -0
  204. data/libzmq/zeromq-2.1.7/src/named_session.cpp +85 -0
  205. data/libzmq/zeromq-2.1.7/src/named_session.hpp +57 -0
  206. data/libzmq/zeromq-2.1.7/src/object.cpp +467 -0
  207. data/libzmq/zeromq-2.1.7/src/object.hpp +127 -0
  208. data/libzmq/zeromq-2.1.7/src/options.cpp +336 -0
  209. data/libzmq/zeromq-2.1.7/src/options.hpp +87 -0
  210. data/libzmq/zeromq-2.1.7/src/own.cpp +214 -0
  211. data/libzmq/zeromq-2.1.7/src/own.hpp +140 -0
  212. data/libzmq/zeromq-2.1.7/src/pair.cpp +180 -0
  213. data/libzmq/zeromq-2.1.7/src/pair.hpp +76 -0
  214. data/libzmq/zeromq-2.1.7/src/pgm_receiver.cpp +259 -0
  215. data/libzmq/zeromq-2.1.7/src/pgm_receiver.hpp +129 -0
  216. data/libzmq/zeromq-2.1.7/src/pgm_sender.cpp +215 -0
  217. data/libzmq/zeromq-2.1.7/src/pgm_sender.hpp +105 -0
  218. data/libzmq/zeromq-2.1.7/src/pgm_socket.cpp +705 -0
  219. data/libzmq/zeromq-2.1.7/src/pgm_socket.hpp +118 -0
  220. data/libzmq/zeromq-2.1.7/src/pipe.cpp +409 -0
  221. data/libzmq/zeromq-2.1.7/src/pipe.hpp +214 -0
  222. data/libzmq/zeromq-2.1.7/src/platform.hpp.in +228 -0
  223. data/libzmq/zeromq-2.1.7/src/poll.cpp +180 -0
  224. data/libzmq/zeromq-2.1.7/src/poll.hpp +104 -0
  225. data/libzmq/zeromq-2.1.7/src/poller.hpp +73 -0
  226. data/libzmq/zeromq-2.1.7/src/poller_base.cpp +99 -0
  227. data/libzmq/zeromq-2.1.7/src/poller_base.hpp +84 -0
  228. data/libzmq/zeromq-2.1.7/src/pub.cpp +31 -0
  229. data/libzmq/zeromq-2.1.7/src/pub.hpp +44 -0
  230. data/libzmq/zeromq-2.1.7/src/pull.cpp +61 -0
  231. data/libzmq/zeromq-2.1.7/src/pull.hpp +60 -0
  232. data/libzmq/zeromq-2.1.7/src/push.cpp +62 -0
  233. data/libzmq/zeromq-2.1.7/src/push.hpp +59 -0
  234. data/libzmq/zeromq-2.1.7/src/reaper.cpp +121 -0
  235. data/libzmq/zeromq-2.1.7/src/reaper.hpp +77 -0
  236. data/libzmq/zeromq-2.1.7/src/rep.cpp +131 -0
  237. data/libzmq/zeromq-2.1.7/src/rep.hpp +59 -0
  238. data/libzmq/zeromq-2.1.7/src/req.cpp +121 -0
  239. data/libzmq/zeromq-2.1.7/src/req.hpp +58 -0
  240. data/libzmq/zeromq-2.1.7/src/select.cpp +211 -0
  241. data/libzmq/zeromq-2.1.7/src/select.hpp +116 -0
  242. data/libzmq/zeromq-2.1.7/src/semaphore.hpp +189 -0
  243. data/libzmq/zeromq-2.1.7/src/session.cpp +347 -0
  244. data/libzmq/zeromq-2.1.7/src/session.hpp +150 -0
  245. data/libzmq/zeromq-2.1.7/src/socket_base.cpp +811 -0
  246. data/libzmq/zeromq-2.1.7/src/socket_base.hpp +207 -0
  247. data/libzmq/zeromq-2.1.7/src/stdint.hpp +63 -0
  248. data/libzmq/zeromq-2.1.7/src/sub.cpp +75 -0
  249. data/libzmq/zeromq-2.1.7/src/sub.hpp +50 -0
  250. data/libzmq/zeromq-2.1.7/src/swap.cpp +325 -0
  251. data/libzmq/zeromq-2.1.7/src/swap.hpp +123 -0
  252. data/libzmq/zeromq-2.1.7/src/tcp_connecter.cpp +310 -0
  253. data/libzmq/zeromq-2.1.7/src/tcp_connecter.hpp +81 -0
  254. data/libzmq/zeromq-2.1.7/src/tcp_listener.cpp +371 -0
  255. data/libzmq/zeromq-2.1.7/src/tcp_listener.hpp +73 -0
  256. data/libzmq/zeromq-2.1.7/src/tcp_socket.cpp +228 -0
  257. data/libzmq/zeromq-2.1.7/src/tcp_socket.hpp +72 -0
  258. data/libzmq/zeromq-2.1.7/src/thread.cpp +97 -0
  259. data/libzmq/zeromq-2.1.7/src/thread.hpp +78 -0
  260. data/libzmq/zeromq-2.1.7/src/transient_session.cpp +41 -0
  261. data/libzmq/zeromq-2.1.7/src/transient_session.hpp +52 -0
  262. data/libzmq/zeromq-2.1.7/src/trie.cpp +181 -0
  263. data/libzmq/zeromq-2.1.7/src/trie.hpp +59 -0
  264. data/libzmq/zeromq-2.1.7/src/uuid.cpp +233 -0
  265. data/libzmq/zeromq-2.1.7/src/uuid.hpp +111 -0
  266. data/libzmq/zeromq-2.1.7/src/windows.hpp +79 -0
  267. data/libzmq/zeromq-2.1.7/src/wire.hpp +99 -0
  268. data/libzmq/zeromq-2.1.7/src/xpub.cpp +76 -0
  269. data/libzmq/zeromq-2.1.7/src/xpub.hpp +61 -0
  270. data/libzmq/zeromq-2.1.7/src/xrep.cpp +337 -0
  271. data/libzmq/zeromq-2.1.7/src/xrep.hpp +116 -0
  272. data/libzmq/zeromq-2.1.7/src/xreq.cpp +74 -0
  273. data/libzmq/zeromq-2.1.7/src/xreq.hpp +65 -0
  274. data/libzmq/zeromq-2.1.7/src/xsub.cpp +172 -0
  275. data/libzmq/zeromq-2.1.7/src/xsub.hpp +80 -0
  276. data/libzmq/zeromq-2.1.7/src/ypipe.hpp +209 -0
  277. data/libzmq/zeromq-2.1.7/src/yqueue.hpp +198 -0
  278. data/libzmq/zeromq-2.1.7/src/zmq.cpp +798 -0
  279. data/libzmq/zeromq-2.1.7/src/zmq_connecter.cpp +166 -0
  280. data/libzmq/zeromq-2.1.7/src/zmq_connecter.hpp +92 -0
  281. data/libzmq/zeromq-2.1.7/src/zmq_engine.cpp +220 -0
  282. data/libzmq/zeromq-2.1.7/src/zmq_engine.hpp +87 -0
  283. data/libzmq/zeromq-2.1.7/src/zmq_init.cpp +216 -0
  284. data/libzmq/zeromq-2.1.7/src/zmq_init.hpp +93 -0
  285. data/libzmq/zeromq-2.1.7/src/zmq_listener.cpp +78 -0
  286. data/libzmq/zeromq-2.1.7/src/zmq_listener.hpp +67 -0
  287. data/libzmq/zeromq-2.1.7/tests/Makefile.am +30 -0
  288. data/libzmq/zeromq-2.1.7/tests/Makefile.in +713 -0
  289. data/libzmq/zeromq-2.1.7/tests/test_hwm.cpp +68 -0
  290. data/libzmq/zeromq-2.1.7/tests/test_pair_inproc.cpp +31 -0
  291. data/libzmq/zeromq-2.1.7/tests/test_pair_ipc.cpp +31 -0
  292. data/libzmq/zeromq-2.1.7/tests/test_pair_tcp.cpp +31 -0
  293. data/libzmq/zeromq-2.1.7/tests/test_reqrep_inproc.cpp +31 -0
  294. data/libzmq/zeromq-2.1.7/tests/test_reqrep_ipc.cpp +31 -0
  295. data/libzmq/zeromq-2.1.7/tests/test_reqrep_tcp.cpp +31 -0
  296. data/libzmq/zeromq-2.1.7/tests/test_shutdown_stress.cpp +87 -0
  297. data/libzmq/zeromq-2.1.7/tests/testutil.hpp +130 -0
  298. data/libzmq/zeromq-2.1.7/version.sh +21 -0
  299. data/libzmq/zeromq-2.1.7/zeromq.spec +139 -0
  300. metadata +348 -0
@@ -0,0 +1,150 @@
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_SESSION_HPP_INCLUDED__
22
+ #define __ZMQ_SESSION_HPP_INCLUDED__
23
+
24
+ #include "own.hpp"
25
+ #include "i_inout.hpp"
26
+ #include "io_object.hpp"
27
+ #include "blob.hpp"
28
+ #include "pipe.hpp"
29
+
30
+ namespace zmq
31
+ {
32
+
33
+ class session_t :
34
+ public own_t,
35
+ public io_object_t,
36
+ public i_inout,
37
+ public i_reader_events,
38
+ public i_writer_events
39
+ {
40
+ public:
41
+
42
+ session_t (class io_thread_t *io_thread_,
43
+ class socket_base_t *socket_, const options_t &options_);
44
+
45
+ // i_inout interface implementation. Note that detach method is not
46
+ // implemented by generic session. Different session types may handle
47
+ // engine disconnection in different ways.
48
+ bool read (::zmq_msg_t *msg_);
49
+ bool write (::zmq_msg_t *msg_);
50
+ void flush ();
51
+ void detach ();
52
+
53
+ void attach_pipes (class reader_t *inpipe_, class writer_t *outpipe_,
54
+ const blob_t &peer_identity_);
55
+
56
+ // i_reader_events interface implementation.
57
+ void activated (class reader_t *pipe_);
58
+ void terminated (class reader_t *pipe_);
59
+ void delimited (class reader_t *pipe_);
60
+
61
+ // i_writer_events interface implementation.
62
+ void activated (class writer_t *pipe_);
63
+ void terminated (class writer_t *pipe_);
64
+
65
+ protected:
66
+
67
+ // This function allows to shut down the session even though
68
+ // there are pending messages in the inbound pipe.
69
+ void terminate ();
70
+
71
+ // Two events for the derived session type. Attached is triggered
72
+ // when session is attached to a peer, detached is triggered at the
73
+ // beginning of the termination process when session is about to
74
+ // be detached from the peer.
75
+ virtual void attached (const blob_t &peer_identity_) = 0;
76
+ virtual void detached () = 0;
77
+
78
+ // Allows derives session types to (un)register session names.
79
+ bool register_session (const blob_t &name_, class session_t *session_);
80
+ void unregister_session (const blob_t &name_);
81
+
82
+ ~session_t ();
83
+
84
+ private:
85
+
86
+ // Handlers for incoming commands.
87
+ void process_plug ();
88
+ void process_attach (struct i_engine *engine_,
89
+ const blob_t &peer_identity_);
90
+ void process_term (int linger_);
91
+
92
+ // i_poll_events handlers.
93
+ void timer_event (int id_);
94
+
95
+ // Remove any half processed messages. Flush unflushed messages.
96
+ // Call this function when engine disconnect to get rid of leftovers.
97
+ void clean_pipes ();
98
+
99
+ // Call this function to move on with the delayed process_term.
100
+ void proceed_with_term ();
101
+
102
+ // Inbound pipe, i.e. one the session is getting messages from.
103
+ class reader_t *in_pipe;
104
+
105
+ // This flag is true if the remainder of the message being processed
106
+ // is still in the in pipe.
107
+ bool incomplete_in;
108
+
109
+ // Outbound pipe, i.e. one the socket is sending messages to.
110
+ class writer_t *out_pipe;
111
+
112
+ // The protocol I/O engine connected to the session.
113
+ struct i_engine *engine;
114
+
115
+ // The socket the session belongs to.
116
+ class socket_base_t *socket;
117
+
118
+ // I/O thread the session is living in. It will be used to plug in
119
+ // the engines into the same thread.
120
+ class io_thread_t *io_thread;
121
+
122
+ // If true, pipes were already attached to this session.
123
+ bool pipes_attached;
124
+
125
+ // If true, delimiter was already read from the inbound pipe.
126
+ bool delimiter_processed;
127
+
128
+ // If true, we should terminate the session even though there are
129
+ // pending messages in the inbound pipe.
130
+ bool force_terminate;
131
+
132
+ // ID of the linger timer
133
+ enum {linger_timer_id = 0x20};
134
+
135
+ // True is linger timer is running.
136
+ bool has_linger_timer;
137
+
138
+ enum {
139
+ active,
140
+ pending,
141
+ terminating
142
+ } state;
143
+
144
+ session_t (const session_t&);
145
+ const session_t &operator = (const session_t&);
146
+ };
147
+
148
+ }
149
+
150
+ #endif
@@ -0,0 +1,811 @@
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 <new>
22
+ #include <string>
23
+ #include <algorithm>
24
+
25
+ #include "../include/zmq.h"
26
+
27
+ #include "platform.hpp"
28
+
29
+ #if defined ZMQ_HAVE_WINDOWS
30
+ #include "windows.hpp"
31
+ #if defined _MSC_VER
32
+ #include <intrin.h>
33
+ #endif
34
+ #else
35
+ #include <unistd.h>
36
+ #endif
37
+
38
+ #include "socket_base.hpp"
39
+ #include "zmq_listener.hpp"
40
+ #include "zmq_connecter.hpp"
41
+ #include "io_thread.hpp"
42
+ #include "connect_session.hpp"
43
+ #include "config.hpp"
44
+ #include "clock.hpp"
45
+ #include "pipe.hpp"
46
+ #include "err.hpp"
47
+ #include "ctx.hpp"
48
+ #include "platform.hpp"
49
+ #include "likely.hpp"
50
+ #include "uuid.hpp"
51
+
52
+ #include "pair.hpp"
53
+ #include "pub.hpp"
54
+ #include "sub.hpp"
55
+ #include "req.hpp"
56
+ #include "rep.hpp"
57
+ #include "pull.hpp"
58
+ #include "push.hpp"
59
+ #include "xreq.hpp"
60
+ #include "xrep.hpp"
61
+ #include "xpub.hpp"
62
+ #include "xsub.hpp"
63
+
64
+ bool zmq::socket_base_t::check_tag ()
65
+ {
66
+ return tag == 0xbaddecaf;
67
+ }
68
+
69
+ zmq::socket_base_t *zmq::socket_base_t::create (int type_, class ctx_t *parent_,
70
+ uint32_t tid_)
71
+ {
72
+ socket_base_t *s = NULL;
73
+ switch (type_) {
74
+
75
+ case ZMQ_PAIR:
76
+ s = new (std::nothrow) pair_t (parent_, tid_);
77
+ break;
78
+ case ZMQ_PUB:
79
+ s = new (std::nothrow) pub_t (parent_, tid_);
80
+ break;
81
+ case ZMQ_SUB:
82
+ s = new (std::nothrow) sub_t (parent_, tid_);
83
+ break;
84
+ case ZMQ_REQ:
85
+ s = new (std::nothrow) req_t (parent_, tid_);
86
+ break;
87
+ case ZMQ_REP:
88
+ s = new (std::nothrow) rep_t (parent_, tid_);
89
+ break;
90
+ case ZMQ_XREQ:
91
+ s = new (std::nothrow) xreq_t (parent_, tid_);
92
+ break;
93
+ case ZMQ_XREP:
94
+ s = new (std::nothrow) xrep_t (parent_, tid_);
95
+ break;
96
+ case ZMQ_PULL:
97
+ s = new (std::nothrow) pull_t (parent_, tid_);
98
+ break;
99
+ case ZMQ_PUSH:
100
+ s = new (std::nothrow) push_t (parent_, tid_);
101
+ break;
102
+ case ZMQ_XPUB:
103
+ s = new (std::nothrow) xpub_t (parent_, tid_);
104
+ break;
105
+ case ZMQ_XSUB:
106
+ s = new (std::nothrow) xsub_t (parent_, tid_);
107
+ break;
108
+ default:
109
+ errno = EINVAL;
110
+ return NULL;
111
+ }
112
+ alloc_assert (s);
113
+ return s;
114
+ }
115
+
116
+ zmq::socket_base_t::socket_base_t (ctx_t *parent_, uint32_t tid_) :
117
+ own_t (parent_, tid_),
118
+ tag (0xbaddecaf),
119
+ ctx_terminated (false),
120
+ destroyed (false),
121
+ last_tsc (0),
122
+ ticks (0),
123
+ rcvmore (false)
124
+ {
125
+ }
126
+
127
+ zmq::socket_base_t::~socket_base_t ()
128
+ {
129
+ zmq_assert (destroyed);
130
+
131
+ // Check whether there are no session leaks.
132
+ sessions_sync.lock ();
133
+ zmq_assert (sessions.empty ());
134
+ sessions_sync.unlock ();
135
+
136
+ // Mark the socket as dead.
137
+ tag = 0xdeadbeef;
138
+ }
139
+
140
+ zmq::mailbox_t *zmq::socket_base_t::get_mailbox ()
141
+ {
142
+ return &mailbox;
143
+ }
144
+
145
+ void zmq::socket_base_t::stop ()
146
+ {
147
+ // Called by ctx when it is terminated (zmq_term).
148
+ // 'stop' command is sent from the threads that called zmq_term to
149
+ // the thread owning the socket. This way, blocking call in the
150
+ // owner thread can be interrupted.
151
+ send_stop ();
152
+ }
153
+
154
+ int zmq::socket_base_t::parse_uri (const char *uri_,
155
+ std::string &protocol_, std::string &address_)
156
+ {
157
+ zmq_assert (uri_ != NULL);
158
+
159
+ std::string uri (uri_);
160
+ std::string::size_type pos = uri.find ("://");
161
+ if (pos == std::string::npos) {
162
+ errno = EINVAL;
163
+ return -1;
164
+ }
165
+ protocol_ = uri.substr (0, pos);
166
+ address_ = uri.substr (pos + 3);
167
+ if (protocol_.empty () || address_.empty ()) {
168
+ errno = EINVAL;
169
+ return -1;
170
+ }
171
+ return 0;
172
+ }
173
+
174
+ int zmq::socket_base_t::check_protocol (const std::string &protocol_)
175
+ {
176
+ // First check out whether the protcol is something we are aware of.
177
+ if (protocol_ != "inproc" && protocol_ != "ipc" && protocol_ != "tcp" &&
178
+ protocol_ != "pgm" && protocol_ != "epgm" && protocol_ != "sys") {
179
+ errno = EPROTONOSUPPORT;
180
+ return -1;
181
+ }
182
+
183
+ // If 0MQ is not compiled with OpenPGM, pgm and epgm transports
184
+ // are not avaialble.
185
+ #if !defined ZMQ_HAVE_OPENPGM
186
+ if (protocol_ == "pgm" || protocol_ == "epgm") {
187
+ errno = EPROTONOSUPPORT;
188
+ return -1;
189
+ }
190
+ #endif
191
+
192
+ // IPC transport is not available on Windows and OpenVMS.
193
+ #if defined ZMQ_HAVE_WINDOWS || defined ZMQ_HAVE_OPENVMS
194
+ if (protocol_ == "ipc") {
195
+ // Unknown protocol.
196
+ errno = EPROTONOSUPPORT;
197
+ return -1;
198
+ }
199
+ #endif
200
+
201
+ // Check whether socket type and transport protocol match.
202
+ // Specifically, multicast protocols can't be combined with
203
+ // bi-directional messaging patterns (socket types).
204
+ if ((protocol_ == "pgm" || protocol_ == "epgm") &&
205
+ options.type != ZMQ_PUB && options.type != ZMQ_SUB &&
206
+ options.type != ZMQ_XPUB && options.type != ZMQ_XSUB) {
207
+ errno = ENOCOMPATPROTO;
208
+ return -1;
209
+ }
210
+
211
+ // Protocol is available.
212
+ return 0;
213
+ }
214
+
215
+ void zmq::socket_base_t::attach_pipes (class reader_t *inpipe_,
216
+ class writer_t *outpipe_, const blob_t &peer_identity_)
217
+ {
218
+ // If the peer haven't specified it's identity, let's generate one.
219
+ if (peer_identity_.size ()) {
220
+ xattach_pipes (inpipe_, outpipe_, peer_identity_);
221
+ }
222
+ else {
223
+ blob_t identity (1, 0);
224
+ identity.append (uuid_t ().to_blob (), uuid_t::uuid_blob_len);
225
+ xattach_pipes (inpipe_, outpipe_, identity);
226
+ }
227
+ }
228
+
229
+ int zmq::socket_base_t::setsockopt (int option_, const void *optval_,
230
+ size_t optvallen_)
231
+ {
232
+ if (unlikely (ctx_terminated)) {
233
+ errno = ETERM;
234
+ return -1;
235
+ }
236
+
237
+ // First, check whether specific socket type overloads the option.
238
+ int rc = xsetsockopt (option_, optval_, optvallen_);
239
+ if (rc == 0 || errno != EINVAL)
240
+ return rc;
241
+
242
+ // If the socket type doesn't support the option, pass it to
243
+ // the generic option parser.
244
+ return options.setsockopt (option_, optval_, optvallen_);
245
+ }
246
+
247
+ int zmq::socket_base_t::getsockopt (int option_, void *optval_,
248
+ size_t *optvallen_)
249
+ {
250
+ if (unlikely (ctx_terminated)) {
251
+ errno = ETERM;
252
+ return -1;
253
+ }
254
+
255
+ if (option_ == ZMQ_RCVMORE) {
256
+ if (*optvallen_ < sizeof (int64_t)) {
257
+ errno = EINVAL;
258
+ return -1;
259
+ }
260
+ *((int64_t*) optval_) = rcvmore ? 1 : 0;
261
+ *optvallen_ = sizeof (int64_t);
262
+ return 0;
263
+ }
264
+
265
+ if (option_ == ZMQ_FD) {
266
+ if (*optvallen_ < sizeof (fd_t)) {
267
+ errno = EINVAL;
268
+ return -1;
269
+ }
270
+ *((fd_t*) optval_) = mailbox.get_fd ();
271
+ *optvallen_ = sizeof (fd_t);
272
+ return 0;
273
+ }
274
+
275
+ if (option_ == ZMQ_EVENTS) {
276
+ if (*optvallen_ < sizeof (uint32_t)) {
277
+ errno = EINVAL;
278
+ return -1;
279
+ }
280
+ int rc = process_commands (false, false);
281
+ if (rc != 0 && (errno == EINTR || errno == ETERM))
282
+ return -1;
283
+ errno_assert (rc == 0);
284
+ *((uint32_t*) optval_) = 0;
285
+ if (has_out ())
286
+ *((uint32_t*) optval_) |= ZMQ_POLLOUT;
287
+ if (has_in ())
288
+ *((uint32_t*) optval_) |= ZMQ_POLLIN;
289
+ *optvallen_ = sizeof (uint32_t);
290
+ return 0;
291
+ }
292
+
293
+ return options.getsockopt (option_, optval_, optvallen_);
294
+ }
295
+
296
+ int zmq::socket_base_t::bind (const char *addr_)
297
+ {
298
+ if (unlikely (ctx_terminated)) {
299
+ errno = ETERM;
300
+ return -1;
301
+ }
302
+
303
+ // Parse addr_ string.
304
+ std::string protocol;
305
+ std::string address;
306
+ int rc = parse_uri (addr_, protocol, address);
307
+ if (rc != 0)
308
+ return -1;
309
+
310
+ rc = check_protocol (protocol);
311
+ if (rc != 0)
312
+ return -1;
313
+
314
+ if (protocol == "inproc" || protocol == "sys") {
315
+ endpoint_t endpoint = {this, options};
316
+ return register_endpoint (addr_, endpoint);
317
+ }
318
+
319
+ if (protocol == "tcp" || protocol == "ipc") {
320
+
321
+ // Choose I/O thread to run the listerner in.
322
+ io_thread_t *io_thread = choose_io_thread (options.affinity);
323
+ if (!io_thread) {
324
+ errno = EMTHREAD;
325
+ return -1;
326
+ }
327
+
328
+ // Create and run the listener.
329
+ zmq_listener_t *listener = new (std::nothrow) zmq_listener_t (
330
+ io_thread, this, options);
331
+ alloc_assert (listener);
332
+ int rc = listener->set_address (protocol.c_str(), address.c_str ());
333
+ if (rc != 0) {
334
+ delete listener;
335
+ return -1;
336
+ }
337
+ launch_child (listener);
338
+
339
+ return 0;
340
+ }
341
+
342
+ if (protocol == "pgm" || protocol == "epgm") {
343
+
344
+ // For convenience's sake, bind can be used interchageable with
345
+ // connect for PGM and EPGM transports.
346
+ return connect (addr_);
347
+ }
348
+
349
+ zmq_assert (false);
350
+ return -1;
351
+ }
352
+
353
+ int zmq::socket_base_t::connect (const char *addr_)
354
+ {
355
+ if (unlikely (ctx_terminated)) {
356
+ errno = ETERM;
357
+ return -1;
358
+ }
359
+
360
+ // Parse addr_ string.
361
+ std::string protocol;
362
+ std::string address;
363
+ int rc = parse_uri (addr_, protocol, address);
364
+ if (rc != 0)
365
+ return -1;
366
+
367
+ rc = check_protocol (protocol);
368
+ if (rc != 0)
369
+ return -1;
370
+
371
+ if (protocol == "inproc" || protocol == "sys") {
372
+
373
+ // TODO: inproc connect is specific with respect to creating pipes
374
+ // as there's no 'reconnect' functionality implemented. Once that
375
+ // is in place we should follow generic pipe creation algorithm.
376
+
377
+ // Find the peer endpoint.
378
+ endpoint_t peer = find_endpoint (addr_);
379
+ if (!peer.socket)
380
+ return -1;
381
+
382
+ reader_t *inpipe_reader = NULL;
383
+ writer_t *inpipe_writer = NULL;
384
+ reader_t *outpipe_reader = NULL;
385
+ writer_t *outpipe_writer = NULL;
386
+
387
+ // The total HWM for an inproc connection should be the sum of
388
+ // the binder's HWM and the connector's HWM. (Similarly for the
389
+ // SWAP.)
390
+ int64_t hwm;
391
+ if (options.hwm == 0 || peer.options.hwm == 0)
392
+ hwm = 0;
393
+ else
394
+ hwm = options.hwm + peer.options.hwm;
395
+ int64_t swap;
396
+ if (options.swap == 0 && peer.options.swap == 0)
397
+ swap = 0;
398
+ else
399
+ swap = options.swap + peer.options.swap;
400
+
401
+ // Create inbound pipe, if required.
402
+ if (options.requires_in)
403
+ create_pipe (this, peer.socket, hwm, swap,
404
+ &inpipe_reader, &inpipe_writer);
405
+
406
+ // Create outbound pipe, if required.
407
+ if (options.requires_out)
408
+ create_pipe (peer.socket, this, hwm, swap,
409
+ &outpipe_reader, &outpipe_writer);
410
+
411
+ // Attach the pipes to this socket object.
412
+ attach_pipes (inpipe_reader, outpipe_writer, peer.options.identity);
413
+
414
+ // Attach the pipes to the peer socket. Note that peer's seqnum
415
+ // was incremented in find_endpoint function. We don't need it
416
+ // increased here.
417
+ send_bind (peer.socket, outpipe_reader, inpipe_writer,
418
+ options.identity, false);
419
+
420
+ return 0;
421
+ }
422
+
423
+ // Choose the I/O thread to run the session in.
424
+ io_thread_t *io_thread = choose_io_thread (options.affinity);
425
+ if (!io_thread) {
426
+ errno = EMTHREAD;
427
+ return -1;
428
+ }
429
+
430
+ // Create session.
431
+ connect_session_t *session = new (std::nothrow) connect_session_t (
432
+ io_thread, this, options, protocol.c_str (), address.c_str ());
433
+ alloc_assert (session);
434
+
435
+ // If 'immediate connect' feature is required, we'll create the pipes
436
+ // to the session straight away. Otherwise, they'll be created by the
437
+ // session once the connection is established.
438
+ if (options.immediate_connect) {
439
+
440
+ reader_t *inpipe_reader = NULL;
441
+ writer_t *inpipe_writer = NULL;
442
+ reader_t *outpipe_reader = NULL;
443
+ writer_t *outpipe_writer = NULL;
444
+
445
+ // Create inbound pipe, if required.
446
+ if (options.requires_in)
447
+ create_pipe (this, session, options.hwm, options.swap,
448
+ &inpipe_reader, &inpipe_writer);
449
+
450
+ // Create outbound pipe, if required.
451
+ if (options.requires_out)
452
+ create_pipe (session, this, options.hwm, options.swap,
453
+ &outpipe_reader, &outpipe_writer);
454
+
455
+ // Attach the pipes to the socket object.
456
+ attach_pipes (inpipe_reader, outpipe_writer, blob_t ());
457
+
458
+ // Attach the pipes to the session object.
459
+ session->attach_pipes (outpipe_reader, inpipe_writer, blob_t ());
460
+ }
461
+
462
+ // Activate the session. Make it a child of this socket.
463
+ launch_child (session);
464
+
465
+ return 0;
466
+ }
467
+
468
+ int zmq::socket_base_t::send (::zmq_msg_t *msg_, int flags_)
469
+ {
470
+ // Check whether the library haven't been shut down yet.
471
+ if (unlikely (ctx_terminated)) {
472
+ errno = ETERM;
473
+ return -1;
474
+ }
475
+
476
+ // Check whether message passed to the function is valid.
477
+ if (unlikely ((msg_->flags | ZMQ_MSG_MASK) != 0xff)) {
478
+ errno = EFAULT;
479
+ return -1;
480
+ }
481
+
482
+ // Process pending commands, if any.
483
+ int rc = process_commands (false, true);
484
+ if (unlikely (rc != 0))
485
+ return -1;
486
+
487
+ // At this point we impose the MORE flag on the message.
488
+ if (flags_ & ZMQ_SNDMORE)
489
+ msg_->flags |= ZMQ_MSG_MORE;
490
+
491
+ // Try to send the message.
492
+ rc = xsend (msg_, flags_);
493
+ if (rc == 0)
494
+ return 0;
495
+
496
+ // In case of non-blocking send we'll simply propagate
497
+ // the error - including EAGAIN - upwards.
498
+ if (flags_ & ZMQ_NOBLOCK)
499
+ return -1;
500
+
501
+ // Oops, we couldn't send the message. Wait for the next
502
+ // command, process it and try to send the message again.
503
+ while (rc != 0) {
504
+ if (errno != EAGAIN)
505
+ return -1;
506
+ if (unlikely (process_commands (true, false) != 0))
507
+ return -1;
508
+ rc = xsend (msg_, flags_);
509
+ }
510
+ return 0;
511
+ }
512
+
513
+ int zmq::socket_base_t::recv (::zmq_msg_t *msg_, int flags_)
514
+ {
515
+ // Check whether the library haven't been shut down yet.
516
+ if (unlikely (ctx_terminated)) {
517
+ errno = ETERM;
518
+ return -1;
519
+ }
520
+
521
+ // Check whether message passed to the function is valid.
522
+ if (unlikely ((msg_->flags | ZMQ_MSG_MASK) != 0xff)) {
523
+ errno = EFAULT;
524
+ return -1;
525
+ }
526
+
527
+ // Get the message.
528
+ int rc = xrecv (msg_, flags_);
529
+ int err = errno;
530
+
531
+ // Once every inbound_poll_rate messages check for signals and process
532
+ // incoming commands. This happens only if we are not polling altogether
533
+ // because there are messages available all the time. If poll occurs,
534
+ // ticks is set to zero and thus we avoid this code.
535
+ //
536
+ // Note that 'recv' uses different command throttling algorithm (the one
537
+ // described above) from the one used by 'send'. This is because counting
538
+ // ticks is more efficient than doing RDTSC all the time.
539
+ if (++ticks == inbound_poll_rate) {
540
+ if (unlikely (process_commands (false, false) != 0))
541
+ return -1;
542
+ ticks = 0;
543
+ }
544
+
545
+ // If we have the message, return immediately.
546
+ if (rc == 0) {
547
+ rcvmore = msg_->flags & ZMQ_MSG_MORE;
548
+ if (rcvmore)
549
+ msg_->flags &= ~ZMQ_MSG_MORE;
550
+ return 0;
551
+ }
552
+
553
+ // If we don't have the message, restore the original cause of the problem.
554
+ errno = err;
555
+
556
+ // If the message cannot be fetched immediately, there are two scenarios.
557
+ // For non-blocking recv, commands are processed in case there's an
558
+ // activate_reader command already waiting int a command pipe.
559
+ // If it's not, return EAGAIN.
560
+ if (flags_ & ZMQ_NOBLOCK) {
561
+ if (errno != EAGAIN)
562
+ return -1;
563
+ if (unlikely (process_commands (false, false) != 0))
564
+ return -1;
565
+ ticks = 0;
566
+
567
+ rc = xrecv (msg_, flags_);
568
+ if (rc == 0) {
569
+ rcvmore = msg_->flags & ZMQ_MSG_MORE;
570
+ if (rcvmore)
571
+ msg_->flags &= ~ZMQ_MSG_MORE;
572
+ }
573
+ return rc;
574
+ }
575
+
576
+ // In blocking scenario, commands are processed over and over again until
577
+ // we are able to fetch a message.
578
+ bool block = (ticks != 0);
579
+ while (rc != 0) {
580
+ if (errno != EAGAIN)
581
+ return -1;
582
+ if (unlikely (process_commands (block, false) != 0))
583
+ return -1;
584
+ rc = xrecv (msg_, flags_);
585
+ ticks = 0;
586
+ block = true;
587
+ }
588
+
589
+ rcvmore = msg_->flags & ZMQ_MSG_MORE;
590
+ if (rcvmore)
591
+ msg_->flags &= ~ZMQ_MSG_MORE;
592
+ return 0;
593
+ }
594
+
595
+ int zmq::socket_base_t::close ()
596
+ {
597
+ // Transfer the ownership of the socket from this application thread
598
+ // to the reaper thread which will take care of the rest of shutdown
599
+ // process.
600
+ send_reap (this);
601
+
602
+ return 0;
603
+ }
604
+
605
+ bool zmq::socket_base_t::has_in ()
606
+ {
607
+ return xhas_in ();
608
+ }
609
+
610
+ bool zmq::socket_base_t::has_out ()
611
+ {
612
+ return xhas_out ();
613
+ }
614
+
615
+ bool zmq::socket_base_t::register_session (const blob_t &name_,
616
+ session_t *session_)
617
+ {
618
+ sessions_sync.lock ();
619
+ bool registered = sessions.insert (
620
+ sessions_t::value_type (name_, session_)).second;
621
+ sessions_sync.unlock ();
622
+ return registered;
623
+ }
624
+
625
+ void zmq::socket_base_t::unregister_session (const blob_t &name_)
626
+ {
627
+ sessions_sync.lock ();
628
+ sessions_t::iterator it = sessions.find (name_);
629
+ zmq_assert (it != sessions.end ());
630
+ sessions.erase (it);
631
+ sessions_sync.unlock ();
632
+ }
633
+
634
+ zmq::session_t *zmq::socket_base_t::find_session (const blob_t &name_)
635
+ {
636
+ sessions_sync.lock ();
637
+ sessions_t::iterator it = sessions.find (name_);
638
+ if (it == sessions.end ()) {
639
+ sessions_sync.unlock ();
640
+ return NULL;
641
+ }
642
+ session_t *session = it->second;
643
+
644
+ // Prepare the session for subsequent attach command.
645
+ session->inc_seqnum ();
646
+
647
+ sessions_sync.unlock ();
648
+ return session;
649
+ }
650
+
651
+ void zmq::socket_base_t::start_reaping (poller_t *poller_)
652
+ {
653
+ poller = poller_;
654
+ handle = poller->add_fd (mailbox.get_fd (), this);
655
+ poller->set_pollin (handle);
656
+ }
657
+
658
+ int zmq::socket_base_t::process_commands (bool block_, bool throttle_)
659
+ {
660
+ int rc;
661
+ command_t cmd;
662
+ if (block_) {
663
+ rc = mailbox.recv (&cmd, true);
664
+ if (rc == -1 && errno == EINTR)
665
+ return -1;
666
+ errno_assert (rc == 0);
667
+ }
668
+ else {
669
+
670
+ // Get the CPU's tick counter. If 0, the counter is not available.
671
+ uint64_t tsc = zmq::clock_t::rdtsc ();
672
+
673
+ // Optimised version of command processing - it doesn't have to check
674
+ // for incoming commands each time. It does so only if certain time
675
+ // elapsed since last command processing. Command delay varies
676
+ // depending on CPU speed: It's ~1ms on 3GHz CPU, ~2ms on 1.5GHz CPU
677
+ // etc. The optimisation makes sense only on platforms where getting
678
+ // a timestamp is a very cheap operation (tens of nanoseconds).
679
+ if (tsc && throttle_) {
680
+
681
+ // Check whether TSC haven't jumped backwards (in case of migration
682
+ // between CPU cores) and whether certain time have elapsed since
683
+ // last command processing. If it didn't do nothing.
684
+ if (tsc >= last_tsc && tsc - last_tsc <= max_command_delay)
685
+ return 0;
686
+ last_tsc = tsc;
687
+ }
688
+
689
+ // Check whether there are any commands pending for this thread.
690
+ rc = mailbox.recv (&cmd, false);
691
+ }
692
+
693
+ // Process all the commands available at the moment.
694
+ while (true) {
695
+ if (rc == -1 && errno == EAGAIN)
696
+ break;
697
+ if (rc == -1 && errno == EINTR)
698
+ return -1;
699
+ errno_assert (rc == 0);
700
+ cmd.destination->process_command (cmd);
701
+ rc = mailbox.recv (&cmd, false);
702
+ }
703
+
704
+ if (ctx_terminated) {
705
+ errno = ETERM;
706
+ return -1;
707
+ }
708
+
709
+ return 0;
710
+ }
711
+
712
+ void zmq::socket_base_t::process_stop ()
713
+ {
714
+ // Here, someone have called zmq_term while the socket was still alive.
715
+ // We'll remember the fact so that any blocking call is interrupted and any
716
+ // further attempt to use the socket will return ETERM. The user is still
717
+ // responsible for calling zmq_close on the socket though!
718
+ ctx_terminated = true;
719
+ }
720
+
721
+ void zmq::socket_base_t::process_bind (reader_t *in_pipe_, writer_t *out_pipe_,
722
+ const blob_t &peer_identity_)
723
+ {
724
+ attach_pipes (in_pipe_, out_pipe_, peer_identity_);
725
+ }
726
+
727
+ void zmq::socket_base_t::process_unplug ()
728
+ {
729
+ }
730
+
731
+ void zmq::socket_base_t::process_term (int linger_)
732
+ {
733
+ // Unregister all inproc endpoints associated with this socket.
734
+ // Doing this we make sure that no new pipes from other sockets (inproc)
735
+ // will be initiated.
736
+ unregister_endpoints (this);
737
+
738
+ // Continue the termination process immediately.
739
+ own_t::process_term (linger_);
740
+ }
741
+
742
+ void zmq::socket_base_t::process_destroy ()
743
+ {
744
+ destroyed = true;
745
+ }
746
+
747
+ int zmq::socket_base_t::xsetsockopt (int option_, const void *optval_,
748
+ size_t optvallen_)
749
+ {
750
+ errno = EINVAL;
751
+ return -1;
752
+ }
753
+
754
+ bool zmq::socket_base_t::xhas_out ()
755
+ {
756
+ return false;
757
+ }
758
+
759
+ int zmq::socket_base_t::xsend (zmq_msg_t *msg_, int options_)
760
+ {
761
+ errno = ENOTSUP;
762
+ return -1;
763
+ }
764
+
765
+ bool zmq::socket_base_t::xhas_in ()
766
+ {
767
+ return false;
768
+ }
769
+
770
+ int zmq::socket_base_t::xrecv (zmq_msg_t *msg_, int options_)
771
+ {
772
+ errno = ENOTSUP;
773
+ return -1;
774
+ }
775
+
776
+ void zmq::socket_base_t::in_event ()
777
+ {
778
+ // Process any commands from other threads/sockets that may be available
779
+ // at the moment. Ultimately, socket will be destroyed.
780
+ process_commands (false, false);
781
+ check_destroy ();
782
+ }
783
+
784
+ void zmq::socket_base_t::out_event ()
785
+ {
786
+ zmq_assert (false);
787
+ }
788
+
789
+ void zmq::socket_base_t::timer_event (int id_)
790
+ {
791
+ zmq_assert (false);
792
+ }
793
+
794
+ void zmq::socket_base_t::check_destroy ()
795
+ {
796
+ // If the object was already marked as destroyed, finish the deallocation.
797
+ if (destroyed) {
798
+
799
+ // Remove the socket from the reaper's poller.
800
+ poller->rm_fd (handle);
801
+
802
+ // Remove the socket from the context.
803
+ destroy_socket (this);
804
+
805
+ // Notify the reaper about the fact.
806
+ send_reaped ();
807
+
808
+ // Deallocate.
809
+ own_t::process_destroy ();
810
+ }
811
+ }