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,209 @@
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_YPIPE_HPP_INCLUDED__
22
+ #define __ZMQ_YPIPE_HPP_INCLUDED__
23
+
24
+ #include "atomic_ptr.hpp"
25
+ #include "yqueue.hpp"
26
+ #include "platform.hpp"
27
+
28
+ namespace zmq
29
+ {
30
+
31
+ // Lock-free queue implementation.
32
+ // Only a single thread can read from the pipe at any specific moment.
33
+ // Only a single thread can write to the pipe at any specific moment.
34
+ // T is the type of the object in the queue.
35
+ // N is granularity of the pipe, i.e. how many items are needed to
36
+ // perform next memory allocation.
37
+
38
+ template <typename T, int N> class ypipe_t
39
+ {
40
+ public:
41
+
42
+ // Initialises the pipe.
43
+ inline ypipe_t ()
44
+ {
45
+ // Insert terminator element into the queue.
46
+ queue.push ();
47
+
48
+ // Let all the pointers to point to the terminator.
49
+ // (unless pipe is dead, in which case c is set to NULL).
50
+ r = w = f = &queue.back ();
51
+ c.set (&queue.back ());
52
+ }
53
+
54
+ // The destructor doesn't have to be virtual. It is mad virtual
55
+ // just to keep ICC and code checking tools from complaining.
56
+ inline virtual ~ypipe_t ()
57
+ {
58
+ }
59
+
60
+ // Following function (write) deliberately copies uninitialised data
61
+ // when used with zmq_msg. Initialising the VSM body for
62
+ // non-VSM messages won't be good for performance.
63
+
64
+ #ifdef ZMQ_HAVE_OPENVMS
65
+ #pragma message save
66
+ #pragma message disable(UNINIT)
67
+ #endif
68
+
69
+ // Write an item to the pipe. Don't flush it yet. If incomplete is
70
+ // set to true the item is assumed to be continued by items
71
+ // subsequently written to the pipe. Incomplete items are never
72
+ // flushed down the stream.
73
+ inline void write (const T &value_, bool incomplete_)
74
+ {
75
+ // Place the value to the queue, add new terminator element.
76
+ queue.back () = value_;
77
+ queue.push ();
78
+
79
+ // Move the "flush up to here" poiter.
80
+ if (!incomplete_)
81
+ f = &queue.back ();
82
+ }
83
+
84
+ #ifdef ZMQ_HAVE_OPENVMS
85
+ #pragma message restore
86
+ #endif
87
+
88
+ // Pop an incomplete item from the pipe. Returns true is such
89
+ // item exists, false otherwise.
90
+ inline bool unwrite (T *value_)
91
+ {
92
+ if (f == &queue.back ())
93
+ return false;
94
+ queue.unpush ();
95
+ *value_ = queue.back ();
96
+ return true;
97
+ }
98
+
99
+ // Flush all the completed items into the pipe. Returns false if
100
+ // the reader thread is sleeping. In that case, caller is obliged to
101
+ // wake the reader up before using the pipe again.
102
+ inline bool flush ()
103
+ {
104
+ // If there are no un-flushed items, do nothing.
105
+ if (w == f)
106
+ return true;
107
+
108
+ // Try to set 'c' to 'f'.
109
+ if (c.cas (w, f) != w) {
110
+
111
+ // Compare-and-swap was unseccessful because 'c' is NULL.
112
+ // This means that the reader is asleep. Therefore we don't
113
+ // care about thread-safeness and update c in non-atomic
114
+ // manner. We'll return false to let the caller know
115
+ // that reader is sleeping.
116
+ c.set (f);
117
+ w = f;
118
+ return false;
119
+ }
120
+
121
+ // Reader is alive. Nothing special to do now. Just move
122
+ // the 'first un-flushed item' pointer to 'f'.
123
+ w = f;
124
+ return true;
125
+ }
126
+
127
+ // Check whether item is available for reading.
128
+ inline bool check_read ()
129
+ {
130
+ // Was the value prefetched already? If so, return.
131
+ if (&queue.front () != r && r)
132
+ return true;
133
+
134
+ // There's no prefetched value, so let us prefetch more values.
135
+ // Prefetching is to simply retrieve the
136
+ // pointer from c in atomic fashion. If there are no
137
+ // items to prefetch, set c to NULL (using compare-and-swap).
138
+ r = c.cas (&queue.front (), NULL);
139
+
140
+ // If there are no elements prefetched, exit.
141
+ // During pipe's lifetime r should never be NULL, however,
142
+ // it can happen during pipe shutdown when items
143
+ // are being deallocated.
144
+ if (&queue.front () == r || !r)
145
+ return false;
146
+
147
+ // There was at least one value prefetched.
148
+ return true;
149
+ }
150
+
151
+ // Reads an item from the pipe. Returns false if there is no value.
152
+ // available.
153
+ inline bool read (T *value_)
154
+ {
155
+ // Try to prefetch a value.
156
+ if (!check_read ())
157
+ return false;
158
+
159
+ // There was at least one value prefetched.
160
+ // Return it to the caller.
161
+ *value_ = queue.front ();
162
+ queue.pop ();
163
+ return true;
164
+ }
165
+
166
+ // Applies the function fn to the first elemenent in the pipe
167
+ // and returns the value returned by the fn.
168
+ // The pipe mustn't be empty or the function crashes.
169
+ inline bool probe (bool (*fn)(T &))
170
+ {
171
+ bool rc = check_read ();
172
+ zmq_assert (rc);
173
+
174
+ return (*fn) (queue.front ());
175
+ }
176
+
177
+ protected:
178
+
179
+ // Allocation-efficient queue to store pipe items.
180
+ // Front of the queue points to the first prefetched item, back of
181
+ // the pipe points to last un-flushed item. Front is used only by
182
+ // reader thread, while back is used only by writer thread.
183
+ yqueue_t <T, N> queue;
184
+
185
+ // Points to the first un-flushed item. This variable is used
186
+ // exclusively by writer thread.
187
+ T *w;
188
+
189
+ // Points to the first un-prefetched item. This variable is used
190
+ // exclusively by reader thread.
191
+ T *r;
192
+
193
+ // Points to the first item to be flushed in the future.
194
+ T *f;
195
+
196
+ // The single point of contention between writer and reader thread.
197
+ // Points past the last flushed item. If it is NULL,
198
+ // reader is asleep. This pointer should be always accessed using
199
+ // atomic operations.
200
+ atomic_ptr_t <T> c;
201
+
202
+ // Disable copying of ypipe object.
203
+ ypipe_t (const ypipe_t&);
204
+ const ypipe_t &operator = (const ypipe_t&);
205
+ };
206
+
207
+ }
208
+
209
+ #endif
@@ -0,0 +1,198 @@
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_YQUEUE_HPP_INCLUDED__
22
+ #define __ZMQ_YQUEUE_HPP_INCLUDED__
23
+
24
+ #include <stdlib.h>
25
+ #include <stddef.h>
26
+
27
+ #include "err.hpp"
28
+ #include "atomic_ptr.hpp"
29
+
30
+ namespace zmq
31
+ {
32
+
33
+ // yqueue is an efficient queue implementation. The main goal is
34
+ // to minimise number of allocations/deallocations needed. Thus yqueue
35
+ // allocates/deallocates elements in batches of N.
36
+ //
37
+ // yqueue allows one thread to use push/back function and another one
38
+ // to use pop/front functions. However, user must ensure that there's no
39
+ // pop on the empty queue and that both threads don't access the same
40
+ // element in unsynchronised manner.
41
+ //
42
+ // T is the type of the object in the queue.
43
+ // N is granularity of the queue (how many pushes have to be done till
44
+ // actual memory allocation is required).
45
+
46
+ template <typename T, int N> class yqueue_t
47
+ {
48
+ public:
49
+
50
+ // Create the queue.
51
+ inline yqueue_t ()
52
+ {
53
+ begin_chunk = (chunk_t*) malloc (sizeof (chunk_t));
54
+ alloc_assert (begin_chunk);
55
+ begin_pos = 0;
56
+ back_chunk = NULL;
57
+ back_pos = 0;
58
+ end_chunk = begin_chunk;
59
+ end_pos = 0;
60
+ }
61
+
62
+ // Destroy the queue.
63
+ inline ~yqueue_t ()
64
+ {
65
+ while (true) {
66
+ if (begin_chunk == end_chunk) {
67
+ free (begin_chunk);
68
+ break;
69
+ }
70
+ chunk_t *o = begin_chunk;
71
+ begin_chunk = begin_chunk->next;
72
+ free (o);
73
+ }
74
+
75
+ chunk_t *sc = spare_chunk.xchg (NULL);
76
+ if (sc)
77
+ free (sc);
78
+ }
79
+
80
+ // Returns reference to the front element of the queue.
81
+ // If the queue is empty, behaviour is undefined.
82
+ inline T &front ()
83
+ {
84
+ return begin_chunk->values [begin_pos];
85
+ }
86
+
87
+ // Returns reference to the back element of the queue.
88
+ // If the queue is empty, behaviour is undefined.
89
+ inline T &back ()
90
+ {
91
+ return back_chunk->values [back_pos];
92
+ }
93
+
94
+ // Adds an element to the back end of the queue.
95
+ inline void push ()
96
+ {
97
+ back_chunk = end_chunk;
98
+ back_pos = end_pos;
99
+
100
+ if (++end_pos != N)
101
+ return;
102
+
103
+ chunk_t *sc = spare_chunk.xchg (NULL);
104
+ if (sc) {
105
+ end_chunk->next = sc;
106
+ sc->prev = end_chunk;
107
+ } else {
108
+ end_chunk->next = (chunk_t*) malloc (sizeof (chunk_t));
109
+ alloc_assert (end_chunk->next);
110
+ end_chunk->next->prev = end_chunk;
111
+ }
112
+ end_chunk = end_chunk->next;
113
+ end_pos = 0;
114
+ }
115
+
116
+ // Removes element from the back end of the queue. In other words
117
+ // it rollbacks last push to the queue. Take care: Caller is
118
+ // responsible for destroying the object being unpushed.
119
+ // The caller must also guarantee that the queue isn't empty when
120
+ // unpush is called. It cannot be done automatically as the read
121
+ // side of the queue can be managed by different, completely
122
+ // unsynchronised thread.
123
+ inline void unpush ()
124
+ {
125
+ // First, move 'back' one position backwards.
126
+ if (back_pos)
127
+ --back_pos;
128
+ else {
129
+ back_pos = N - 1;
130
+ back_chunk = back_chunk->prev;
131
+ }
132
+
133
+ // Now, move 'end' position backwards. Note that obsolete end chunk
134
+ // is not used as a spare chunk. The analysis shows that doing so
135
+ // would require free and atomic operation per chunk deallocated
136
+ // instead of a simple free.
137
+ if (end_pos)
138
+ --end_pos;
139
+ else {
140
+ end_pos = N - 1;
141
+ end_chunk = end_chunk->prev;
142
+ free (end_chunk->next);
143
+ end_chunk->next = NULL;
144
+ }
145
+ }
146
+
147
+ // Removes an element from the front end of the queue.
148
+ inline void pop ()
149
+ {
150
+ if (++ begin_pos == N) {
151
+ chunk_t *o = begin_chunk;
152
+ begin_chunk = begin_chunk->next;
153
+ begin_chunk->prev = NULL;
154
+ begin_pos = 0;
155
+
156
+ // 'o' has been more recently used than spare_chunk,
157
+ // so for cache reasons we'll get rid of the spare and
158
+ // use 'o' as the spare.
159
+ chunk_t *cs = spare_chunk.xchg (o);
160
+ if (cs)
161
+ free (cs);
162
+ }
163
+ }
164
+
165
+ private:
166
+
167
+ // Individual memory chunk to hold N elements.
168
+ struct chunk_t
169
+ {
170
+ T values [N];
171
+ chunk_t *prev;
172
+ chunk_t *next;
173
+ };
174
+
175
+ // Back position may point to invalid memory if the queue is empty,
176
+ // while begin & end positions are always valid. Begin position is
177
+ // accessed exclusively be queue reader (front/pop), while back and
178
+ // end positions are accessed exclusively by queue writer (back/push).
179
+ chunk_t *begin_chunk;
180
+ int begin_pos;
181
+ chunk_t *back_chunk;
182
+ int back_pos;
183
+ chunk_t *end_chunk;
184
+ int end_pos;
185
+
186
+ // People are likely to produce and consume at similar rates. In
187
+ // this scenario holding onto the most recently freed chunk saves
188
+ // us from having to call malloc/free.
189
+ atomic_ptr_t<chunk_t> spare_chunk;
190
+
191
+ // Disable copying of yqueue.
192
+ yqueue_t (const yqueue_t&);
193
+ const yqueue_t &operator = (const yqueue_t&);
194
+ };
195
+
196
+ }
197
+
198
+ #endif
@@ -0,0 +1,798 @@
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
+ // On AIX, poll.h has to be included before zmq.h to get consistent
24
+ // definition of pollfd structure (AIX uses 'reqevents' and 'retnevents'
25
+ // instead of 'events' and 'revents' and defines macros to map from POSIX-y
26
+ // names to AIX-specific names).
27
+ #if defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD ||\
28
+ defined ZMQ_HAVE_OPENBSD || defined ZMQ_HAVE_SOLARIS ||\
29
+ defined ZMQ_HAVE_OSX || defined ZMQ_HAVE_QNXNTO ||\
30
+ defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_AIX ||\
31
+ defined ZMQ_HAVE_NETBSD
32
+ #include <poll.h>
33
+ #endif
34
+
35
+ #include "../include/zmq.h"
36
+ #include "../include/zmq_utils.h"
37
+
38
+ #include <string.h>
39
+ #include <errno.h>
40
+ #include <stdlib.h>
41
+ #include <new>
42
+
43
+ #include "device.hpp"
44
+ #include "socket_base.hpp"
45
+ #include "msg_content.hpp"
46
+ #include "stdint.hpp"
47
+ #include "config.hpp"
48
+ #include "likely.hpp"
49
+ #include "clock.hpp"
50
+ #include "ctx.hpp"
51
+ #include "err.hpp"
52
+ #include "fd.hpp"
53
+
54
+ #if !defined ZMQ_HAVE_WINDOWS
55
+ #include <unistd.h>
56
+ #endif
57
+
58
+ #if defined ZMQ_HAVE_OPENPGM
59
+ #define __PGM_WININT_H__
60
+ #include <pgm/pgm.h>
61
+
62
+ // TODO: OpenPGM redefines bool -- remove this once OpenPGM is fixed.
63
+ #if defined bool
64
+ #undef bool
65
+ #endif
66
+
67
+ #endif
68
+
69
+ void zmq_version (int *major_, int *minor_, int *patch_)
70
+ {
71
+ *major_ = ZMQ_VERSION_MAJOR;
72
+ *minor_ = ZMQ_VERSION_MINOR;
73
+ *patch_ = ZMQ_VERSION_PATCH;
74
+ }
75
+
76
+ const char *zmq_strerror (int errnum_)
77
+ {
78
+ return zmq::errno_to_string (errnum_);
79
+ }
80
+
81
+ int zmq_msg_init (zmq_msg_t *msg_)
82
+ {
83
+ msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
84
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
85
+ msg_->vsm_size = 0;
86
+ return 0;
87
+ }
88
+
89
+ int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_)
90
+ {
91
+ if (size_ <= ZMQ_MAX_VSM_SIZE) {
92
+ msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
93
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
94
+ msg_->vsm_size = (uint8_t) size_;
95
+ }
96
+ else {
97
+ msg_->content =
98
+ (zmq::msg_content_t*) malloc (sizeof (zmq::msg_content_t) + size_);
99
+ if (!msg_->content) {
100
+ errno = ENOMEM;
101
+ return -1;
102
+ }
103
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
104
+
105
+ zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
106
+ content->data = (void*) (content + 1);
107
+ content->size = size_;
108
+ content->ffn = NULL;
109
+ content->hint = NULL;
110
+ new (&content->refcnt) zmq::atomic_counter_t ();
111
+ }
112
+ return 0;
113
+ }
114
+
115
+ int zmq_msg_init_data (zmq_msg_t *msg_, void *data_, size_t size_,
116
+ zmq_free_fn *ffn_, void *hint_)
117
+ {
118
+ msg_->content = (zmq::msg_content_t*) malloc (sizeof (zmq::msg_content_t));
119
+ alloc_assert (msg_->content);
120
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
121
+ zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
122
+ content->data = data_;
123
+ content->size = size_;
124
+ content->ffn = ffn_;
125
+ content->hint = hint_;
126
+ new (&content->refcnt) zmq::atomic_counter_t ();
127
+ return 0;
128
+ }
129
+
130
+ int zmq_msg_close (zmq_msg_t *msg_)
131
+ {
132
+ // Check the validity tag.
133
+ if (unlikely (msg_->flags | ZMQ_MSG_MASK) != 0xff) {
134
+ errno = EFAULT;
135
+ return -1;
136
+ }
137
+
138
+ // For VSMs and delimiters there are no resources to free.
139
+ if (msg_->content != (zmq::msg_content_t*) ZMQ_DELIMITER &&
140
+ msg_->content != (zmq::msg_content_t*) ZMQ_VSM) {
141
+
142
+ // If the content is not shared, or if it is shared and the reference.
143
+ // count has dropped to zero, deallocate it.
144
+ zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
145
+ if (!(msg_->flags & ZMQ_MSG_SHARED) || !content->refcnt.sub (1)) {
146
+
147
+ // We used "placement new" operator to initialize the reference.
148
+ // counter so we call its destructor now.
149
+ content->refcnt.~atomic_counter_t ();
150
+
151
+ if (content->ffn)
152
+ content->ffn (content->data, content->hint);
153
+ free (content);
154
+ }
155
+ }
156
+
157
+ // Remove the validity tag from the message.
158
+ msg_->flags = 0;
159
+
160
+ return 0;
161
+ }
162
+
163
+ int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_)
164
+ {
165
+ #if 0
166
+ // Check the validity tags.
167
+ if (unlikely ((dest_->flags | ZMQ_MSG_MASK) != 0xff ||
168
+ (src_->flags | ZMQ_MSG_MASK) != 0xff)) {
169
+ errno = EFAULT;
170
+ return -1;
171
+ }
172
+ #endif
173
+ zmq_msg_close (dest_);
174
+ *dest_ = *src_;
175
+ zmq_msg_init (src_);
176
+ return 0;
177
+ }
178
+
179
+ int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_)
180
+ {
181
+ // Check the validity tags.
182
+ if (unlikely ((dest_->flags | ZMQ_MSG_MASK) != 0xff ||
183
+ (src_->flags | ZMQ_MSG_MASK) != 0xff)) {
184
+ errno = EFAULT;
185
+ return -1;
186
+ }
187
+
188
+ zmq_msg_close (dest_);
189
+
190
+ // VSMs and delimiters require no special handling.
191
+ if (src_->content != (zmq::msg_content_t*) ZMQ_DELIMITER &&
192
+ src_->content != (zmq::msg_content_t*) ZMQ_VSM) {
193
+
194
+ // One reference is added to shared messages. Non-shared messages
195
+ // are turned into shared messages and reference count is set to 2.
196
+ zmq::msg_content_t *content = (zmq::msg_content_t*) src_->content;
197
+ if (src_->flags & ZMQ_MSG_SHARED)
198
+ content->refcnt.add (1);
199
+ else {
200
+ src_->flags |= ZMQ_MSG_SHARED;
201
+ content->refcnt.set (2);
202
+ }
203
+ }
204
+
205
+ *dest_ = *src_;
206
+ return 0;
207
+ }
208
+
209
+ void *zmq_msg_data (zmq_msg_t *msg_)
210
+ {
211
+ zmq_assert ((msg_->flags | ZMQ_MSG_MASK) == 0xff);
212
+
213
+ if (msg_->content == (zmq::msg_content_t*) ZMQ_VSM)
214
+ return msg_->vsm_data;
215
+ if (msg_->content == (zmq::msg_content_t*) ZMQ_DELIMITER)
216
+ return NULL;
217
+
218
+ return ((zmq::msg_content_t*) msg_->content)->data;
219
+ }
220
+
221
+ size_t zmq_msg_size (zmq_msg_t *msg_)
222
+ {
223
+ zmq_assert ((msg_->flags | ZMQ_MSG_MASK) == 0xff);
224
+
225
+ if (msg_->content == (zmq::msg_content_t*) ZMQ_VSM)
226
+ return msg_->vsm_size;
227
+ if (msg_->content == (zmq::msg_content_t*) ZMQ_DELIMITER)
228
+ return 0;
229
+
230
+ return ((zmq::msg_content_t*) msg_->content)->size;
231
+ }
232
+
233
+ void *zmq_init (int io_threads_)
234
+ {
235
+ if (io_threads_ < 0) {
236
+ errno = EINVAL;
237
+ return NULL;
238
+ }
239
+
240
+ #if defined ZMQ_HAVE_OPENPGM
241
+
242
+ // Init PGM transport. Ensure threading and timer are enabled. Find PGM
243
+ // protocol ID. Note that if you want to use gettimeofday and sleep for
244
+ // openPGM timing, set environment variables PGM_TIMER to "GTOD" and
245
+ // PGM_SLEEP to "USLEEP".
246
+ pgm_error_t *pgm_error = NULL;
247
+ const bool ok = pgm_init (&pgm_error);
248
+ if (ok != TRUE) {
249
+
250
+ // Invalid parameters don't set pgm_error_t
251
+ zmq_assert (pgm_error != NULL);
252
+ if (pgm_error->domain == PGM_ERROR_DOMAIN_TIME && (
253
+ pgm_error->code == PGM_ERROR_FAILED)) {
254
+
255
+ // Failed to access RTC or HPET device.
256
+ pgm_error_free (pgm_error);
257
+ errno = EINVAL;
258
+ return NULL;
259
+ }
260
+
261
+ // PGM_ERROR_DOMAIN_ENGINE: WSAStartup errors or missing WSARecvMsg.
262
+ zmq_assert (false);
263
+ }
264
+ #endif
265
+
266
+ #ifdef ZMQ_HAVE_WINDOWS
267
+ // Intialise Windows sockets. Note that WSAStartup can be called multiple
268
+ // times given that WSACleanup will be called for each WSAStartup.
269
+ // We do this before the ctx constructor since its embedded mailbox_t
270
+ // object needs Winsock to be up and running.
271
+ WORD version_requested = MAKEWORD (2, 2);
272
+ WSADATA wsa_data;
273
+ int rc = WSAStartup (version_requested, &wsa_data);
274
+ zmq_assert (rc == 0);
275
+ zmq_assert (LOBYTE (wsa_data.wVersion) == 2 &&
276
+ HIBYTE (wsa_data.wVersion) == 2);
277
+ #endif
278
+
279
+ // Create 0MQ context.
280
+ zmq::ctx_t *ctx = new (std::nothrow) zmq::ctx_t ((uint32_t) io_threads_);
281
+ alloc_assert (ctx);
282
+ return (void*) ctx;
283
+ }
284
+
285
+ int zmq_term (void *ctx_)
286
+ {
287
+ if (!ctx_ || !((zmq::ctx_t*) ctx_)->check_tag ()) {
288
+ errno = EFAULT;
289
+ return -1;
290
+ }
291
+
292
+ int rc = ((zmq::ctx_t*) ctx_)->terminate ();
293
+ int en = errno;
294
+
295
+ #ifdef ZMQ_HAVE_WINDOWS
296
+ // On Windows, uninitialise socket layer.
297
+ rc = WSACleanup ();
298
+ wsa_assert (rc != SOCKET_ERROR);
299
+ #endif
300
+
301
+ #if defined ZMQ_HAVE_OPENPGM
302
+ // Shut down the OpenPGM library.
303
+ if (pgm_shutdown () != TRUE)
304
+ zmq_assert (false);
305
+ #endif
306
+
307
+ errno = en;
308
+ return rc;
309
+ }
310
+
311
+ void *zmq_socket (void *ctx_, int type_)
312
+ {
313
+ if (!ctx_ || !((zmq::ctx_t*) ctx_)->check_tag ()) {
314
+ errno = EFAULT;
315
+ return NULL;
316
+ }
317
+ return (void*) (((zmq::ctx_t*) ctx_)->create_socket (type_));
318
+ }
319
+
320
+ int zmq_close (void *s_)
321
+ {
322
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
323
+ errno = ENOTSOCK;
324
+ return -1;
325
+ }
326
+ ((zmq::socket_base_t*) s_)->close ();
327
+ return 0;
328
+ }
329
+
330
+ int zmq_setsockopt (void *s_, int option_, const void *optval_,
331
+ size_t optvallen_)
332
+ {
333
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
334
+ errno = ENOTSOCK;
335
+ return -1;
336
+ }
337
+ return (((zmq::socket_base_t*) s_)->setsockopt (option_, optval_,
338
+ optvallen_));
339
+ }
340
+
341
+ int zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_)
342
+ {
343
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
344
+ errno = ENOTSOCK;
345
+ return -1;
346
+ }
347
+ return (((zmq::socket_base_t*) s_)->getsockopt (option_, optval_,
348
+ optvallen_));
349
+ }
350
+
351
+ int zmq_bind (void *s_, const char *addr_)
352
+ {
353
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
354
+ errno = ENOTSOCK;
355
+ return -1;
356
+ }
357
+ return (((zmq::socket_base_t*) s_)->bind (addr_));
358
+ }
359
+
360
+ int zmq_connect (void *s_, const char *addr_)
361
+ {
362
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
363
+ errno = ENOTSOCK;
364
+ return -1;
365
+ }
366
+ return (((zmq::socket_base_t*) s_)->connect (addr_));
367
+ }
368
+
369
+ int zmq_send (void *s_, zmq_msg_t *msg_, int flags_)
370
+ {
371
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
372
+ errno = ENOTSOCK;
373
+ return -1;
374
+ }
375
+ return (((zmq::socket_base_t*) s_)->send (msg_, flags_));
376
+ }
377
+
378
+ int zmq_recv (void *s_, zmq_msg_t *msg_, int flags_)
379
+ {
380
+ if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
381
+ errno = ENOTSOCK;
382
+ return -1;
383
+ }
384
+ return (((zmq::socket_base_t*) s_)->recv (msg_, flags_));
385
+ }
386
+
387
+ #if defined ZMQ_FORCE_SELECT
388
+ #define ZMQ_POLL_BASED_ON_SELECT
389
+ #elif defined ZMQ_FORCE_POLL
390
+ #define ZMQ_POLL_BASED_ON_POLL
391
+ #elif defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD ||\
392
+ defined ZMQ_HAVE_OPENBSD || defined ZMQ_HAVE_SOLARIS ||\
393
+ defined ZMQ_HAVE_OSX || defined ZMQ_HAVE_QNXNTO ||\
394
+ defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_AIX ||\
395
+ defined ZMQ_HAVE_NETBSD
396
+ #define ZMQ_POLL_BASED_ON_POLL
397
+ #elif defined ZMQ_HAVE_WINDOWS || defined ZMQ_HAVE_OPENVMS
398
+ #define ZMQ_POLL_BASED_ON_SELECT
399
+ #endif
400
+
401
+ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
402
+ {
403
+ #if defined ZMQ_POLL_BASED_ON_POLL
404
+ if (unlikely (nitems_ < 0)) {
405
+ errno = EINVAL;
406
+ return -1;
407
+ }
408
+ if (unlikely (nitems_ == 0)) {
409
+ if (timeout_ == 0)
410
+ return 0;
411
+ #if defined ZMQ_HAVE_WINDOWS
412
+ Sleep (timeout_ > 0 ? timeout_ / 1000 : INFINITE);
413
+ return 0;
414
+ #else
415
+ return usleep (timeout_);
416
+ #endif
417
+ }
418
+
419
+ if (!items_) {
420
+ errno = EFAULT;
421
+ return -1;
422
+ }
423
+
424
+ zmq::clock_t clock;
425
+ uint64_t now = 0;
426
+ uint64_t end = 0;
427
+
428
+ pollfd *pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd));
429
+ alloc_assert (pollfds);
430
+
431
+ // Build pollset for poll () system call.
432
+ for (int i = 0; i != nitems_; i++) {
433
+
434
+ // If the poll item is a 0MQ socket, we poll on the file descriptor
435
+ // retrieved by the ZMQ_FD socket option.
436
+ if (items_ [i].socket) {
437
+ size_t zmq_fd_size = sizeof (zmq::fd_t);
438
+ if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, &pollfds [i].fd,
439
+ &zmq_fd_size) == -1) {
440
+ free (pollfds);
441
+ return -1;
442
+ }
443
+ pollfds [i].events = items_ [i].events ? POLLIN : 0;
444
+ }
445
+ // Else, the poll item is a raw file descriptor. Just convert the
446
+ // events to normal POLLIN/POLLOUT for poll ().
447
+ else {
448
+ pollfds [i].fd = items_ [i].fd;
449
+ pollfds [i].events =
450
+ (items_ [i].events & ZMQ_POLLIN ? POLLIN : 0) |
451
+ (items_ [i].events & ZMQ_POLLOUT ? POLLOUT : 0);
452
+ }
453
+ }
454
+
455
+ bool first_pass = true;
456
+ int nevents = 0;
457
+
458
+ while (true) {
459
+
460
+ // Compute the timeout for the subsequent poll.
461
+ int timeout;
462
+ if (first_pass)
463
+ timeout = 0;
464
+ else if (timeout_ < 0)
465
+ timeout = -1;
466
+ else
467
+ timeout = end - now;
468
+
469
+ // Wait for events.
470
+ while (true) {
471
+ int rc = poll (pollfds, nitems_, timeout);
472
+ if (rc == -1 && errno == EINTR) {
473
+ free (pollfds);
474
+ return -1;
475
+ }
476
+ errno_assert (rc >= 0);
477
+ break;
478
+ }
479
+
480
+ // Check for the events.
481
+ for (int i = 0; i != nitems_; i++) {
482
+
483
+ items_ [i].revents = 0;
484
+
485
+ // The poll item is a 0MQ socket. Retrieve pending events
486
+ // using the ZMQ_EVENTS socket option.
487
+ if (items_ [i].socket) {
488
+ size_t zmq_events_size = sizeof (uint32_t);
489
+ uint32_t zmq_events;
490
+ if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events,
491
+ &zmq_events_size) == -1) {
492
+ free (pollfds);
493
+ return -1;
494
+ }
495
+ if ((items_ [i].events & ZMQ_POLLOUT) &&
496
+ (zmq_events & ZMQ_POLLOUT))
497
+ items_ [i].revents |= ZMQ_POLLOUT;
498
+ if ((items_ [i].events & ZMQ_POLLIN) &&
499
+ (zmq_events & ZMQ_POLLIN))
500
+ items_ [i].revents |= ZMQ_POLLIN;
501
+ }
502
+ // Else, the poll item is a raw file descriptor, simply convert
503
+ // the events to zmq_pollitem_t-style format.
504
+ else {
505
+ if (pollfds [i].revents & POLLIN)
506
+ items_ [i].revents |= ZMQ_POLLIN;
507
+ if (pollfds [i].revents & POLLOUT)
508
+ items_ [i].revents |= ZMQ_POLLOUT;
509
+ if (pollfds [i].revents & ~(POLLIN | POLLOUT))
510
+ items_ [i].revents |= ZMQ_POLLERR;
511
+ }
512
+
513
+ if (items_ [i].revents)
514
+ nevents++;
515
+ }
516
+
517
+ // If timout is zero, exit immediately whether there are events or not.
518
+ if (timeout_ == 0)
519
+ break;
520
+
521
+ // If there are events to return, we can exit immediately.
522
+ if (nevents)
523
+ break;
524
+
525
+ // At this point we are meant to wait for events but there are none.
526
+ // If timeout is infinite we can just loop until we get some events.
527
+ if (timeout_ < 0) {
528
+ if (first_pass)
529
+ first_pass = false;
530
+ continue;
531
+ }
532
+
533
+ // The timeout is finite and there are no events. In the first pass
534
+ // we get a timestamp of when the polling have begun. (We assume that
535
+ // first pass have taken negligible time). We also compute the time
536
+ // when the polling should time out.
537
+ if (first_pass) {
538
+ now = clock.now_ms ();
539
+ end = now + (timeout_ / 1000);
540
+ if (now == end)
541
+ break;
542
+ first_pass = false;
543
+ continue;
544
+ }
545
+
546
+ // Find out whether timeout have expired.
547
+ now = clock.now_ms ();
548
+ if (now >= end)
549
+ break;
550
+ }
551
+
552
+ free (pollfds);
553
+ return nevents;
554
+
555
+ #elif defined ZMQ_POLL_BASED_ON_SELECT
556
+
557
+ if (unlikely (nitems_ < 0)) {
558
+ errno = EINVAL;
559
+ return -1;
560
+ }
561
+ if (unlikely (nitems_ == 0)) {
562
+ if (timeout_ == 0)
563
+ return 0;
564
+ #if defined ZMQ_HAVE_WINDOWS
565
+ Sleep (timeout_ > 0 ? timeout_ / 1000 : INFINITE);
566
+ return 0;
567
+ #else
568
+ return usleep (timeout_);
569
+ #endif
570
+ }
571
+
572
+ if (!items_) {
573
+ errno = EFAULT;
574
+ return -1;
575
+ }
576
+
577
+ zmq::clock_t clock;
578
+ uint64_t now = 0;
579
+ uint64_t end = 0;
580
+
581
+ // Ensure we do not attempt to select () on more than FD_SETSIZE
582
+ // file descriptors.
583
+ zmq_assert (nitems_ <= FD_SETSIZE);
584
+
585
+ fd_set pollset_in;
586
+ FD_ZERO (&pollset_in);
587
+ fd_set pollset_out;
588
+ FD_ZERO (&pollset_out);
589
+ fd_set pollset_err;
590
+ FD_ZERO (&pollset_err);
591
+
592
+ zmq::fd_t maxfd = 0;
593
+
594
+ // Build the fd_sets for passing to select ().
595
+ for (int i = 0; i != nitems_; i++) {
596
+
597
+ // If the poll item is a 0MQ socket we are interested in input on the
598
+ // notification file descriptor retrieved by the ZMQ_FD socket option.
599
+ if (items_ [i].socket) {
600
+ size_t zmq_fd_size = sizeof (zmq::fd_t);
601
+ zmq::fd_t notify_fd;
602
+ if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, &notify_fd,
603
+ &zmq_fd_size) == -1)
604
+ return -1;
605
+ if (items_ [i].events) {
606
+ FD_SET (notify_fd, &pollset_in);
607
+ if (maxfd < notify_fd)
608
+ maxfd = notify_fd;
609
+ }
610
+ }
611
+ // Else, the poll item is a raw file descriptor. Convert the poll item
612
+ // events to the appropriate fd_sets.
613
+ else {
614
+ if (items_ [i].events & ZMQ_POLLIN)
615
+ FD_SET (items_ [i].fd, &pollset_in);
616
+ if (items_ [i].events & ZMQ_POLLOUT)
617
+ FD_SET (items_ [i].fd, &pollset_out);
618
+ if (items_ [i].events & ZMQ_POLLERR)
619
+ FD_SET (items_ [i].fd, &pollset_err);
620
+ if (maxfd < items_ [i].fd)
621
+ maxfd = items_ [i].fd;
622
+ }
623
+ }
624
+
625
+ bool first_pass = true;
626
+ int nevents = 0;
627
+ fd_set inset, outset, errset;
628
+
629
+ while (true) {
630
+
631
+ // Compute the timeout for the subsequent poll.
632
+ timeval timeout;
633
+ timeval *ptimeout;
634
+ if (first_pass) {
635
+ timeout.tv_sec = 0;
636
+ timeout.tv_usec = 0;
637
+ ptimeout = &timeout;
638
+ }
639
+ else if (timeout_ < 0)
640
+ ptimeout = NULL;
641
+ else {
642
+ timeout.tv_sec = (long) ((end - now) / 1000);
643
+ timeout.tv_usec = (long) ((end - now) % 1000 * 1000);
644
+ ptimeout = &timeout;
645
+ }
646
+
647
+ // Wait for events. Ignore interrupts if there's infinite timeout.
648
+ while (true) {
649
+ memcpy (&inset, &pollset_in, sizeof (fd_set));
650
+ memcpy (&outset, &pollset_out, sizeof (fd_set));
651
+ memcpy (&errset, &pollset_err, sizeof (fd_set));
652
+ int rc = select (maxfd + 1, &inset, &outset, &errset, ptimeout);
653
+ #if defined ZMQ_HAVE_WINDOWS
654
+ wsa_assert (rc != SOCKET_ERROR);
655
+ #else
656
+ if (rc == -1 && errno == EINTR)
657
+ return -1;
658
+ errno_assert (rc >= 0);
659
+ #endif
660
+ break;
661
+ }
662
+
663
+ // Check for the events.
664
+ for (int i = 0; i != nitems_; i++) {
665
+
666
+ items_ [i].revents = 0;
667
+
668
+ // The poll item is a 0MQ socket. Retrieve pending events
669
+ // using the ZMQ_EVENTS socket option.
670
+ if (items_ [i].socket) {
671
+ size_t zmq_events_size = sizeof (uint32_t);
672
+ uint32_t zmq_events;
673
+ if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events,
674
+ &zmq_events_size) == -1)
675
+ return -1;
676
+ if ((items_ [i].events & ZMQ_POLLOUT) &&
677
+ (zmq_events & ZMQ_POLLOUT))
678
+ items_ [i].revents |= ZMQ_POLLOUT;
679
+ if ((items_ [i].events & ZMQ_POLLIN) &&
680
+ (zmq_events & ZMQ_POLLIN))
681
+ items_ [i].revents |= ZMQ_POLLIN;
682
+ }
683
+ // Else, the poll item is a raw file descriptor, simply convert
684
+ // the events to zmq_pollitem_t-style format.
685
+ else {
686
+ if (FD_ISSET (items_ [i].fd, &inset))
687
+ items_ [i].revents |= ZMQ_POLLIN;
688
+ if (FD_ISSET (items_ [i].fd, &outset))
689
+ items_ [i].revents |= ZMQ_POLLOUT;
690
+ if (FD_ISSET (items_ [i].fd, &errset))
691
+ items_ [i].revents |= ZMQ_POLLERR;
692
+ }
693
+
694
+ if (items_ [i].revents)
695
+ nevents++;
696
+ }
697
+
698
+ // If timout is zero, exit immediately whether there are events or not.
699
+ if (timeout_ == 0)
700
+ break;
701
+
702
+ // If there are events to return, we can exit immediately.
703
+ if (nevents)
704
+ break;
705
+
706
+ // At this point we are meant to wait for events but there are none.
707
+ // If timeout is infinite we can just loop until we get some events.
708
+ if (timeout_ < 0) {
709
+ if (first_pass)
710
+ first_pass = false;
711
+ continue;
712
+ }
713
+
714
+ // The timeout is finite and there are no events. In the first pass
715
+ // we get a timestamp of when the polling have begun. (We assume that
716
+ // first pass have taken negligible time). We also compute the time
717
+ // when the polling should time out.
718
+ if (first_pass) {
719
+ now = clock.now_ms ();
720
+ end = now + (timeout_ / 1000);
721
+ if (now == end)
722
+ break;
723
+ first_pass = false;
724
+ continue;
725
+ }
726
+
727
+ // Find out whether timeout have expired.
728
+ now = clock.now_ms ();
729
+ if (now >= end)
730
+ break;
731
+ }
732
+
733
+ return nevents;
734
+
735
+ #else
736
+ // Exotic platforms that support neither poll() nor select().
737
+ errno = ENOTSUP;
738
+ return -1;
739
+ #endif
740
+ }
741
+
742
+ #if defined ZMQ_POLL_BASED_ON_SELECT
743
+ #undef ZMQ_POLL_BASED_ON_SELECT
744
+ #endif
745
+ #if defined ZMQ_POLL_BASED_ON_POLL
746
+ #undef ZMQ_POLL_BASED_ON_POLL
747
+ #endif
748
+
749
+ int zmq_errno ()
750
+ {
751
+ return errno;
752
+ }
753
+
754
+ int zmq_device (int device_, void *insocket_, void *outsocket_)
755
+ {
756
+ if (!insocket_ || !outsocket_) {
757
+ errno = EFAULT;
758
+ return -1;
759
+ }
760
+
761
+ if (device_ != ZMQ_FORWARDER && device_ != ZMQ_QUEUE &&
762
+ device_ != ZMQ_STREAMER) {
763
+ errno = EINVAL;
764
+ return -1;
765
+ }
766
+
767
+ return zmq::device ((zmq::socket_base_t*) insocket_,
768
+ (zmq::socket_base_t*) outsocket_);
769
+ }
770
+
771
+ ////////////////////////////////////////////////////////////////////////////////
772
+ // 0MQ utils - to be used by perf tests
773
+ ////////////////////////////////////////////////////////////////////////////////
774
+
775
+ void zmq_sleep (int seconds_)
776
+ {
777
+ #if defined ZMQ_HAVE_WINDOWS
778
+ Sleep (seconds_ * 1000);
779
+ #else
780
+ sleep (seconds_);
781
+ #endif
782
+ }
783
+
784
+ void *zmq_stopwatch_start ()
785
+ {
786
+ uint64_t *watch = (uint64_t*) malloc (sizeof (uint64_t));
787
+ alloc_assert (watch);
788
+ *watch = zmq::clock_t::now_us ();
789
+ return (void*) watch;
790
+ }
791
+
792
+ unsigned long zmq_stopwatch_stop (void *watch_)
793
+ {
794
+ uint64_t end = zmq::clock_t::now_us ();
795
+ uint64_t start = *(uint64_t*) watch_;
796
+ free (watch_);
797
+ return (unsigned long) (end - start);
798
+ }