zmq_alt.hpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. Copyright (c) 2007-2011 iMatix Corporation
  3. Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
  4. This file is part of 0MQ.
  5. 0MQ is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. 0MQ is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifndef __ZMQ_HPP_INCLUDED__
  17. #define __ZMQ_HPP_INCLUDED__
  18. #include <zmq.h>
  19. #include <algorithm>
  20. #include <cassert>
  21. #include <cstring>
  22. #include <exception>
  23. // Detect whether the compiler supports C++11 rvalue references.
  24. #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
  25. # define ZMQ_HAS_RVALUE_REFS
  26. #endif
  27. #if (defined(__clang__))
  28. # if __has_feature(cxx_rvalue_references)
  29. # define ZMQ_HAS_RVALUE_REFS
  30. # endif
  31. #endif
  32. #if (defined(_MSC_VER) && (_MSC_VER >= 1600))
  33. # define ZMQ_HAS_RVALUE_REFS
  34. #endif
  35. // In order to prevent unused variable warnings when building in non-debug
  36. // mode use this macro to make assertions.
  37. #ifndef NDEBUG
  38. # define ZMQ_ASSERT(expression) assert(expression)
  39. #else
  40. # define ZMQ_ASSERT(expression) (expression)
  41. #endif
  42. namespace zmq
  43. {
  44. typedef zmq_free_fn free_fn;
  45. typedef zmq_pollitem_t pollitem_t;
  46. inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1)
  47. {
  48. int rc = zmq_poll (items_, nitems_, timeout_);
  49. if (rc < 0)
  50. return -1;
  51. return rc;
  52. }
  53. inline bool device (int device_, void * insocket_, void* outsocket_)
  54. {
  55. int rc = zmq_device (device_, insocket_, outsocket_);
  56. if (rc != 0)
  57. return 0;
  58. return 1;
  59. }
  60. inline void version (int *major_, int *minor_, int *patch_)
  61. {
  62. zmq_version (major_, minor_, patch_);
  63. }
  64. class message_t : private zmq_msg_t
  65. {
  66. friend class socket_t;
  67. public:
  68. inline message_t ()
  69. {
  70. int rc = zmq_msg_init (this);
  71. }
  72. inline message_t (size_t size_)
  73. {
  74. int rc = zmq_msg_init_size (this, size_);
  75. }
  76. inline message_t (void *data_, size_t size_, free_fn *ffn_,
  77. void *hint_ = NULL)
  78. {
  79. int rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
  80. }
  81. inline ~message_t ()
  82. {
  83. int rc = zmq_msg_close (this);
  84. ZMQ_ASSERT (rc == 0);
  85. }
  86. inline bool rebuild ()
  87. {
  88. int rc = zmq_msg_close (this);
  89. if (rc != 0)
  90. return 0;
  91. rc = zmq_msg_init (this);
  92. if (rc != 0)
  93. return 0;
  94. return 1;
  95. }
  96. inline bool rebuild (size_t size_)
  97. {
  98. int rc = zmq_msg_close (this);
  99. if (rc != 0)
  100. return 0;
  101. rc = zmq_msg_init_size (this, size_);
  102. if (rc != 0)
  103. return 0;
  104. return 1;
  105. }
  106. inline bool rebuild (void *data_, size_t size_, free_fn *ffn_,
  107. void *hint_ = NULL)
  108. {
  109. int rc = zmq_msg_close (this);
  110. if (rc != 0)
  111. return 0;
  112. rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
  113. if (rc != 0)
  114. return 0;
  115. return 1;
  116. }
  117. inline bool move (message_t *msg_)
  118. {
  119. int rc = zmq_msg_move (this, (zmq_msg_t*) msg_);
  120. if (rc != 0)
  121. return 0;
  122. return 1;
  123. }
  124. inline bool copy (message_t *msg_)
  125. {
  126. int rc = zmq_msg_copy (this, (zmq_msg_t*) msg_);
  127. if (rc != 0)
  128. return 0;
  129. return 1;
  130. }
  131. inline void *data ()
  132. {
  133. return zmq_msg_data (this);
  134. }
  135. inline size_t size ()
  136. {
  137. return zmq_msg_size (this);
  138. }
  139. private:
  140. // Disable implicit message copying, so that users won't use shared
  141. // messages (less efficient) without being aware of the fact.
  142. message_t (const message_t&);
  143. void operator = (const message_t&);
  144. };
  145. class context_t
  146. {
  147. friend class socket_t;
  148. public:
  149. inline context_t (int io_threads_)
  150. {
  151. ptr = zmq_init (io_threads_);
  152. }
  153. #ifdef ZMQ_HAS_RVALUE_REFS
  154. inline context_t(context_t&& rhs) : ptr(rhs.ptr)
  155. {
  156. rhs.ptr = NULL;
  157. }
  158. inline context_t& operator=(context_t&& rhs)
  159. {
  160. std::swap(ptr, rhs.ptr);
  161. return *this;
  162. }
  163. #endif
  164. inline ~context_t ()
  165. {
  166. if (ptr == NULL)
  167. return;
  168. int rc = zmq_term (ptr);
  169. ZMQ_ASSERT (rc == 0);
  170. }
  171. // Be careful with this, it's probably only useful for
  172. // using the C api together with an existing C++ api.
  173. // Normally you should never need to use this.
  174. inline operator void* ()
  175. {
  176. return ptr;
  177. }
  178. private:
  179. void *ptr;
  180. context_t (const context_t&);
  181. void operator = (const context_t&);
  182. };
  183. class socket_t
  184. {
  185. public:
  186. inline socket_t (context_t &context_, int type_)
  187. {
  188. err = 0;
  189. ptr = zmq_socket (context_.ptr, type_);
  190. if (ptr == NULL)
  191. err = 1;
  192. }
  193. #ifdef ZMQ_HAS_RVALUE_REFS
  194. inline socket_t(socket_t&& rhs) : ptr(rhs.ptr)
  195. {
  196. err = 0;
  197. rhs.ptr = NULL;
  198. }
  199. inline socket_t& operator=(socket_t&& rhs)
  200. {
  201. err = 0;
  202. std::swap(ptr, rhs.ptr);
  203. return *this;
  204. }
  205. #endif
  206. inline ~socket_t ()
  207. {
  208. close();
  209. }
  210. inline operator void* ()
  211. {
  212. return ptr;
  213. }
  214. inline bool isOk()
  215. {
  216. return !err;
  217. }
  218. inline bool close()
  219. {
  220. if(ptr == NULL)
  221. // already closed
  222. return 1;
  223. int rc = zmq_close (ptr);
  224. if (rc != 0)
  225. return 0;
  226. ptr = 0 ;
  227. return 1;
  228. }
  229. inline bool setsockopt (int option_, const void *optval_,
  230. size_t optvallen_)
  231. {
  232. int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
  233. if (rc != 0)
  234. return 0;
  235. return 1;
  236. }
  237. inline bool getsockopt (int option_, void *optval_,
  238. size_t *optvallen_)
  239. {
  240. int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_);
  241. if (rc != 0)
  242. return 0;
  243. return 1;
  244. }
  245. inline bool bind (const char *addr_)
  246. {
  247. int rc = zmq_bind (ptr, addr_);
  248. if (rc != 0)
  249. return 0;
  250. return 1;
  251. }
  252. inline bool connect (const char *addr_)
  253. {
  254. int rc = zmq_connect (ptr, addr_);
  255. if (rc != 0)
  256. return 0;
  257. return 1;
  258. }
  259. inline bool send (message_t &msg_, int flags_ = 0)
  260. {
  261. int rc = zmq_send (ptr, &msg_, flags_);
  262. if (rc == 0)
  263. return true;
  264. if (rc == -1 && zmq_errno () == EAGAIN)
  265. return false;
  266. return false;
  267. }
  268. inline bool recv (message_t *msg_, int flags_ = 0)
  269. {
  270. int rc = zmq_recv (ptr, msg_, flags_);
  271. if (rc == 0)
  272. return true;
  273. if (rc == -1 && zmq_errno () == EAGAIN)
  274. return false;
  275. return false;
  276. }
  277. private:
  278. bool err;
  279. void *ptr;
  280. socket_t (const socket_t&);
  281. void operator = (const socket_t&);
  282. };
  283. }
  284. #endif