rbczmq 1.7.4 → 1.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +4 -1
  3. data/CHANGELOG.rdoc +13 -0
  4. data/Gemfile +8 -1
  5. data/Gemfile.lock +211 -2
  6. data/README.rdoc +7 -4
  7. data/ext/rbczmq/beacon.c +6 -3
  8. data/ext/rbczmq/context.c +117 -8
  9. data/ext/rbczmq/context.h +5 -0
  10. data/ext/rbczmq/message.c +6 -4
  11. data/ext/rbczmq/poller.c +12 -5
  12. data/ext/rbczmq/rbczmq_ext.c +2 -0
  13. data/ext/rbczmq/rbczmq_ext.h +1 -0
  14. data/ext/rbczmq/socket.c +135 -59
  15. data/ext/rbczmq/socket.h +2 -0
  16. data/ext/zeromq/CMakeLists.txt +3 -1
  17. data/ext/zeromq/NEWS +28 -3
  18. data/ext/zeromq/doc/zmq.txt +3 -3
  19. data/ext/zeromq/doc/zmq_getsockopt.txt +3 -3
  20. data/ext/zeromq/doc/zmq_msg_get.txt +2 -1
  21. data/ext/zeromq/doc/zmq_msg_more.txt +1 -1
  22. data/ext/zeromq/doc/zmq_setsockopt.txt +18 -19
  23. data/ext/zeromq/doc/zmq_socket.txt +4 -0
  24. data/ext/zeromq/include/zmq.h +14 -18
  25. data/ext/zeromq/src/clock.cpp +57 -2
  26. data/ext/zeromq/src/ctx.cpp +11 -5
  27. data/ext/zeromq/src/devpoll.cpp +5 -0
  28. data/ext/zeromq/src/devpoll.hpp +2 -0
  29. data/ext/zeromq/src/epoll.cpp +5 -0
  30. data/ext/zeromq/src/epoll.hpp +2 -0
  31. data/ext/zeromq/src/i_engine.hpp +2 -2
  32. data/ext/zeromq/src/kqueue.cpp +5 -0
  33. data/ext/zeromq/src/kqueue.hpp +2 -0
  34. data/ext/zeromq/src/pgm_receiver.cpp +2 -2
  35. data/ext/zeromq/src/pgm_receiver.hpp +2 -2
  36. data/ext/zeromq/src/pgm_sender.cpp +2 -2
  37. data/ext/zeromq/src/pgm_sender.hpp +2 -2
  38. data/ext/zeromq/src/poll.cpp +5 -0
  39. data/ext/zeromq/src/poll.hpp +2 -0
  40. data/ext/zeromq/src/router.cpp +2 -0
  41. data/ext/zeromq/src/select.cpp +5 -0
  42. data/ext/zeromq/src/select.hpp +2 -0
  43. data/ext/zeromq/src/session_base.cpp +2 -2
  44. data/ext/zeromq/src/signaler.cpp +73 -99
  45. data/ext/zeromq/src/signaler.hpp +2 -2
  46. data/ext/zeromq/src/socket_base.cpp +42 -40
  47. data/ext/zeromq/src/stream_engine.cpp +60 -58
  48. data/ext/zeromq/src/stream_engine.hpp +7 -8
  49. data/ext/zeromq/src/zmq_utils.cpp +6 -5
  50. data/ext/zeromq/tests/Makefile.am +6 -5
  51. data/ext/zeromq/tests/test_conflate.cpp +2 -5
  52. data/ext/zeromq/tests/test_ctx_destroy.cpp +1 -1
  53. data/ext/zeromq/tests/test_ctx_options.cpp +1 -1
  54. data/ext/zeromq/tests/test_immediate.cpp +1 -2
  55. data/ext/zeromq/tests/test_inproc_connect.cpp +1 -1
  56. data/ext/zeromq/tests/test_iov.cpp +1 -1
  57. data/ext/zeromq/tests/test_many_sockets.cpp +90 -0
  58. data/ext/zeromq/tests/test_monitor.cpp +3 -3
  59. data/ext/zeromq/tests/test_req_relaxed.cpp +1 -1
  60. data/ext/zeromq/tests/test_router_raw_empty.cpp +65 -0
  61. data/ext/zeromq/tests/test_spec_req.cpp +1 -1
  62. data/ext/zeromq/tests/test_stream.cpp +6 -7
  63. data/ext/zeromq/tests/test_sub_forward.cpp +1 -1
  64. data/ext/zeromq/tests/test_term_endpoint.cpp +2 -2
  65. data/ext/zeromq/tests/testutil.hpp +18 -1
  66. data/ext/zeromq/tools/Makefile.am +1 -1
  67. data/lib/zmq/socket.rb +1 -0
  68. data/lib/zmq/socket/stream.rb +44 -0
  69. data/lib/zmq/version.rb +1 -1
  70. data/test/socket/test_dealer_socket.rb +1 -1
  71. data/test/socket/test_pair_socket.rb +1 -1
  72. data/test/socket/test_pair_sockets.rb +1 -1
  73. data/test/socket/test_pub_socket.rb +1 -1
  74. data/test/socket/test_pub_sub_sockets.rb +1 -1
  75. data/test/socket/test_pull_socket.rb +1 -1
  76. data/test/socket/test_push_pull_sockets.rb +1 -1
  77. data/test/socket/test_push_socket.rb +1 -1
  78. data/test/socket/test_rep_socket.rb +1 -1
  79. data/test/socket/test_req_rep_sockets.rb +1 -1
  80. data/test/socket/test_req_socket.rb +1 -1
  81. data/test/socket/test_router_socket.rb +1 -1
  82. data/test/socket/test_routing.rb +1 -1
  83. data/test/socket/test_stream_socket.rb +74 -0
  84. data/test/socket/test_sub_socket.rb +1 -1
  85. data/test/test_beacon.rb +4 -2
  86. data/test/test_context.rb +2 -2
  87. data/test/test_frame.rb +2 -2
  88. data/test/test_handler.rb +2 -2
  89. data/test/test_logger.rb +1 -1
  90. data/test/test_loop.rb +2 -2
  91. data/test/test_message.rb +1 -1
  92. data/test/test_monitoring.rb +15 -3
  93. data/test/test_poller.rb +2 -2
  94. data/test/test_pollitem.rb +2 -2
  95. data/test/test_socket.rb +53 -6
  96. data/test/test_threading.rb +2 -2
  97. data/test/test_timer.rb +2 -2
  98. data/test/test_zmq.rb +2 -2
  99. metadata +109 -104
@@ -611,7 +611,9 @@ set(tests
611
611
  test_term_endpoint
612
612
  test_timeo
613
613
  test_inproc_connect
614
- test_issue_566)
614
+ test_issue_566
615
+ test_many_sockets
616
+ )
615
617
  if(NOT WIN32)
616
618
  list(APPEND tests
617
619
  test_monitor
@@ -1,3 +1,31 @@
1
+ 0MQ version 4.0.3 stable, released on 2013/11/24
2
+ ================================================
3
+
4
+ Bug Fixes
5
+ ---------
6
+
7
+ * Fixed test_many_sockets case, which failed when process socket limit
8
+ was 1024.
9
+
10
+
11
+ 0MQ version 4.0.2 stable, released on 2013/11/24
12
+ ================================================
13
+
14
+ Bug Fixes
15
+ ---------
16
+
17
+ * Fixed LIBZMQ-583 - improved low-res timer for Windows
18
+ * Fixed LIBZMQ-578 - z85_decode was extremely slow
19
+ * Fixed LIBZMQ-577 - fault in man pages.
20
+ * Fixed LIBZMQ-574 - assertion failure when ran out of system file handles
21
+ * Fixed LIBZMQ-571 - test_stream failing in some cases
22
+ * Fixed LIBZMQ-569 - Socket server crashes with random client data and when
23
+ talking to 2.2 versions
24
+ * Fixed LIBZMQ-39 - Bad file descriptor during shutdown
25
+ * Pulled expected failing test_linger.cpp from release
26
+ * Reduced pause time in tests to allow "make check" to run faster
27
+
28
+
1
29
  0MQ version 4.0.1 stable, released on 2013/10/08
2
30
  ================================================
3
31
 
@@ -23,9 +51,6 @@ Changes
23
51
 
24
52
  * Added zmq_curve_keypair to core libzmq API.
25
53
 
26
- * Replaced macro constants in zmq.h with enum types for user-facing
27
- constants (except ZMQ version numbers).
28
-
29
54
  * Bumped library ABI version to 4:0:1.
30
55
 
31
56
  Bug fixes
@@ -44,9 +44,6 @@ Work with context properties::
44
44
  Destroy a 0MQ context::
45
45
  linkzmq:zmq_ctx_term[3]
46
46
 
47
- Monitor a 0MQ context::
48
- linkzmq:zmq_ctx_set_monitor[3]
49
-
50
47
  These deprecated functions let you create and destroy 'contexts':
51
48
 
52
49
  Initialise 0MQ context::
@@ -142,6 +139,9 @@ Sending and receiving messages::
142
139
  linkzmq:zmq_recv[3]
143
140
  linkzmq:zmq_send_const[3]
144
141
 
142
+ Monitoring socket events:
143
+ linkzmq:zmq_socket_monitor[3]
144
+
145
145
  .Input/output multiplexing
146
146
  0MQ provides a mechanism for applications to multiplex input/output events over
147
147
  a set containing both 0MQ sockets and standard sockets. This mechanism mirrors
@@ -120,8 +120,8 @@ Default value:: 0
120
120
  Applicable socket types:: N/A
121
121
 
122
122
 
123
- ZMQ_IDENTITY: Set socket identity
124
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123
+ ZMQ_IDENTITY: Retrieve socket identity
124
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125
125
  The 'ZMQ_IDENTITY' option shall retrieve the identity of the specified 'socket'.
126
126
  Socket identity is used only by request/reply pattern. Namely, it can be used
127
127
  in tandem with ROUTER socket to route messages to the peer with specific
@@ -134,7 +134,7 @@ starting with binary zero are reserved for use by 0MQ infrastructure.
134
134
  Option value type:: binary data
135
135
  Option value unit:: N/A
136
136
  Default value:: NULL
137
- Applicable socket types:: all
137
+ Applicable socket types:: ZMQ_REP, ZMQ_REQ, ZMQ_ROUTER, ZMQ_DEALER.
138
138
 
139
139
 
140
140
  ZMQ_RATE: Retrieve multicast data rate
@@ -40,6 +40,7 @@ EXAMPLE
40
40
  -------
41
41
  .Receiving a multi-frame message
42
42
  ----
43
+ zmq_msg_t frame;
43
44
  while (true) {
44
45
  // Create an empty 0MQ message to hold the message frame
45
46
  int rc = zmq_msg_init (&frame);
@@ -53,7 +54,7 @@ while (true) {
53
54
  fprintf (stderr, "end\n");
54
55
  break;
55
56
  }
56
- zmq_msg_close (frame);
57
+ zmq_msg_close (&frame);
57
58
  }
58
59
  ----
59
60
 
@@ -45,7 +45,7 @@ while (true) {
45
45
  fprintf (stderr, "end\n");
46
46
  break;
47
47
  }
48
- zmq_msg_close (part);
48
+ zmq_msg_close (&part);
49
49
  }
50
50
  ----
51
51
 
@@ -150,7 +150,7 @@ results shall be undefined.
150
150
  Option value type:: binary data
151
151
  Option value unit:: N/A
152
152
  Default value:: NULL
153
- Applicable socket types:: all
153
+ Applicable socket types:: ZMQ_REQ, ZMQ_REP, ZMQ_ROUTER, ZMQ_DEALER.
154
154
 
155
155
 
156
156
  ZMQ_RATE: Set multicast data rate
@@ -624,7 +624,9 @@ linkzmq:zmq_curve[7]. A value of '1' means the socket will act as
624
624
  CURVE server. A value of '0' means the socket will not act as CURVE
625
625
  server, and its security role then depends on other option settings.
626
626
  Setting this to '0' shall reset the socket security to NULL. When you
627
- set this you must also set the ZMQ_CURVE_PUBLICKEY option.
627
+ set this you must also set the server's secret key using the
628
+ ZMQ_CURVE_SECRETKEY option. A server socket does not need to know
629
+ its own public key.
628
630
 
629
631
  [horizontal]
630
632
  Option value type:: int
@@ -636,14 +638,11 @@ Applicable socket types:: all, when using TCP transport
636
638
  ZMQ_CURVE_PUBLICKEY: Set CURVE public key
637
639
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
638
640
 
639
- Sets the socket's long term public key. You must set this on a CURVE
640
- client or server socket, see linkzmq:zmq_curve[7]. You can provide the
641
- key as 32 binary bytes, or as a 40-character string encoded in the Z85
642
- encoding format. For servers, the public key must be persisted and
643
- shared through some unspecified but secure mechanism to clients. The
644
- public key must always be used with the matching secret key generated
645
- at the same time. To generate a public/secret key pair, use the
646
- tools/curve_keygen tool.
641
+ Sets the socket's long term public key. You must set this on CURVE client
642
+ sockets, see linkzmq:zmq_curve[7]. You can provide the key as 32 binary
643
+ bytes, or as a 40-character string encoded in the Z85 encoding format.
644
+ The public key must always be used with the matching secret key. To
645
+ generate a public/secret key pair, use linkzmq:zmq_curve_keypair[3].
647
646
 
648
647
  [horizontal]
649
648
  Option value type:: binary data or Z85 text string
@@ -655,10 +654,11 @@ Applicable socket types:: all, when using TCP transport
655
654
  ZMQ_CURVE_SECRETKEY: Set CURVE secret key
656
655
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
657
656
 
658
- Sets the socket's long term secret key. You must set this on a CURVE
659
- client socket, see linkzmq:zmq_curve[7]. You can provide the key as
660
- 32 binary bytes, or as a 40-character string encoded in the Z85 encoding
661
- format.
657
+ Sets the socket's long term secret key. You must set this on both CURVE
658
+ client and server sockets, see linkzmq:zmq_curve[7]. You can provide the
659
+ key as 32 binary bytes, or as a 40-character string encoded in the Z85
660
+ encoding format. To generate a public/secret key pair, use
661
+ linkzmq:zmq_curve_keypair[3].
662
662
 
663
663
  [horizontal]
664
664
  Option value type:: binary data or Z85 text string
@@ -670,11 +670,10 @@ Applicable socket types:: all, when using TCP transport
670
670
  ZMQ_CURVE_SERVERKEY: Set CURVE server key
671
671
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
672
672
 
673
- Sets the socket's long term server key. You must set this on a CURVE
674
- client socket, see linkzmq:zmq_curve[7]. You can provide the key as
675
- 32 binary bytes, or as a 40-character string encoded in the Z85 encoding
676
- format. This key must be the same as the public key set on the server
677
- socket.
673
+ Sets the socket's long term server key. You must set this on CURVE client
674
+ sockets, see linkzmq:zmq_curve[7]. You can provide the key as 32 binary
675
+ bytes, or as a 40-character string encoded in the Z85 encoding format.
676
+ This key must have been generated together with the server's secret key.
678
677
 
679
678
  [horizontal]
680
679
  Option value type:: binary data or Z85 text string
@@ -62,6 +62,7 @@ The request-reply pattern is used for sending requests from a ZMQ_REQ _client_
62
62
  to one or more ZMQ_REP _services_, and receiving subsequent replies to each
63
63
  request sent.
64
64
 
65
+ The request-reply pattern is formally defined by http://rfc.zeromq.org/spec:28.
65
66
 
66
67
  ZMQ_REQ
67
68
  ^^^^^^^
@@ -168,6 +169,7 @@ Publish-subscribe pattern
168
169
  The publish-subscribe pattern is used for one-to-many distribution of data from
169
170
  a single _publisher_ to multiple _subscribers_ in a fan out fashion.
170
171
 
172
+ The publish-subscribe pattern is formally defined by http://rfc.zeromq.org/spec:29.
171
173
 
172
174
  ZMQ_PUB
173
175
  ^^^^^^^
@@ -249,6 +251,7 @@ a pipeline. Data always flows down the pipeline, and each stage of the pipeline
249
251
  is connected to at least one _node_. When a pipeline stage is connected to
250
252
  multiple _nodes_ data is round-robined among all connected _nodes_.
251
253
 
254
+ The pipeline pattern is formally defined by http://rfc.zeromq.org/spec:30.
252
255
 
253
256
  ZMQ_PUSH
254
257
  ^^^^^^^^
@@ -296,6 +299,7 @@ The exclusive pair pattern is used to connect a peer to precisely one other
296
299
  peer. This pattern is used for inter-thread communication across the inproc
297
300
  transport.
298
301
 
302
+ The exclusive pair pattern is formally defined by http://rfc.zeromq.org/spec:31.
299
303
 
300
304
  ZMQ_PAIR
301
305
  ^^^^^^^^
@@ -28,6 +28,16 @@
28
28
  #ifndef __ZMQ_H_INCLUDED__
29
29
  #define __ZMQ_H_INCLUDED__
30
30
 
31
+ /* Version macros for compile-time API version detection */
32
+ #define ZMQ_VERSION_MAJOR 4
33
+ #define ZMQ_VERSION_MINOR 0
34
+ #define ZMQ_VERSION_PATCH 3
35
+
36
+ #define ZMQ_MAKE_VERSION(major, minor, patch) \
37
+ ((major) * 10000 + (minor) * 100 + (patch))
38
+ #define ZMQ_VERSION \
39
+ ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
40
+
31
41
  #ifdef __cplusplus
32
42
  extern "C" {
33
43
  #endif
@@ -78,23 +88,6 @@ typedef unsigned __int8 uint8_t;
78
88
  #endif
79
89
 
80
90
 
81
- /******************************************************************************/
82
- /* 0MQ versioning support. */
83
- /******************************************************************************/
84
-
85
- /* Version macros for compile-time API version detection */
86
- #define ZMQ_VERSION_MAJOR 4
87
- #define ZMQ_VERSION_MINOR 0
88
- #define ZMQ_VERSION_PATCH 1
89
-
90
- #define ZMQ_MAKE_VERSION(major, minor, patch) \
91
- ((major) * 10000 + (minor) * 100 + (patch))
92
- #define ZMQ_VERSION \
93
- ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
94
-
95
- /* Run-time API version detection */
96
- ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
97
-
98
91
  /******************************************************************************/
99
92
  /* 0MQ errors. */
100
93
  /******************************************************************************/
@@ -165,6 +158,9 @@ ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
165
158
  #define ETERM (ZMQ_HAUSNUMERO + 53)
166
159
  #define EMTHREAD (ZMQ_HAUSNUMERO + 54)
167
160
 
161
+ /* Run-time API version detection */
162
+ ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
163
+
168
164
  /* This function retrieves the errno as it is known to 0MQ library. The goal */
169
165
  /* of this function is to make the code 100% portable, including where 0MQ */
170
166
  /* compiled with certain CRT library (on Windows) is linked to an */
@@ -185,7 +181,7 @@ ZMQ_EXPORT const char *zmq_strerror (int errnum);
185
181
 
186
182
  /* Default for new contexts */
187
183
  #define ZMQ_IO_THREADS_DFLT 1
188
- #define ZMQ_MAX_SOCKETS_DFLT 1024
184
+ #define ZMQ_MAX_SOCKETS_DFLT 1023
189
185
 
190
186
  ZMQ_EXPORT void *zmq_ctx_new (void);
191
187
  ZMQ_EXPORT int zmq_ctx_term (void *context);
@@ -22,6 +22,7 @@
22
22
  #include "likely.hpp"
23
23
  #include "config.hpp"
24
24
  #include "err.hpp"
25
+ #include "mutex.hpp"
25
26
 
26
27
  #include <stddef.h>
27
28
 
@@ -41,9 +42,49 @@
41
42
  #include <time.h>
42
43
  #endif
43
44
 
45
+ #ifdef ZMQ_HAVE_WINDOWS
46
+ typedef ULONGLONG (*f_compatible_get_tick_count64)();
47
+
48
+ static zmq::mutex_t compatible_get_tick_count64_mutex;
49
+
50
+ ULONGLONG compatible_get_tick_count64()
51
+ {
52
+ compatible_get_tick_count64_mutex.lock();
53
+ static DWORD s_wrap = 0;
54
+ static DWORD s_last_tick = 0;
55
+ const DWORD current_tick = ::GetTickCount();
56
+ if (current_tick < s_last_tick)
57
+ ++s_wrap;
58
+
59
+ s_last_tick = current_tick;
60
+ const ULONGLONG result = (static_cast<ULONGLONG>(s_wrap) << 32) + static_cast<ULONGLONG>(current_tick);
61
+ compatible_get_tick_count64_mutex.unlock();
62
+ return result;
63
+ }
64
+
65
+ f_compatible_get_tick_count64 init_compatible_get_tick_count64()
66
+ {
67
+ f_compatible_get_tick_count64 func = NULL;
68
+ HMODULE module = ::LoadLibraryA("Kernel32.dll");
69
+ if (module != NULL)
70
+ func = reinterpret_cast<f_compatible_get_tick_count64>(::GetProcAddress(module, "GetTickCount64"));
71
+
72
+ if (func == NULL)
73
+ func = compatible_get_tick_count64;
74
+
75
+ return func;
76
+ }
77
+
78
+ static f_compatible_get_tick_count64 my_get_tick_count64 = init_compatible_get_tick_count64();
79
+ #endif
80
+
44
81
  zmq::clock_t::clock_t () :
45
82
  last_tsc (rdtsc ()),
83
+ #ifdef ZMQ_HAVE_WINDOWS
84
+ last_time (static_cast<uint64_t>((*my_get_tick_count64)()))
85
+ #else
46
86
  last_time (now_us () / 1000)
87
+ #endif
47
88
  {
48
89
  }
49
90
 
@@ -65,7 +106,7 @@ uint64_t zmq::clock_t::now_us ()
65
106
 
66
107
  // Convert the tick number into the number of seconds
67
108
  // since the system was started.
68
- double ticks_div = ticksPerSecond.QuadPart / 1000000.0;
109
+ double ticks_div = ticksPerSecond.QuadPart / 1000000.0;
69
110
  return (uint64_t) (tick.QuadPart / ticks_div);
70
111
 
71
112
  #elif defined HAVE_CLOCK_GETTIME && defined CLOCK_MONOTONIC
@@ -74,7 +115,7 @@ uint64_t zmq::clock_t::now_us ()
74
115
  struct timespec tv;
75
116
  int rc = clock_gettime (CLOCK_MONOTONIC, &tv);
76
117
  // Fix case where system has clock_gettime but CLOCK_MONOTONIC is not supported.
77
- // This should be a configuration check, but I looked into it and writing an
118
+ // This should be a configuration check, but I looked into it and writing an
78
119
  // AC_FUNC_CLOCK_MONOTONIC seems beyond my powers.
79
120
  if( rc != 0) {
80
121
  // Use POSIX gettimeofday function to get precise time.
@@ -106,7 +147,17 @@ uint64_t zmq::clock_t::now_ms ()
106
147
 
107
148
  // If TSC is not supported, get precise time and chop off the microseconds.
108
149
  if (!tsc)
150
+ {
151
+ #ifdef ZMQ_HAVE_WINDOWS
152
+ // Under Windows, now_us is not so reliable since QueryPerformanceCounter
153
+ // does not guarantee that it will use a hardware that offers a monotonic timer.
154
+ // So, lets use GetTickCount when GetTickCount64 is not available with an workaround
155
+ // to its 32 bit limitation.
156
+ return static_cast<uint64_t>((*my_get_tick_count64)());
157
+ #else
109
158
  return now_us () / 1000;
159
+ #endif
160
+ }
110
161
 
111
162
  // If TSC haven't jumped back (in case of migration to a different
112
163
  // CPU core) and if not too much time elapsed since last measurement,
@@ -115,7 +166,11 @@ uint64_t zmq::clock_t::now_ms ()
115
166
  return last_time;
116
167
 
117
168
  last_tsc = tsc;
169
+ #ifdef ZMQ_HAVE_WINDOWS
170
+ last_time = static_cast<uint64_t>((*my_get_tick_count64)());
171
+ #else
118
172
  last_time = now_us () / 1000;
173
+ #endif
119
174
  return last_time;
120
175
  }
121
176
 
@@ -38,6 +38,14 @@
38
38
  #define ZMQ_CTX_TAG_VALUE_GOOD 0xabadcafe
39
39
  #define ZMQ_CTX_TAG_VALUE_BAD 0xdeadbeef
40
40
 
41
+ int clipped_maxsocket(int max_requested)
42
+ {
43
+ if (max_requested >= zmq::poller_t::max_fds () && zmq::poller_t::max_fds () != -1)
44
+ max_requested = zmq::poller_t::max_fds () - 1; // -1 because we need room for the repear mailbox.
45
+
46
+ return max_requested;
47
+ }
48
+
41
49
  zmq::ctx_t::ctx_t () :
42
50
  tag (ZMQ_CTX_TAG_VALUE_GOOD),
43
51
  starting (true),
@@ -45,7 +53,7 @@ zmq::ctx_t::ctx_t () :
45
53
  reaper (NULL),
46
54
  slot_count (0),
47
55
  slots (NULL),
48
- max_sockets (ZMQ_MAX_SOCKETS_DFLT),
56
+ max_sockets (clipped_maxsocket (ZMQ_MAX_SOCKETS_DFLT)),
49
57
  io_thread_count (ZMQ_IO_THREADS_DFLT),
50
58
  ipv6 (false)
51
59
  {
@@ -107,7 +115,6 @@ int zmq::ctx_t::terminate ()
107
115
  // restarted.
108
116
  bool restarted = terminating;
109
117
  terminating = true;
110
- slot_sync.unlock ();
111
118
 
112
119
  // First attempt to terminate the context.
113
120
  if (!restarted) {
@@ -115,13 +122,12 @@ int zmq::ctx_t::terminate ()
115
122
  // First send stop command to sockets so that any blocking calls
116
123
  // can be interrupted. If there are no sockets we can ask reaper
117
124
  // thread to stop.
118
- slot_sync.lock ();
119
125
  for (sockets_t::size_type i = 0; i != sockets.size (); i++)
120
126
  sockets [i]->stop ();
121
127
  if (sockets.empty ())
122
128
  reaper->stop ();
123
- slot_sync.unlock ();
124
129
  }
130
+ slot_sync.unlock();
125
131
 
126
132
  // Wait till reaper thread closes all the sockets.
127
133
  command_t cmd;
@@ -163,7 +169,7 @@ int zmq::ctx_t::shutdown ()
163
169
  int zmq::ctx_t::set (int option_, int optval_)
164
170
  {
165
171
  int rc = 0;
166
- if (option_ == ZMQ_MAX_SOCKETS && optval_ >= 1) {
172
+ if (option_ == ZMQ_MAX_SOCKETS && optval_ >= 1 && optval_ == clipped_maxsocket (optval_)) {
167
173
  opt_sync.lock ();
168
174
  max_sockets = optval_;
169
175
  opt_sync.unlock ();
@@ -133,6 +133,11 @@ void zmq::devpoll_t::stop ()
133
133
  stopping = true;
134
134
  }
135
135
 
136
+ int zmq::devpoll_t::max_fds ()
137
+ {
138
+ return -1;
139
+ }
140
+
136
141
  void zmq::devpoll_t::loop ()
137
142
  {
138
143
  while (!stopping) {