Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: ports/python_modules/pyzmq/nacl.patch

Issue 138913004: Build system for statically-linked Python. (Closed) Base URL: https://naclports.googlecode.com/svn/trunk/src
Patch Set: Final update with merge against current naclports.py Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ports/python_modules/pyzmq/modules.list ('k') | ports/python_modules/pyzmq/pkg_info » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 diff --git a/buildutils/config.py b/buildutils/config.py
2 index 66f61e3..de2cd6e 100644
3 --- a/buildutils/config.py
4 +++ b/buildutils/config.py
5 @@ -87,6 +87,11 @@ def get_cfg_args():
6 cfg = cfg2dict(cfg)
7
8 g = cfg.setdefault('global', {})
9 + if "NACL_BUILD_TREE" in os.environ:
10 + NACL_TREE = os.environ["NACL_BUILD_TREE"]
11 + cfg["global"]["zmq_prefix"] = NACL_TREE
12 + cfg["global"]["have_sys_un_h"] = "False"
13 +
14 # boolean keys:
15 for key in ['libzmq_extension',
16 'bundle_libzmq_dylib',
17 diff --git a/setup.cfg b/setup.cfg
18 new file mode 100644
19 index 0000000..15686fc
20 --- /dev/null
21 +++ b/setup.cfg
22 @@ -0,0 +1,3 @@
23 +[bdist_egg]
24 +plat-name = pnacl
25 +
26 diff --git a/setup.py b/setup.py
27 index 5348c61..a204e23 100755
28 --- a/setup.py
29 +++ b/setup.py
30 @@ -270,6 +270,10 @@ class Configure(build_ext):
31 # include internal directories
32 settings.setdefault('include_dirs', [])
33 settings['include_dirs'] += [pjoin('zmq', sub) for sub in ('utils','cor e','devices')]
34 + if "NACL_BUILD_TREE" in os.environ:
35 + settings['include_dirs'].append(pjoin(
36 + os.environ["NACL_BUILD_TREE"],
37 + "include", "glibc-compat"))
38
39 for ext in self.distribution.ext_modules:
40 if ext.name == 'zmq.libzmq':
41 @@ -826,29 +830,29 @@ def dotc(subdir, name):
42
43 libzmq = pxd('core', 'libzmq')
44 buffers = pxd('utils', 'buffers')
45 -message = pxd('core', 'message')
46 -context = pxd('core', 'context')
47 -socket = pxd('core', 'socket')
48 +message = pxd('core', '_zmessage')
49 +context = pxd('core', '_zcontext')
50 +socket = pxd('core', '_zsocket')
51 checkrc = pxd('core', 'checkrc')
52 -monqueue = pxd('devices', 'monitoredqueue')
53 +monqueue = pxd('devices', '_zmonitoredqueue')
54
55 submodules = dict(
56 - core = {'constants': [libzmq],
57 - 'error':[libzmq, checkrc],
58 - '_poll':[libzmq, socket, context, checkrc],
59 - 'stopwatch':[libzmq, pxd('core','stopwatch'), checkrc],
60 - 'context':[context, libzmq, checkrc],
61 - 'message':[libzmq, buffers, message, checkrc],
62 - 'socket':[context, message, socket, libzmq, buffers, checkrc],
63 - '_device':[libzmq, socket, context, checkrc],
64 - '_version':[libzmq],
65 + core = {'_zconstants': [libzmq],
66 + '_zerror':[libzmq, checkrc],
67 + '__zpoll':[libzmq, socket, context, checkrc],
68 + '_zstopwatch':[libzmq, pxd('core','_zstopwatch'), checkrc],
69 + '_zcontext':[context, libzmq, checkrc],
70 + '_zmessage':[libzmq, buffers, message, checkrc],
71 + '_zsocket':[context, message, socket, libzmq, buffers, checkrc],
72 + '__zdevice':[libzmq, socket, context, checkrc],
73 + '__zversion':[libzmq],
74 },
75 devices = {
76 - 'monitoredqueue':[buffers, libzmq, monqueue, socket, context, check rc],
77 + '_zmonitoredqueue':[buffers, libzmq, monqueue, socket, context, che ckrc],
78 },
79 utils = {
80 - 'initthreads':[libzmq],
81 - 'rebuffer':[buffers],
82 + '_zinitthreads':[libzmq],
83 + '_zrebuffer':[buffers],
84 },
85 )
86
87 #-----------------------------------------------------------------------------
88 # Main setup
89 #-----------------------------------------------------------------------------
90 diff --git a/zmq/__init__.py b/zmq/__init__.py
91 index 19cb4a9..c55ac5c 100644
92 --- a/zmq/__init__.py
93 +++ b/zmq/__init__.py
94 @@ -39,7 +39,7 @@ if bundled:
95
96 if 'PyPy' not in sys.version:
97 try:
98 - from zmq.utils import initthreads # initialize threads
99 + from zmq.utils import _zinitthreads as initthreads # initialize threads
100 except ImportError as e:
101 raise ImportError("%s\nAre you trying to `import zmq` from the pyzmq so urce dir?" % e)
102 else:
103 diff --git a/zmq/core/__init__.py b/zmq/core/__init__.py
104 index 862f1d5..275e47a 100644
105 --- a/zmq/core/__init__.py
106 +++ b/zmq/core/__init__.py
107 @@ -23,21 +23,21 @@
108 # Imports
109 #-----------------------------------------------------------------------------
110
111 -from zmq.core import (constants, error, message, context,
112 - socket, stopwatch, _poll, _version, _device )
113 +from zmq.core import (_zconstants, _zerror, _zmessage, _zcontext,
114 + _zsocket, _zstopwatch, __zpoll, __zversion, __zdevice )
115
116 __all__ = []
117 -for submod in (constants, error, message, context,
118 - socket, stopwatch, _poll, _version, _device):
119 +for submod in (_zconstants, _zerror, _zmessage, _zcontext,
120 + _zsocket, _zstopwatch, __zpoll, __zversion, __zdevice):
121 __all__.extend(submod.__all__)
122
123 -from zmq.core.constants import *
124 -from zmq.core.error import *
125 -from zmq.core.message import *
126 -from zmq.core.context import *
127 -from zmq.core.socket import *
128 -from zmq.core._poll import *
129 -from zmq.core.stopwatch import *
130 -from zmq.core._device import *
131 -from zmq.core._version import *
132 +from zmq.core._zconstants import *
133 +from zmq.core._zerror import *
134 +from zmq.core._zmessage import *
135 +from zmq.core._zcontext import *
136 +from zmq.core._zsocket import *
137 +from zmq.core.__zpoll import *
138 +from zmq.core._zstopwatch import *
139 +from zmq.core.__zdevice import *
140 +from zmq.core.__zversion import *
141
142 diff --git a/zmq/core/__zdevice.pyx b/zmq/core/__zdevice.pyx
143 new file mode 100644
144 index 0000000..99bcc27
145 --- /dev/null
146 +++ b/zmq/core/__zdevice.pyx
147 @@ -0,0 +1,86 @@
148 +"""Python binding for 0MQ device function."""
149 +
150 +#
151 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
152 +#
153 +# This file is part of pyzmq.
154 +#
155 +# pyzmq is free software; you can redistribute it and/or modify it under
156 +# the terms of the Lesser GNU General Public License as published by
157 +# the Free Software Foundation; either version 3 of the License, or
158 +# (at your option) any later version.
159 +#
160 +# pyzmq is distributed in the hope that it will be useful,
161 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
162 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
163 +# Lesser GNU General Public License for more details.
164 +#
165 +# You should have received a copy of the Lesser GNU General Public License
166 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
167 +#
168 +
169 +#-----------------------------------------------------------------------------
170 +# Imports
171 +#-----------------------------------------------------------------------------
172 +
173 +from libzmq cimport zmq_device, zmq_proxy, ZMQ_VERSION_MAJOR
174 +from zmq.core._zsocket cimport Socket as cSocket
175 +from zmq.core.checkrc cimport _check_rc
176 +
177 +#-----------------------------------------------------------------------------
178 +# Basic device API
179 +#-----------------------------------------------------------------------------
180 +
181 +def device(int device_type, cSocket frontend, cSocket backend=None):
182 + """device(device_type, frontend, backend)
183 +
184 + Start a zeromq device.
185 +
186 + WARNING: zmq.device is deprecated as of libzmq-3.2,
187 + in favor of zmq.proxy.
188 +
189 + Parameters
190 + ----------
191 + device_type : (QUEUE, FORWARDER, STREAMER)
192 + The type of device to start.
193 + frontend : Socket
194 + The Socket instance for the incoming traffic.
195 + backend : Socket
196 + The Socket instance for the outbound traffic.
197 + """
198 + if ZMQ_VERSION_MAJOR >= 3:
199 + return proxy(frontend, backend)
200 +
201 + cdef int rc = 0
202 + with nogil:
203 + rc = zmq_device(device_type, frontend.handle, backend.handle)
204 + _check_rc(rc)
205 + return rc
206 +
207 +def proxy(cSocket frontend, cSocket backend, cSocket capture=None):
208 + """proxy(frontend, backend, capture)
209 +
210 + Start a zeromq proxy (replacement for device).
211 +
212 + Parameters
213 + ----------
214 + frontend : Socket
215 + The Socket instance for the incoming traffic.
216 + backend : Socket
217 + The Socket instance for the outbound traffic.
218 + capture : Socket
219 + The Socket instance for capturing traffic.
220 + """
221 + cdef int rc = 0
222 + cdef void* capture_handle
223 + if isinstance(capture, cSocket):
224 + capture_handle = capture.handle
225 + else:
226 + capture_handle = NULL
227 + with nogil:
228 + rc = zmq_proxy(frontend.handle, backend.handle, capture_handle)
229 + _check_rc(rc)
230 + return rc
231 +
232 +__all__ = ['device', 'proxy']
233 +
234 diff --git a/zmq/core/__zpoll.pyx b/zmq/core/__zpoll.pyx
235 new file mode 100644
236 index 0000000..799b20b
237 --- /dev/null
238 +++ b/zmq/core/__zpoll.pyx
239 @@ -0,0 +1,136 @@
240 +"""0MQ polling related functions and classes."""
241 +
242 +#
243 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
244 +#
245 +# This file is part of pyzmq.
246 +#
247 +# pyzmq is free software; you can redistribute it and/or modify it under
248 +# the terms of the Lesser GNU General Public License as published by
249 +# the Free Software Foundation; either version 3 of the License, or
250 +# (at your option) any later version.
251 +#
252 +# pyzmq is distributed in the hope that it will be useful,
253 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
254 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
255 +# Lesser GNU General Public License for more details.
256 +#
257 +# You should have received a copy of the Lesser GNU General Public License
258 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
259 +#
260 +
261 +#-----------------------------------------------------------------------------
262 +# Imports
263 +#-----------------------------------------------------------------------------
264 +
265 +from libc.stdlib cimport free, malloc
266 +
267 +from libzmq cimport zmq_pollitem_t, ZMQ_VERSION_MAJOR
268 +from libzmq cimport zmq_poll as zmq_poll_c
269 +from _zsocket cimport Socket
270 +
271 +import sys
272 +
273 +from zmq.core.checkrc cimport _check_rc
274 +
275 +#-----------------------------------------------------------------------------
276 +# Polling related methods
277 +#-----------------------------------------------------------------------------
278 +
279 +# version-independent typecheck for int/long
280 +if sys.version_info[0] >= 3:
281 + int_t = int
282 +else:
283 + int_t = (int,long)
284 +
285 +def zmq_poll(sockets, long timeout=-1):
286 + """zmq_poll(sockets, timeout=-1)
287 +
288 + Poll a set of 0MQ sockets, native file descs. or sockets.
289 +
290 + Parameters
291 + ----------
292 + sockets : list of tuples of (socket, flags)
293 + Each element of this list is a two-tuple containing a socket
294 + and a flags. The socket may be a 0MQ socket or any object with
295 + a ``fileno()`` method. The flags can be zmq.POLLIN (for detecting
296 + for incoming messages), zmq.POLLOUT (for detecting that send is OK)
297 + or zmq.POLLIN|zmq.POLLOUT for detecting both.
298 + timeout : int
299 + The number of milliseconds to poll for. Negative means no timeout.
300 + """
301 + cdef int rc, i
302 + cdef zmq_pollitem_t *pollitems = NULL
303 + cdef int nsockets = <int>len(sockets)
304 + cdef Socket current_socket
305 +
306 + if nsockets == 0:
307 + return []
308 +
309 + pollitems = <zmq_pollitem_t *>malloc(nsockets*sizeof(zmq_pollitem_t))
310 + if pollitems == NULL:
311 + raise MemoryError("Could not allocate poll items")
312 +
313 + if ZMQ_VERSION_MAJOR < 3:
314 + # timeout is us in 2.x, ms in 3.x
315 + # expected input is ms (matches 3.x)
316 + timeout = 1000*timeout
317 +
318 + for i in range(nsockets):
319 + s = sockets[i][0]
320 + events = sockets[i][1]
321 + if isinstance(s, Socket):
322 + current_socket = s
323 + pollitems[i].socket = current_socket.handle
324 + pollitems[i].events = events
325 + pollitems[i].revents = 0
326 + elif isinstance(s, int_t):
327 + pollitems[i].socket = NULL
328 + pollitems[i].fd = s
329 + pollitems[i].events = events
330 + pollitems[i].revents = 0
331 + elif hasattr(s, 'fileno'):
332 + try:
333 + fileno = int(s.fileno())
334 + except:
335 + free(pollitems)
336 + raise ValueError('fileno() must return an valid integer fd')
337 + else:
338 + pollitems[i].socket = NULL
339 + pollitems[i].fd = fileno
340 + pollitems[i].events = events
341 + pollitems[i].revents = 0
342 + else:
343 + free(pollitems)
344 + raise TypeError(
345 + "Socket must be a 0MQ socket, an integer fd or have "
346 + "a fileno() method: %r" % s
347 + )
348 +
349 +
350 + with nogil:
351 + rc = zmq_poll_c(pollitems, nsockets, timeout)
352 +
353 + if rc < 0:
354 + free(pollitems)
355 + _check_rc(rc)
356 +
357 + results = []
358 + for i in range(nsockets):
359 + s = sockets[i][0]
360 + # Return the fd for sockets, for compat. with select.poll.
361 + if hasattr(s, 'fileno'):
362 + s = s.fileno()
363 + revents = pollitems[i].revents
364 + # Only return sockets with non-zero status for compat. with select.poll .
365 + if revents > 0:
366 + results.append((s, revents))
367 +
368 + free(pollitems)
369 + return results
370 +
371 +#-----------------------------------------------------------------------------
372 +# Symbols to export
373 +#-----------------------------------------------------------------------------
374 +
375 +__all__ = [ 'zmq_poll' ]
376 diff --git a/zmq/core/__zversion.pyx b/zmq/core/__zversion.pyx
377 new file mode 100644
378 index 0000000..02cf6fc
379 --- /dev/null
380 +++ b/zmq/core/__zversion.pyx
381 @@ -0,0 +1,43 @@
382 +"""PyZMQ and 0MQ version functions."""
383 +
384 +#
385 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
386 +#
387 +# This file is part of pyzmq.
388 +#
389 +# pyzmq is free software; you can redistribute it and/or modify it under
390 +# the terms of the Lesser GNU General Public License as published by
391 +# the Free Software Foundation; either version 3 of the License, or
392 +# (at your option) any later version.
393 +#
394 +# pyzmq is distributed in the hope that it will be useful,
395 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
396 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
397 +# Lesser GNU General Public License for more details.
398 +#
399 +# You should have received a copy of the Lesser GNU General Public License
400 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
401 +#
402 +
403 +#-----------------------------------------------------------------------------
404 +# Imports
405 +#-----------------------------------------------------------------------------
406 +
407 +from libzmq cimport _zmq_version
408 +
409 +#-----------------------------------------------------------------------------
410 +# Code
411 +#-----------------------------------------------------------------------------
412 +
413 +def zmq_version_info():
414 + """zmq_version_info()
415 +
416 + Return the version of ZeroMQ itself as a 3-tuple of ints.
417 + """
418 + cdef int major, minor, patch
419 + _zmq_version(&major, &minor, &patch)
420 + return (major, minor, patch)
421 +
422 +
423 +__all__ = ['zmq_version_info']
424 +
425 diff --git a/zmq/core/_device.pyx b/zmq/core/_device.pyx
426 deleted file mode 100644
427 index 5471e73..0000000
428 --- a/zmq/core/_device.pyx
429 +++ /dev/null
430 @@ -1,86 +0,0 @@
431 -"""Python binding for 0MQ device function."""
432 -
433 -#
434 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
435 -#
436 -# This file is part of pyzmq.
437 -#
438 -# pyzmq is free software; you can redistribute it and/or modify it under
439 -# the terms of the Lesser GNU General Public License as published by
440 -# the Free Software Foundation; either version 3 of the License, or
441 -# (at your option) any later version.
442 -#
443 -# pyzmq is distributed in the hope that it will be useful,
444 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
445 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
446 -# Lesser GNU General Public License for more details.
447 -#
448 -# You should have received a copy of the Lesser GNU General Public License
449 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
450 -#
451 -
452 -#-----------------------------------------------------------------------------
453 -# Imports
454 -#-----------------------------------------------------------------------------
455 -
456 -from libzmq cimport zmq_device, zmq_proxy, ZMQ_VERSION_MAJOR
457 -from zmq.core.socket cimport Socket as cSocket
458 -from zmq.core.checkrc cimport _check_rc
459 -
460 -#-----------------------------------------------------------------------------
461 -# Basic device API
462 -#-----------------------------------------------------------------------------
463 -
464 -def device(int device_type, cSocket frontend, cSocket backend=None):
465 - """device(device_type, frontend, backend)
466 -
467 - Start a zeromq device.
468 -
469 - WARNING: zmq.device is deprecated as of libzmq-3.2,
470 - in favor of zmq.proxy.
471 -
472 - Parameters
473 - ----------
474 - device_type : (QUEUE, FORWARDER, STREAMER)
475 - The type of device to start.
476 - frontend : Socket
477 - The Socket instance for the incoming traffic.
478 - backend : Socket
479 - The Socket instance for the outbound traffic.
480 - """
481 - if ZMQ_VERSION_MAJOR >= 3:
482 - return proxy(frontend, backend)
483 -
484 - cdef int rc = 0
485 - with nogil:
486 - rc = zmq_device(device_type, frontend.handle, backend.handle)
487 - _check_rc(rc)
488 - return rc
489 -
490 -def proxy(cSocket frontend, cSocket backend, cSocket capture=None):
491 - """proxy(frontend, backend, capture)
492 -
493 - Start a zeromq proxy (replacement for device).
494 -
495 - Parameters
496 - ----------
497 - frontend : Socket
498 - The Socket instance for the incoming traffic.
499 - backend : Socket
500 - The Socket instance for the outbound traffic.
501 - capture : Socket
502 - The Socket instance for capturing traffic.
503 - """
504 - cdef int rc = 0
505 - cdef void* capture_handle
506 - if isinstance(capture, cSocket):
507 - capture_handle = capture.handle
508 - else:
509 - capture_handle = NULL
510 - with nogil:
511 - rc = zmq_proxy(frontend.handle, backend.handle, capture_handle)
512 - _check_rc(rc)
513 - return rc
514 -
515 -__all__ = ['device', 'proxy']
516 -
517 diff --git a/zmq/core/_poll.pyx b/zmq/core/_poll.pyx
518 deleted file mode 100644
519 index 9db19e1..0000000
520 --- a/zmq/core/_poll.pyx
521 +++ /dev/null
522 @@ -1,136 +0,0 @@
523 -"""0MQ polling related functions and classes."""
524 -
525 -#
526 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
527 -#
528 -# This file is part of pyzmq.
529 -#
530 -# pyzmq is free software; you can redistribute it and/or modify it under
531 -# the terms of the Lesser GNU General Public License as published by
532 -# the Free Software Foundation; either version 3 of the License, or
533 -# (at your option) any later version.
534 -#
535 -# pyzmq is distributed in the hope that it will be useful,
536 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
537 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
538 -# Lesser GNU General Public License for more details.
539 -#
540 -# You should have received a copy of the Lesser GNU General Public License
541 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
542 -#
543 -
544 -#-----------------------------------------------------------------------------
545 -# Imports
546 -#-----------------------------------------------------------------------------
547 -
548 -from libc.stdlib cimport free, malloc
549 -
550 -from libzmq cimport zmq_pollitem_t, ZMQ_VERSION_MAJOR
551 -from libzmq cimport zmq_poll as zmq_poll_c
552 -from socket cimport Socket
553 -
554 -import sys
555 -
556 -from zmq.core.checkrc cimport _check_rc
557 -
558 -#-----------------------------------------------------------------------------
559 -# Polling related methods
560 -#-----------------------------------------------------------------------------
561 -
562 -# version-independent typecheck for int/long
563 -if sys.version_info[0] >= 3:
564 - int_t = int
565 -else:
566 - int_t = (int,long)
567 -
568 -def zmq_poll(sockets, long timeout=-1):
569 - """zmq_poll(sockets, timeout=-1)
570 -
571 - Poll a set of 0MQ sockets, native file descs. or sockets.
572 -
573 - Parameters
574 - ----------
575 - sockets : list of tuples of (socket, flags)
576 - Each element of this list is a two-tuple containing a socket
577 - and a flags. The socket may be a 0MQ socket or any object with
578 - a ``fileno()`` method. The flags can be zmq.POLLIN (for detecting
579 - for incoming messages), zmq.POLLOUT (for detecting that send is OK)
580 - or zmq.POLLIN|zmq.POLLOUT for detecting both.
581 - timeout : int
582 - The number of milliseconds to poll for. Negative means no timeout.
583 - """
584 - cdef int rc, i
585 - cdef zmq_pollitem_t *pollitems = NULL
586 - cdef int nsockets = <int>len(sockets)
587 - cdef Socket current_socket
588 -
589 - if nsockets == 0:
590 - return []
591 -
592 - pollitems = <zmq_pollitem_t *>malloc(nsockets*sizeof(zmq_pollitem_t))
593 - if pollitems == NULL:
594 - raise MemoryError("Could not allocate poll items")
595 -
596 - if ZMQ_VERSION_MAJOR < 3:
597 - # timeout is us in 2.x, ms in 3.x
598 - # expected input is ms (matches 3.x)
599 - timeout = 1000*timeout
600 -
601 - for i in range(nsockets):
602 - s = sockets[i][0]
603 - events = sockets[i][1]
604 - if isinstance(s, Socket):
605 - current_socket = s
606 - pollitems[i].socket = current_socket.handle
607 - pollitems[i].events = events
608 - pollitems[i].revents = 0
609 - elif isinstance(s, int_t):
610 - pollitems[i].socket = NULL
611 - pollitems[i].fd = s
612 - pollitems[i].events = events
613 - pollitems[i].revents = 0
614 - elif hasattr(s, 'fileno'):
615 - try:
616 - fileno = int(s.fileno())
617 - except:
618 - free(pollitems)
619 - raise ValueError('fileno() must return an valid integer fd')
620 - else:
621 - pollitems[i].socket = NULL
622 - pollitems[i].fd = fileno
623 - pollitems[i].events = events
624 - pollitems[i].revents = 0
625 - else:
626 - free(pollitems)
627 - raise TypeError(
628 - "Socket must be a 0MQ socket, an integer fd or have "
629 - "a fileno() method: %r" % s
630 - )
631 -
632 -
633 - with nogil:
634 - rc = zmq_poll_c(pollitems, nsockets, timeout)
635 -
636 - if rc < 0:
637 - free(pollitems)
638 - _check_rc(rc)
639 -
640 - results = []
641 - for i in range(nsockets):
642 - s = sockets[i][0]
643 - # Return the fd for sockets, for compat. with select.poll.
644 - if hasattr(s, 'fileno'):
645 - s = s.fileno()
646 - revents = pollitems[i].revents
647 - # Only return sockets with non-zero status for compat. with select.poll .
648 - if revents > 0:
649 - results.append((s, revents))
650 -
651 - free(pollitems)
652 - return results
653 -
654 -#-----------------------------------------------------------------------------
655 -# Symbols to export
656 -#-----------------------------------------------------------------------------
657 -
658 -__all__ = [ 'zmq_poll' ]
659 diff --git a/zmq/core/_version.pyx b/zmq/core/_version.pyx
660 deleted file mode 100644
661 index 02cf6fc..0000000
662 --- a/zmq/core/_version.pyx
663 +++ /dev/null
664 @@ -1,43 +0,0 @@
665 -"""PyZMQ and 0MQ version functions."""
666 -
667 -#
668 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
669 -#
670 -# This file is part of pyzmq.
671 -#
672 -# pyzmq is free software; you can redistribute it and/or modify it under
673 -# the terms of the Lesser GNU General Public License as published by
674 -# the Free Software Foundation; either version 3 of the License, or
675 -# (at your option) any later version.
676 -#
677 -# pyzmq is distributed in the hope that it will be useful,
678 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
679 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
680 -# Lesser GNU General Public License for more details.
681 -#
682 -# You should have received a copy of the Lesser GNU General Public License
683 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
684 -#
685 -
686 -#-----------------------------------------------------------------------------
687 -# Imports
688 -#-----------------------------------------------------------------------------
689 -
690 -from libzmq cimport _zmq_version
691 -
692 -#-----------------------------------------------------------------------------
693 -# Code
694 -#-----------------------------------------------------------------------------
695 -
696 -def zmq_version_info():
697 - """zmq_version_info()
698 -
699 - Return the version of ZeroMQ itself as a 3-tuple of ints.
700 - """
701 - cdef int major, minor, patch
702 - _zmq_version(&major, &minor, &patch)
703 - return (major, minor, patch)
704 -
705 -
706 -__all__ = ['zmq_version_info']
707 -
708 diff --git a/zmq/core/_zconstants.pyx b/zmq/core/_zconstants.pyx
709 new file mode 100644
710 index 0000000..fa2695d
711 --- /dev/null
712 +++ b/zmq/core/_zconstants.pyx
713 @@ -0,0 +1,190 @@
714 +"""0MQ Constants."""
715 +
716 +#
717 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
718 +#
719 +# This file is part of pyzmq.
720 +#
721 +# pyzmq is free software; you can redistribute it and/or modify it under
722 +# the terms of the Lesser GNU General Public License as published by
723 +# the Free Software Foundation; either version 3 of the License, or
724 +# (at your option) any later version.
725 +#
726 +# pyzmq is distributed in the hope that it will be useful,
727 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
728 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
729 +# Lesser GNU General Public License for more details.
730 +#
731 +# You should have received a copy of the Lesser GNU General Public License
732 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
733 +#
734 +
735 +#-----------------------------------------------------------------------------
736 +# Imports
737 +#-----------------------------------------------------------------------------
738 +
739 +from libzmq cimport *
740 +
741 +#-----------------------------------------------------------------------------
742 +# Python module level constants
743 +#-----------------------------------------------------------------------------
744 +
745 +_optionals = []
746 +
747 +if ZMQ_VERSION < 30000:
748 + # backport DONTWAIT as alias to NOBLOCK
749 + NOBLOCK = ZMQ_NOBLOCK
750 + DONTWAIT = ZMQ_NOBLOCK
751 +else:
752 + # keep NOBLOCK as alias for new DONTWAIT
753 + NOBLOCK = ZMQ_DONTWAIT
754 + DONTWAIT = ZMQ_DONTWAIT
755 +
756 +VERSION = ZMQ_VERSION
757 +
758 +# socket types
759 +PAIR = ZMQ_PAIR
760 +PUB = ZMQ_PUB
761 +SUB = ZMQ_SUB
762 +REQ = ZMQ_REQ
763 +REP = ZMQ_REP
764 +DEALER = ZMQ_DEALER
765 +ROUTER = ZMQ_ROUTER
766 +PULL = ZMQ_PULL
767 +PUSH = ZMQ_PUSH
768 +XPUB = ZMQ_XPUB
769 +XSUB = ZMQ_XSUB
770 +
771 +# keep deprecated aliases
772 +XREQ = DEALER
773 +XREP = ROUTER
774 +UPSTREAM = PULL
775 +DOWNSTREAM = PUSH
776 +
777 +
778 +# socket options
779 +AFFINITY = ZMQ_AFFINITY
780 +IDENTITY = ZMQ_IDENTITY
781 +SUBSCRIBE = ZMQ_SUBSCRIBE
782 +UNSUBSCRIBE = ZMQ_UNSUBSCRIBE
783 +RATE = ZMQ_RATE
784 +RECOVERY_IVL = ZMQ_RECOVERY_IVL
785 +RECONNECT_IVL_MAX = ZMQ_RECONNECT_IVL_MAX
786 +SNDBUF = ZMQ_SNDBUF
787 +RCVBUF = ZMQ_RCVBUF
788 +RCVMORE = ZMQ_RCVMORE
789 +SNDMORE = ZMQ_SNDMORE
790 +POLLIN = ZMQ_POLLIN
791 +POLLOUT = ZMQ_POLLOUT
792 +POLLERR = ZMQ_POLLERR
793 +
794 +STREAMER = ZMQ_STREAMER
795 +FORWARDER = ZMQ_FORWARDER
796 +QUEUE = ZMQ_QUEUE
797 +
798 +# sockopts new in 2.2.0
799 +SNDTIMEO = ZMQ_SNDTIMEO
800 +RCVTIMEO = ZMQ_RCVTIMEO
801 +
802 +# sockopts removed in 3.0.0
803 +HWM = ZMQ_HWM
804 +SWAP = ZMQ_SWAP
805 +MCAST_LOOP = ZMQ_MCAST_LOOP
806 +RECOVERY_IVL_MSEC = ZMQ_RECOVERY_IVL_MSEC
807 +
808 +# new in 3.x
809 +IO_THREADS = ZMQ_IO_THREADS
810 +MAX_SOCKETS = ZMQ_MAX_SOCKETS
811 +
812 +MORE = ZMQ_MORE
813 +
814 +MAXMSGSIZE = ZMQ_MAXMSGSIZE
815 +SNDHWM = ZMQ_SNDHWM
816 +RCVHWM = ZMQ_RCVHWM
817 +MULTICAST_HOPS = ZMQ_MULTICAST_HOPS
818 +IPV4ONLY = ZMQ_IPV4ONLY
819 +LAST_ENDPOINT = ZMQ_LAST_ENDPOINT
820 +
821 +ROUTER_MANDATORY = ZMQ_ROUTER_MANDATORY
822 +# aliases
823 +ROUTER_BEHAVIOR = ROUTER_MANDATORY
824 +FAIL_UNROUTABLE = ROUTER_MANDATORY
825 +
826 +TCP_KEEPALIVE = ZMQ_TCP_KEEPALIVE
827 +TCP_KEEPALIVE_CNT = ZMQ_TCP_KEEPALIVE_CNT
828 +TCP_KEEPALIVE_IDLE = ZMQ_TCP_KEEPALIVE_IDLE
829 +TCP_KEEPALIVE_INTVL = ZMQ_TCP_KEEPALIVE_INTVL
830 +TCP_ACCEPT_FILTER = ZMQ_TCP_ACCEPT_FILTER
831 +DELAY_ATTACH_ON_CONNECT = ZMQ_DELAY_ATTACH_ON_CONNECT
832 +XPUB_VERBOSE = ZMQ_XPUB_VERBOSE
833 +ROUTER_RAW = ZMQ_ROUTER_RAW
834 +
835 +EVENT_CONNECTED = ZMQ_EVENT_CONNECTED
836 +EVENT_CONNECT_DELAYED = ZMQ_EVENT_CONNECT_DELAYED
837 +EVENT_CONNECT_RETRIED = ZMQ_EVENT_CONNECT_RETRIED
838 +EVENT_LISTENING = ZMQ_EVENT_LISTENING
839 +EVENT_BIND_FAILED = ZMQ_EVENT_BIND_FAILED
840 +EVENT_ACCEPTED = ZMQ_EVENT_ACCEPTED
841 +EVENT_ACCEPT_FAILED = ZMQ_EVENT_ACCEPT_FAILED
842 +EVENT_CLOSED = ZMQ_EVENT_CLOSED
843 +EVENT_CLOSE_FAILED = ZMQ_EVENT_CLOSE_FAILED
844 +EVENT_DISCONNECTED = ZMQ_EVENT_DISCONNECTED
845 +
846 +FD = ZMQ_FD
847 +EVENTS = ZMQ_EVENTS
848 +TYPE = ZMQ_TYPE
849 +LINGER = ZMQ_LINGER
850 +RECONNECT_IVL = ZMQ_RECONNECT_IVL
851 +BACKLOG = ZMQ_BACKLOG
852 +
853 +# As new constants are added in future versions, add a new block here
854 +# like the two above, checking agains the relevant value for ZMQ_VERSION.
855 +# The constants will need to be added to libzmq.pxd and utils/zmq_compat.h
856 +# as well.
857 +
858 +#-----------------------------------------------------------------------------
859 +# Error handling
860 +#-----------------------------------------------------------------------------
861 +
862 +# Often used standard errnos
863 +from errno import (
864 + EAGAIN,
865 + EINVAL,
866 + EFAULT,
867 + ENOMEM,
868 + ENODEV
869 +)
870 +
871 +# For Windows compatability
872 +ENOTSUP = ZMQ_ENOTSUP
873 +EPROTONOSUPPORT = ZMQ_EPROTONOSUPPORT
874 +ENOBUFS = ZMQ_ENOBUFS
875 +ENETDOWN = ZMQ_ENETDOWN
876 +EADDRINUSE = ZMQ_EADDRINUSE
877 +EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL
878 +ECONNREFUSED = ZMQ_ECONNREFUSED
879 +EINPROGRESS = ZMQ_EINPROGRESS
880 +ENOTSOCK = ZMQ_ENOTSOCK
881 +
882 +# new errnos in zmq3
883 +EMSGSIZE = ZMQ_EMSGSIZE
884 +EAFNOSUPPORT = ZMQ_EAFNOSUPPORT
885 +ENETUNREACH = ZMQ_ENETUNREACH
886 +ECONNABORTED = ZMQ_ECONNABORTED
887 +ECONNRESET = ZMQ_ECONNRESET
888 +ENOTCONN = ZMQ_ENOTCONN
889 +ETIMEDOUT = ZMQ_ETIMEDOUT
890 +EHOSTUNREACH = ZMQ_EHOSTUNREACH
891 +ENETRESET = ZMQ_ENETRESET
892 +
893 +# 0MQ Native
894 +EFSM = ZMQ_EFSM
895 +ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO
896 +ETERM = ZMQ_ETERM
897 +EMTHREAD = ZMQ_EMTHREAD
898 +
899 +#-----------------------------------------------------------------------------
900 +# Symbols to export
901 +#-----------------------------------------------------------------------------
902 +_names = list(locals().keys())
903 +__all__ = [ key for key in _names if not key.startswith('_') ]
904 diff --git a/zmq/core/_zcontext.pxd b/zmq/core/_zcontext.pxd
905 new file mode 100644
906 index 0000000..e399de5
907 --- /dev/null
908 +++ b/zmq/core/_zcontext.pxd
909 @@ -0,0 +1,40 @@
910 +"""0MQ Context class declaration."""
911 +
912 +#
913 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
914 +#
915 +# This file is part of pyzmq.
916 +#
917 +# pyzmq is free software; you can redistribute it and/or modify it under
918 +# the terms of the Lesser GNU General Public License as published by
919 +# the Free Software Foundation; either version 3 of the License, or
920 +# (at your option) any later version.
921 +#
922 +# pyzmq is distributed in the hope that it will be useful,
923 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
924 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
925 +# Lesser GNU General Public License for more details.
926 +#
927 +# You should have received a copy of the Lesser GNU General Public License
928 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
929 +#
930 +
931 +#-----------------------------------------------------------------------------
932 +# Code
933 +#-----------------------------------------------------------------------------
934 +
935 +cdef class Context:
936 + """Manage the lifecycle of a 0MQ context."""
937 +
938 + cdef object __weakref__ # enable weakref
939 + cdef void *handle # The C handle for the underlying zmq object.
940 + cdef void **_sockets # A C-array containg socket handles
941 + cdef size_t _n_sockets # the number of sockets
942 + cdef size_t _max_sockets # the size of the _sockets array
943 + cdef int _pid # the pid of the process which created me (for fork safety)
944 +
945 + cdef public object closed # bool property for a closed context.
946 + # helpers for events on _sockets in Socket.__cinit__()/close()
947 + cdef inline void _add_socket(self, void* handle)
948 + cdef inline void _remove_socket(self, void* handle)
949 +
950 diff --git a/zmq/core/_zcontext.pyx b/zmq/core/_zcontext.pyx
951 new file mode 100644
952 index 0000000..0917c66
953 --- /dev/null
954 +++ b/zmq/core/_zcontext.pyx
955 @@ -0,0 +1,254 @@
956 +"""0MQ Context class."""
957 +
958 +#
959 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
960 +#
961 +# This file is part of pyzmq.
962 +#
963 +# pyzmq is free software; you can redistribute it and/or modify it under
964 +# the terms of the Lesser GNU General Public License as published by
965 +# the Free Software Foundation; either version 3 of the License, or
966 +# (at your option) any later version.
967 +#
968 +# pyzmq is distributed in the hope that it will be useful,
969 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
970 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
971 +# Lesser GNU General Public License for more details.
972 +#
973 +# You should have received a copy of the Lesser GNU General Public License
974 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
975 +#
976 +
977 +#-----------------------------------------------------------------------------
978 +# Imports
979 +#-----------------------------------------------------------------------------
980 +
981 +from libc.stdlib cimport free, malloc, realloc
982 +
983 +from libzmq cimport *
984 +
985 +cdef extern from "getpid_compat.h":
986 + int getpid()
987 +
988 +from zmq.error import ZMQError
989 +from zmq.core.checkrc cimport _check_rc
990 +
991 +#-----------------------------------------------------------------------------
992 +# Code
993 +#-----------------------------------------------------------------------------
994 +
995 +_instance = None
996 +
997 +cdef class Context:
998 + """Context(io_threads=1)
999 +
1000 + Manage the lifecycle of a 0MQ context.
1001 +
1002 + Parameters
1003 + ----------
1004 + io_threads : int
1005 + The number of IO threads.
1006 + """
1007 +
1008 + def __cinit__(self, int io_threads = 1, **kwargs):
1009 + self.handle = NULL
1010 + self._sockets = NULL
1011 +
1012 + if ZMQ_VERSION_MAJOR >= 3:
1013 + self.handle = zmq_ctx_new()
1014 + else:
1015 + self.handle = zmq_init(io_threads)
1016 +
1017 + if self.handle == NULL:
1018 + raise ZMQError()
1019 +
1020 + cdef int rc = 0
1021 + if ZMQ_VERSION_MAJOR >= 3:
1022 + rc = zmq_ctx_set(self.handle, ZMQ_IO_THREADS, io_threads)
1023 + _check_rc(rc)
1024 +
1025 + self.closed = False
1026 + self._n_sockets = 0
1027 + self._max_sockets = 32
1028 +
1029 + self._sockets = <void **>malloc(self._max_sockets*sizeof(void *))
1030 + if self._sockets == NULL:
1031 + raise MemoryError("Could not allocate _sockets array")
1032 +
1033 + self._pid = getpid()
1034 +
1035 + def __init__(self, io_threads=1):
1036 + # no-op
1037 + pass
1038 +
1039 +
1040 + def __del__(self):
1041 + """deleting a Context should terminate it, without trying non-threadsaf e destroy"""
1042 + self.term()
1043 +
1044 + def __dealloc__(self):
1045 + """don't touch members in dealloc, just cleanup allocations"""
1046 + cdef int rc
1047 + if self._sockets != NULL:
1048 + free(self._sockets)
1049 + self._sockets = NULL
1050 + self._n_sockets = 0
1051 + self.term()
1052 +
1053 + cdef inline void _add_socket(self, void* handle):
1054 + """Add a socket handle to be closed when Context terminates.
1055 +
1056 + This is to be called in the Socket constructor.
1057 + """
1058 + # print self._n_sockets, self._max_sockets
1059 + if self._n_sockets >= self._max_sockets:
1060 + self._max_sockets *= 2
1061 + self._sockets = <void **>realloc(self._sockets, self._max_sockets*s izeof(void *))
1062 + if self._sockets == NULL:
1063 + raise MemoryError("Could not reallocate _sockets array")
1064 +
1065 + self._sockets[self._n_sockets] = handle
1066 + self._n_sockets += 1
1067 + # print self._n_sockets, self._max_sockets
1068 +
1069 + cdef inline void _remove_socket(self, void* handle):
1070 + """Remove a socket from the collected handles.
1071 +
1072 + This should be called by Socket.close, to prevent trying to
1073 + close a socket a second time.
1074 + """
1075 + cdef bint found = False
1076 +
1077 + for idx in range(self._n_sockets):
1078 + if self._sockets[idx] == handle:
1079 + found=True
1080 + break
1081 +
1082 + if found:
1083 + self._n_sockets -= 1
1084 + if self._n_sockets:
1085 + # move last handle to closed socket's index
1086 + self._sockets[idx] = self._sockets[self._n_sockets]
1087 +
1088 + @property
1089 + def _handle(self):
1090 + return <Py_ssize_t> self.handle
1091 +
1092 + def term(self):
1093 + """ctx.term()
1094 +
1095 + Close or terminate the context.
1096 +
1097 + This can be called to close the context by hand. If this is not called,
1098 + the context will automatically be closed when it is garbage collected.
1099 + """
1100 + cdef int rc
1101 + cdef int i=-1
1102 +
1103 + if self.handle != NULL and not self.closed and getpid() == self._pid:
1104 + with nogil:
1105 + rc = zmq_ctx_destroy(self.handle)
1106 + _check_rc(rc)
1107 + self.handle = NULL
1108 + self.closed = True
1109 +
1110 + def set(self, int option, optval):
1111 + """ctx.set(option, optval)
1112 +
1113 + Set context options.
1114 +
1115 + See the 0MQ API documentation for zmq_ctx_set
1116 + for details on specific options.
1117 +
1118 + New in libzmq-3.2
1119 +
1120 + Parameters
1121 + ----------
1122 + option : int
1123 + The option to set. Available values will depend on your
1124 + version of libzmq. Examples include::
1125 +
1126 + zmq.IO_THREADS, zmq.MAX_SOCKETS
1127 +
1128 + optval : int
1129 + The value of the option to set.
1130 + """
1131 + cdef int optval_int_c
1132 + cdef int rc
1133 + cdef char* optval_c
1134 +
1135 + if self.closed:
1136 + raise RuntimeError("Context has been destroyed")
1137 +
1138 + if not isinstance(optval, int):
1139 + raise TypeError('expected int, got: %r' % optval)
1140 + optval_int_c = optval
1141 + rc = zmq_ctx_set(self.handle, option, optval_int_c)
1142 + _check_rc(rc)
1143 +
1144 + def get(self, int option):
1145 + """ctx.get(option)
1146 +
1147 + Get the value of a context option.
1148 +
1149 + See the 0MQ API documentation for zmq_ctx_get
1150 + for details on specific options.
1151 +
1152 + New in libzmq-3.2
1153 +
1154 + Parameters
1155 + ----------
1156 + option : int
1157 + The option to get. Available values will depend on your
1158 + version of libzmq. Examples include::
1159 +
1160 + zmq.IO_THREADS, zmq.MAX_SOCKETS
1161 +
1162 + Returns
1163 + -------
1164 + optval : int
1165 + The value of the option as an integer.
1166 + """
1167 + cdef int optval_int_c
1168 + cdef size_t sz
1169 + cdef int rc
1170 +
1171 + if self.closed:
1172 + raise RuntimeError("Context has been destroyed")
1173 +
1174 + rc = zmq_ctx_get(self.handle, option)
1175 + _check_rc(rc)
1176 +
1177 + return rc
1178 +
1179 + def destroy(self, linger=None):
1180 + """ctx.destroy(linger=None)
1181 +
1182 + Close all sockets associated with this context, and then terminate
1183 + the context. If linger is specified,
1184 + the LINGER sockopt of the sockets will be set prior to closing.
1185 +
1186 + WARNING:
1187 +
1188 + destroy involves calling zmq_close(), which is *NOT* threadsafe.
1189 + If there are active sockets in other threads, this must not be called.
1190 + """
1191 +
1192 + cdef int linger_c
1193 + cdef bint setlinger=False
1194 +
1195 + if linger is not None:
1196 + linger_c = linger
1197 + setlinger=True
1198 + if self.handle != NULL and not self.closed and self._n_sockets:
1199 + while self._n_sockets:
1200 + if setlinger:
1201 + zmq_setsockopt(self._sockets[0], ZMQ_LINGER, &linger_c, siz eof(int))
1202 + rc = zmq_close(self._sockets[0])
1203 + if rc < 0 and zmq_errno() != ZMQ_ENOTSOCK:
1204 + raise ZMQError()
1205 + self._n_sockets -= 1
1206 + self._sockets[0] = self._sockets[self._n_sockets]
1207 + self.term()
1208 +
1209 +__all__ = ['Context']
1210 diff --git a/zmq/core/_zerror.pyx b/zmq/core/_zerror.pyx
1211 new file mode 100644
1212 index 0000000..85e785f
1213 --- /dev/null
1214 +++ b/zmq/core/_zerror.pyx
1215 @@ -0,0 +1,56 @@
1216 +"""0MQ Error classes and functions."""
1217 +
1218 +#
1219 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
1220 +#
1221 +# This file is part of pyzmq.
1222 +#
1223 +# pyzmq is free software; you can redistribute it and/or modify it under
1224 +# the terms of the Lesser GNU General Public License as published by
1225 +# the Free Software Foundation; either version 3 of the License, or
1226 +# (at your option) any later version.
1227 +#
1228 +# pyzmq is distributed in the hope that it will be useful,
1229 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1230 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1231 +# Lesser GNU General Public License for more details.
1232 +#
1233 +# You should have received a copy of the Lesser GNU General Public License
1234 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
1235 +#
1236 +
1237 +#-----------------------------------------------------------------------------
1238 +# Imports
1239 +#-----------------------------------------------------------------------------
1240 +
1241 +# allow const char*
1242 +cdef extern from *:
1243 + ctypedef char* const_char_ptr "const char*"
1244 +
1245 +from libzmq cimport zmq_strerror, zmq_errno as zmq_errno_c
1246 +
1247 +from zmq.utils.strtypes import bytes
1248 +
1249 +def strerror(int errno):
1250 + """strerror(errno)
1251 +
1252 + Return the error string given the error number.
1253 + """
1254 + cdef const_char_ptr str_e
1255 + # char * will be a bytes object:
1256 + str_e = zmq_strerror(errno)
1257 + if str is bytes:
1258 + # Python 2: str is bytes, so we already have the right type
1259 + return str_e
1260 + else:
1261 + # Python 3: decode bytes to unicode str
1262 + return str_e.decode()
1263 +
1264 +def zmq_errno():
1265 + """zmq_errno()
1266 +
1267 + Return the integer errno of the most recent zmq error.
1268 + """
1269 + return zmq_errno_c()
1270 +
1271 +__all__ = ['strerror', 'zmq_errno']
1272 diff --git a/zmq/core/_zmessage.pxd b/zmq/core/_zmessage.pxd
1273 new file mode 100644
1274 index 0000000..a86a8e0
1275 --- /dev/null
1276 +++ b/zmq/core/_zmessage.pxd
1277 @@ -0,0 +1,66 @@
1278 +"""0MQ Message related class declarations."""
1279 +
1280 +#
1281 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
1282 +#
1283 +# This file is part of pyzmq.
1284 +#
1285 +# pyzmq is free software; you can redistribute it and/or modify it under
1286 +# the terms of the Lesser GNU General Public License as published by
1287 +# the Free Software Foundation; either version 3 of the License, or
1288 +# (at your option) any later version.
1289 +#
1290 +# pyzmq is distributed in the hope that it will be useful,
1291 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1292 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1293 +# Lesser GNU General Public License for more details.
1294 +#
1295 +# You should have received a copy of the Lesser GNU General Public License
1296 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
1297 +#
1298 +
1299 +#-----------------------------------------------------------------------------
1300 +# Imports
1301 +#-----------------------------------------------------------------------------
1302 +
1303 +from cpython cimport PyBytes_FromStringAndSize
1304 +
1305 +from libzmq cimport zmq_msg_t, zmq_msg_data, zmq_msg_size
1306 +
1307 +#-----------------------------------------------------------------------------
1308 +# Code
1309 +#-----------------------------------------------------------------------------
1310 +
1311 +cdef class MessageTracker(object):
1312 + """A class for tracking if 0MQ is done using one or more messages."""
1313 +
1314 + cdef set events # Message Event objects to track.
1315 + cdef set peers # Other Message or MessageTracker objects.
1316 +
1317 +
1318 +cdef class Frame:
1319 + """A Message Frame class for non-copy send/recvs."""
1320 +
1321 + cdef zmq_msg_t zmq_msg
1322 + cdef object _data # The actual message data as a Python object.
1323 + cdef object _buffer # A Python Buffer/View of the message contents
1324 + cdef object _bytes # A bytes/str copy of the message.
1325 + cdef bint _failed_init # Flag to handle failed zmq_msg_init
1326 + cdef public object tracker_event # Event for use with zmq_free_fn.
1327 + cdef public object tracker # MessageTracker object.
1328 + cdef public bint more # whether RCVMORE was set
1329 +
1330 + cdef Frame fast_copy(self) # Create shallow copy of Message object.
1331 + cdef object _getbuffer(self) # Construct self._buffer.
1332 +
1333 +
1334 +cdef inline object copy_zmq_msg_bytes(zmq_msg_t *zmq_msg):
1335 + """ Copy the data from a zmq_msg_t """
1336 + cdef char *data_c = NULL
1337 + cdef Py_ssize_t data_len_c
1338 + with nogil:
1339 + data_c = <char *>zmq_msg_data(zmq_msg)
1340 + data_len_c = zmq_msg_size(zmq_msg)
1341 + return PyBytes_FromStringAndSize(data_c, data_len_c)
1342 +
1343 +
1344 diff --git a/zmq/core/_zmessage.pyx b/zmq/core/_zmessage.pyx
1345 new file mode 100644
1346 index 0000000..1d358ab
1347 --- /dev/null
1348 +++ b/zmq/core/_zmessage.pyx
1349 @@ -0,0 +1,297 @@
1350 +"""0MQ Message related classes."""
1351 +
1352 +#
1353 +# Copyright (c) 2013 Brian E. Granger & Min Ragan-Kelley
1354 +#
1355 +# This file is part of pyzmq.
1356 +#
1357 +# pyzmq is free software; you can redistribute it and/or modify it under
1358 +# the terms of the Lesser GNU General Public License as published by
1359 +# the Free Software Foundation; either version 3 of the License, or
1360 +# (at your option) any later version.
1361 +#
1362 +# pyzmq is distributed in the hope that it will be useful,
1363 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1364 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1365 +# Lesser GNU General Public License for more details.
1366 +#
1367 +# You should have received a copy of the Lesser GNU General Public License
1368 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
1369 +#
1370 +
1371 +#-----------------------------------------------------------------------------
1372 +# Imports
1373 +#-----------------------------------------------------------------------------
1374 +
1375 +# get version-independent aliases:
1376 +cdef extern from "pyversion_compat.h":
1377 + pass
1378 +
1379 +from cpython cimport Py_DECREF, Py_INCREF
1380 +
1381 +from buffers cimport asbuffer_r, viewfromobject_r
1382 +
1383 +cdef extern from "Python.h":
1384 + ctypedef int Py_ssize_t
1385 +
1386 +from libzmq cimport *
1387 +
1388 +import time
1389 +
1390 +try:
1391 + # below 3.3
1392 + from threading import _Event as Event
1393 +except (ImportError, AttributeError):
1394 + # python throws ImportError, cython throws AttributeError
1395 + from threading import Event
1396 +
1397 +import zmq
1398 +from zmq.core.checkrc cimport _check_rc
1399 +from zmq.utils.strtypes import bytes,unicode,basestring
1400 +
1401 +#-----------------------------------------------------------------------------
1402 +# Code
1403 +#-----------------------------------------------------------------------------
1404 +
1405 +
1406 +cdef void free_python_msg(void *data, void *hint) with gil:
1407 + """A function for DECREF'ing Python based messages."""
1408 + if hint != NULL:
1409 + tracker_event = (<tuple>hint)[1]
1410 + Py_DECREF(<object>hint)
1411 + if isinstance(tracker_event, Event):
1412 + # don't assert before DECREF:
1413 + # assert tracker_queue.empty(), "somebody else wrote to my Queue!"
1414 + tracker_event.set()
1415 + tracker_event = None
1416 +
1417 +
1418 +cdef class Frame:
1419 + """Frame(data=None, track=False)
1420 +
1421 + A zmq message Frame class for non-copy send/recvs.
1422 +
1423 + This class is only needed if you want to do non-copying send and recvs.
1424 + When you pass a string to this class, like ``Frame(s)``, the
1425 + ref-count of `s` is increased by two: once because the Frame saves `s` as
1426 + an instance attribute and another because a ZMQ message is created that
1427 + points to the buffer of `s`. This second ref-count increase makes sure
1428 + that `s` lives until all messages that use it have been sent. Once 0MQ
1429 + sends all the messages and it doesn't need the buffer of s, 0MQ will call
1430 + ``Py_DECREF(s)``.
1431 +
1432 + Parameters
1433 + ----------
1434 +
1435 + data : object, optional
1436 + any object that provides the buffer interface will be used to
1437 + construct the 0MQ message data.
1438 + track : bool [default: False]
1439 + whether a MessageTracker_ should be created to track this object.
1440 + Tracking a message has a cost at creation, because it creates a threads afe
1441 + Event object.
1442 +
1443 + """
1444 +
1445 + def __cinit__(self, object data=None, track=False, **kwargs):
1446 + cdef int rc
1447 + cdef char *data_c = NULL
1448 + cdef Py_ssize_t data_len_c=0
1449 + cdef object hint
1450 +
1451 + # init more as False
1452 + self.more = False
1453 +
1454 + # Save the data object in case the user wants the the data as a str.
1455 + self._data = data
1456 + self._failed_init = True # bool switch for dealloc
1457 + self._buffer = None # buffer view of data
1458 + self._bytes = None # bytes copy of data
1459 +
1460 + # Event and MessageTracker for monitoring when zmq is done with data:
1461 + if track:
1462 + evt = Event()
1463 + self.tracker_event = evt
1464 + self.tracker = zmq.MessageTracker(evt)
1465 + else:
1466 + self.tracker_event = None
1467 + self.tracker = None
1468 +
1469 + if isinstance(data, unicode):
1470 + raise TypeError("Unicode objects not allowed. Only: str/bytes, buff er interfaces.")
1471 +
1472 + if data is None:
1473 + with nogil:
1474 + rc = zmq_msg_init(&self.zmq_msg)
1475 + _check_rc(rc)
1476 + self._failed_init = False
1477 + return
1478 + else:
1479 + asbuffer_r(data, <void **>&data_c, &data_len_c)
1480 + # We INCREF the *original* Python object (not self) and pass it
1481 + # as the hint below. This allows other copies of this Frame
1482 + # object to take over the ref counting of data properly.
1483 + hint = (data, self.tracker_event)
1484 + Py_INCREF(hint)
1485 + with nogil:
1486 + rc = zmq_msg_init_data(
1487 + &self.zmq_msg, <void *>data_c, data_len_c,
1488 + <zmq_free_fn *>free_python_msg, <void *>hint
1489 + )
1490 + if rc != 0:
1491 + Py_DECREF(hint)
1492 + _check_rc(rc)
1493 + self._failed_init = False
1494 +
1495 + def __init__(self, object data=None, track=False):
1496 + """Enforce signature"""
1497 + pass
1498 +
1499 + def __dealloc__(self):
1500 + cdef int rc
1501 + if self._failed_init:
1502 + return
1503 + # This simply decreases the 0MQ ref-count of zmq_msg.
1504 + with nogil:
1505 + rc = zmq_msg_close(&self.zmq_msg)
1506 + _check_rc(rc)
1507 +
1508 + # buffer interface code adapted from petsc4py by Lisandro Dalcin, a BSD pro ject
1509 +
1510 + def __getbuffer__(self, Py_buffer* buffer, int flags):
1511 + # new-style (memoryview) buffer interface
1512 + with nogil:
1513 + buffer.buf = zmq_msg_data(&self.zmq_msg)
1514 + buffer.len = zmq_msg_size(&self.zmq_msg)
1515 +
1516 + buffer.obj = self
1517 + buffer.readonly = 1
1518 + buffer.format = "B"
1519 + buffer.ndim = 0
1520 + buffer.shape = NULL
1521 + buffer.strides = NULL
1522 + buffer.suboffsets = NULL
1523 + buffer.itemsize = 1
1524 + buffer.internal = NULL
1525 +
1526 + def __getsegcount__(self, Py_ssize_t *lenp):
1527 + # required for getreadbuffer
1528 + if lenp != NULL:
1529 + with nogil:
1530 + lenp[0] = zmq_msg_size(&self.zmq_msg)
1531 + return 1
1532 +
1533 + def __getreadbuffer__(self, Py_ssize_t idx, void **p):
1534 + # old-style (buffer) interface
1535 + cdef char *data_c = NULL
1536 + cdef Py_ssize_t data_len_c
1537 + if idx != 0:
1538 + raise SystemError("accessing non-existent buffer segment")
1539 + # read-only, because we don't want to allow
1540 + # editing of the message in-place
1541 + with nogil:
1542 + data_c = <char *>zmq_msg_data(&self.zmq_msg)
1543 + data_len_c = zmq_msg_size(&self.zmq_msg)
1544 + if p != NULL:
1545 + p[0] = <void*>data_c
1546 + return data_len_c
1547 +
1548 + # end buffer interface
1549 +
1550 + def __copy__(self):
1551 + """Create a shallow copy of the message.
1552 +
1553 + This does not copy the contents of the Frame, just the pointer.
1554 + This will increment the 0MQ ref count of the message, but not
1555 + the ref count of the Python object. That is only done once when
1556 + the Python is first turned into a 0MQ message.
1557 + """
1558 + return self.fast_copy()
1559 +
1560 + cdef Frame fast_copy(self):
1561 + """Fast, cdef'd version of shallow copy of the Frame."""
1562 + cdef Frame new_msg
1563 + new_msg = Frame()
1564 + # This does not copy the contents, but just increases the ref-count
1565 + # of the zmq_msg by one.
1566 + with nogil:
1567 + zmq_msg_copy(&new_msg.zmq_msg, &self.zmq_msg)
1568 + # Copy the ref to data so the copy won't create a copy when str is
1569 + # called.
1570 + if self._data is not None:
1571 + new_msg._data = self._data
1572 + if self._buffer is not None:
1573 + new_msg._buffer = self._buffer
1574 + if self._bytes is not None:
1575 + new_msg._bytes = self._bytes
1576 +
1577 + # Frame copies share the tracker and tracker_event
1578 + new_msg.tracker_event = self.tracker_event
1579 + new_msg.tracker = self.tracker
1580 +
1581 + return new_msg
1582 +
1583 + def __len__(self):
1584 + """Return the length of the message in bytes."""
1585 + cdef size_t sz
1586 + with nogil:
1587 + sz = zmq_msg_size(&self.zmq_msg)
1588 + return sz
1589 + # return <int>zmq_msg_size(&self.zmq_msg)
1590 +
1591 + def __str__(self):
1592 + """Return the str form of the message."""
1593 + if isinstance(self._data, bytes):
1594 + b = self._data
1595 + else:
1596 + b = self.bytes
1597 + if str is unicode:
1598 + return b.decode()
1599 + else:
1600 + return b
1601 +
1602 + cdef inline object _getbuffer(self):
1603 + """Create a Python buffer/view of the message data.
1604 +
1605 + This will be called only once, the first time the `buffer` property
1606 + is accessed. Subsequent calls use a cached copy.
1607 + """
1608 + if self._data is None:
1609 + return viewfromobject_r(self)
1610 + else:
1611 + return viewfromobject_r(self._data)
1612 +
1613 + @property
1614 + def buffer(self):
1615 + """Get a read-only buffer view of the message contents."""
1616 + if self._buffer is None:
1617 + self._buffer = self._getbuffer()
1618 + return self._buffer
1619 +
1620 + @property
1621 + def bytes(self):
1622 + """Get the message content as a Python str/bytes object.
1623 +
1624 + The first time this property is accessed, a copy of the message
1625 + contents is made. From then on that same copy of the message is
1626 + returned.
1627 + """
1628 + if self._bytes is None:
1629 + self._bytes = copy_zmq_msg_bytes(&self.zmq_msg)
1630 + return self._bytes
1631 +
1632 + def set(self, int option, int value):
1633 + """Set a message property"""
1634 + cdef int rc = zmq_msg_set(&self.zmq_msg, option, value)
1635 + _check_rc(rc)
1636 +
1637 + def get(self, int option):
1638 + """Get a message property"""
1639 + cdef int rc = zmq_msg_get(&self.zmq_msg, option)
1640 + _check_rc(rc)
1641 + return rc
1642 +
1643 +# legacy Message name
1644 +Message = Frame
1645 +
1646 +__all__ = ['Frame', 'Message']
1647 diff --git a/zmq/core/_zsocket.pxd b/zmq/core/_zsocket.pxd
1648 new file mode 100644
1649 index 0000000..68f96c8
1650 --- /dev/null
1651 +++ b/zmq/core/_zsocket.pxd
1652 @@ -0,0 +1,48 @@
1653 +"""0MQ Socket class declaration."""
1654 +
1655 +#
1656 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
1657 +#
1658 +# This file is part of pyzmq.
1659 +#
1660 +# pyzmq is free software; you can redistribute it and/or modify it under
1661 +# the terms of the Lesser GNU General Public License as published by
1662 +# the Free Software Foundation; either version 3 of the License, or
1663 +# (at your option) any later version.
1664 +#
1665 +# pyzmq is distributed in the hope that it will be useful,
1666 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1667 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1668 +# Lesser GNU General Public License for more details.
1669 +#
1670 +# You should have received a copy of the Lesser GNU General Public License
1671 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
1672 +#
1673 +
1674 +#-----------------------------------------------------------------------------
1675 +# Imports
1676 +#-----------------------------------------------------------------------------
1677 +
1678 +from _zcontext cimport Context
1679 +
1680 +#-----------------------------------------------------------------------------
1681 +# Code
1682 +#-----------------------------------------------------------------------------
1683 +
1684 +
1685 +cdef class Socket:
1686 + """A 0MQ socket."""
1687 +
1688 + cdef object __weakref__ # enable weakref
1689 + cdef void *handle # The C handle for the underlying zmq object.
1690 + cdef public int socket_type # The 0MQ socket type - REQ,REP, etc.
1691 + # Hold on to a reference to the context to make sure it is not garbage
1692 + # collected until the socket it done with it.
1693 + cdef public Context context # The zmq Context object that owns this.
1694 + cdef public bint _closed # bool property for a closed socket.
1695 + cdef int _pid # the pid of the process which created me (for fork safety)
1696 +
1697 + # cpdef methods for direct-cython access:
1698 + cpdef object send(self, object data, int flags=*, copy=*, track=*)
1699 + cpdef object recv(self, int flags=*, copy=*, track=*)
1700 +
1701 diff --git a/zmq/core/_zsocket.pyx b/zmq/core/_zsocket.pyx
1702 new file mode 100644
1703 index 0000000..a5e507d
1704 --- /dev/null
1705 +++ b/zmq/core/_zsocket.pyx
1706 @@ -0,0 +1,628 @@
1707 +"""0MQ Socket class."""
1708 +
1709 +#
1710 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
1711 +#
1712 +# This file is part of pyzmq.
1713 +#
1714 +# pyzmq is free software; you can redistribute it and/or modify it under
1715 +# the terms of the Lesser GNU General Public License as published by
1716 +# the Free Software Foundation; either version 3 of the License, or
1717 +# (at your option) any later version.
1718 +#
1719 +# pyzmq is distributed in the hope that it will be useful,
1720 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1721 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1722 +# Lesser GNU General Public License for more details.
1723 +#
1724 +# You should have received a copy of the Lesser GNU General Public License
1725 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
1726 +#
1727 +
1728 +#-----------------------------------------------------------------------------
1729 +# Cython Imports
1730 +#-----------------------------------------------------------------------------
1731 +
1732 +# get version-independent aliases:
1733 +cdef extern from "pyversion_compat.h":
1734 + pass
1735 +
1736 +from libc.errno cimport ENAMETOOLONG
1737 +from libc.string cimport memcpy
1738 +
1739 +from cpython cimport PyBytes_FromStringAndSize
1740 +from cpython cimport PyBytes_AsString, PyBytes_Size
1741 +from cpython cimport Py_DECREF, Py_INCREF
1742 +
1743 +from buffers cimport asbuffer_r, viewfromobject_r
1744 +
1745 +from libzmq cimport *
1746 +from _zmessage cimport Frame, copy_zmq_msg_bytes
1747 +
1748 +from _zcontext cimport Context
1749 +
1750 +cdef extern from "Python.h":
1751 + ctypedef int Py_ssize_t
1752 +
1753 +cdef extern from "ipcmaxlen.h":
1754 + int get_ipc_path_max_len()
1755 +
1756 +cdef extern from "getpid_compat.h":
1757 + int getpid()
1758 +
1759 +
1760 +#-----------------------------------------------------------------------------
1761 +# Python Imports
1762 +#-----------------------------------------------------------------------------
1763 +
1764 +import copy as copy_mod
1765 +import time
1766 +import sys
1767 +import random
1768 +import struct
1769 +import codecs
1770 +
1771 +from zmq.utils import jsonapi
1772 +
1773 +try:
1774 + import cPickle
1775 + pickle = cPickle
1776 +except:
1777 + cPickle = None
1778 + import pickle
1779 +
1780 +import zmq
1781 +from zmq.core import _zconstants as constants
1782 +from zmq.core._zconstants import *
1783 +from zmq.core.checkrc cimport _check_rc
1784 +from zmq.error import ZMQError, ZMQBindError
1785 +from zmq.utils.strtypes import bytes,unicode,basestring
1786 +
1787 +#-----------------------------------------------------------------------------
1788 +# Code
1789 +#-----------------------------------------------------------------------------
1790 +
1791 +IPC_PATH_MAX_LEN = get_ipc_path_max_len()
1792 +
1793 +# inline some small socket submethods:
1794 +# true methods frequently cannot be inlined, acc. Cython docs
1795 +
1796 +cdef inline _check_closed(Socket s, bint raise_notsup):
1797 + cdef int rc
1798 + cdef int errno
1799 + cdef int stype
1800 + cdef size_t sz=sizeof(int)
1801 + if s._closed:
1802 + if raise_notsup:
1803 + raise ZMQError(ENOTSUP)
1804 + else:
1805 + return True
1806 + else:
1807 + rc = zmq_getsockopt(s.handle, ZMQ_TYPE, <void *>&stype, &sz)
1808 + if rc < 0 and zmq_errno() == ENOTSOCK:
1809 + s._closed = True
1810 + if raise_notsup:
1811 + raise ZMQError(ENOTSUP)
1812 + else:
1813 + return True
1814 + else:
1815 + _check_rc(rc)
1816 + return False
1817 +
1818 +cdef inline Frame _recv_frame(void *handle, int flags=0, track=False):
1819 + """Receive a message in a non-copying manner and return a Frame."""
1820 + cdef int rc
1821 + cdef Frame msg
1822 + msg = Frame(track=track)
1823 +
1824 + with nogil:
1825 + rc = zmq_msg_recv(&msg.zmq_msg, handle, flags)
1826 +
1827 + _check_rc(rc)
1828 + return msg
1829 +
1830 +cdef inline object _recv_copy(void *handle, int flags=0):
1831 + """Receive a message and return a copy"""
1832 + cdef zmq_msg_t zmq_msg
1833 + with nogil:
1834 + zmq_msg_init (&zmq_msg)
1835 + rc = zmq_msg_recv(&zmq_msg, handle, flags)
1836 + _check_rc(rc)
1837 + msg_bytes = copy_zmq_msg_bytes(&zmq_msg)
1838 + with nogil:
1839 + zmq_msg_close(&zmq_msg)
1840 + return msg_bytes
1841 +
1842 +cdef inline object _send_frame(void *handle, Frame msg, int flags=0):
1843 + """Send a Frame on this socket in a non-copy manner."""
1844 + cdef int rc
1845 + cdef Frame msg_copy
1846 +
1847 + # Always copy so the original message isn't garbage collected.
1848 + # This doesn't do a real copy, just a reference.
1849 + msg_copy = msg.fast_copy()
1850 +
1851 + with nogil:
1852 + rc = zmq_msg_send(&msg_copy.zmq_msg, handle, flags)
1853 +
1854 + _check_rc(rc)
1855 + return msg.tracker
1856 +
1857 +
1858 +cdef inline object _send_copy(void *handle, object msg, int flags=0):
1859 + """Send a message on this socket by copying its content."""
1860 + cdef int rc, rc2
1861 + cdef zmq_msg_t data
1862 + cdef char *msg_c
1863 + cdef Py_ssize_t msg_c_len=0
1864 +
1865 + # copy to c array:
1866 + asbuffer_r(msg, <void **>&msg_c, &msg_c_len)
1867 +
1868 + # Copy the msg before sending. This avoids any complications with
1869 + # the GIL, etc.
1870 + # If zmq_msg_init_* fails we must not call zmq_msg_close (Bus Error)
1871 + with nogil:
1872 + rc = zmq_msg_init_size(&data, msg_c_len)
1873 +
1874 + _check_rc(rc)
1875 +
1876 + with nogil:
1877 + memcpy(zmq_msg_data(&data), msg_c, zmq_msg_size(&data))
1878 + rc = zmq_msg_send(&data, handle, flags)
1879 + rc2 = zmq_msg_close(&data)
1880 + _check_rc(rc)
1881 + _check_rc(rc2)
1882 +
1883 +
1884 +cdef class Socket:
1885 + """Socket(context, socket_type)
1886 +
1887 + A 0MQ socket.
1888 +
1889 + These objects will generally be constructed via the socket() method of a Co ntext object.
1890 +
1891 + Note: 0MQ Sockets are *not* threadsafe. **DO NOT** share them across thread s.
1892 +
1893 + Parameters
1894 + ----------
1895 + context : Context
1896 + The 0MQ Context this Socket belongs to.
1897 + socket_type : int
1898 + The socket type, which can be any of the 0MQ socket types:
1899 + REQ, REP, PUB, SUB, PAIR, DEALER, ROUTER, PULL, PUSH, XPUB, XSUB.
1900 +
1901 + See Also
1902 + --------
1903 + .Context.socket : method for creating a socket bound to a Context.
1904 + """
1905 +
1906 + def __cinit__(self, Context context, int socket_type, *args, **kwrags):
1907 + cdef Py_ssize_t c_handle
1908 + c_handle = context._handle
1909 +
1910 + self.handle = NULL
1911 + self.context = context
1912 + self.socket_type = socket_type
1913 + with nogil:
1914 + self.handle = zmq_socket(<void *>c_handle, socket_type)
1915 + if self.handle == NULL:
1916 + raise ZMQError()
1917 + self._closed = False
1918 + self._pid = getpid()
1919 + context._add_socket(self.handle)
1920 +
1921 + def __dealloc__(self):
1922 + """close *and* remove from context's list
1923 +
1924 + But be careful that context might not exist if called during gc
1925 + """
1926 + if self.handle != NULL and getpid() == self._pid:
1927 + rc = zmq_close(self.handle)
1928 + if rc != 0 and zmq_errno() != ENOTSOCK:
1929 + # ignore ENOTSOCK (closed by Context)
1930 + _check_rc(rc)
1931 + # during gc, self.context might be NULL
1932 + if self.context:
1933 + self.context._remove_socket(self.handle)
1934 +
1935 + def __init__(self, context, socket_type):
1936 + pass
1937 +
1938 + @property
1939 + def closed(self):
1940 + return _check_closed(self, False)
1941 +
1942 + def close(self, linger=None):
1943 + """s.close(linger=None)
1944 +
1945 + Close the socket.
1946 +
1947 + If linger is specified, LINGER sockopt will be set prior to closing.
1948 +
1949 + This can be called to close the socket by hand. If this is not
1950 + called, the socket will automatically be closed when it is
1951 + garbage collected.
1952 + """
1953 + cdef int rc=0
1954 + cdef int linger_c
1955 + cdef bint setlinger=False
1956 +
1957 + if linger is not None:
1958 + linger_c = linger
1959 + setlinger=True
1960 +
1961 + if self.handle != NULL and not self._closed and getpid() == self._pid:
1962 + if setlinger:
1963 + zmq_setsockopt(self.handle, ZMQ_LINGER, &linger_c, sizeof(int))
1964 + rc = zmq_close(self.handle)
1965 + if rc != 0 and zmq_errno() != ENOTSOCK:
1966 + # ignore ENOTSOCK (closed by Context)
1967 + _check_rc(rc)
1968 + self._closed = True
1969 + # during gc, self.context might be NULL
1970 + if self.context:
1971 + self.context._remove_socket(self.handle)
1972 + self.handle = NULL
1973 +
1974 + def set(self, int option, optval):
1975 + """s.set(option, optval)
1976 +
1977 + Set socket options.
1978 +
1979 + See the 0MQ API documentation for details on specific options.
1980 +
1981 + Parameters
1982 + ----------
1983 + option : int
1984 + The option to set. Available values will depend on your
1985 + version of libzmq. Examples include::
1986 +
1987 + zmq.SUBSCRIBE, UNSUBSCRIBE, IDENTITY, HWM, LINGER, FD
1988 +
1989 + optval : int or bytes
1990 + The value of the option to set.
1991 + """
1992 + cdef int64_t optval_int64_c
1993 + cdef int optval_int_c
1994 + cdef int rc
1995 + cdef char* optval_c
1996 + cdef Py_ssize_t sz
1997 +
1998 + _check_closed(self, True)
1999 + if isinstance(optval, unicode):
2000 + raise TypeError("unicode not allowed, use setsockopt_string")
2001 +
2002 + if option in zmq.constants.bytes_sockopts:
2003 + if not isinstance(optval, bytes):
2004 + raise TypeError('expected bytes, got: %r' % optval)
2005 + optval_c = PyBytes_AsString(optval)
2006 + sz = PyBytes_Size(optval)
2007 + with nogil:
2008 + rc = zmq_setsockopt(
2009 + self.handle, option,
2010 + optval_c, sz
2011 + )
2012 + elif option in zmq.constants.int64_sockopts:
2013 + if not isinstance(optval, int):
2014 + raise TypeError('expected int, got: %r' % optval)
2015 + optval_int64_c = optval
2016 + with nogil:
2017 + rc = zmq_setsockopt(
2018 + self.handle, option,
2019 + &optval_int64_c, sizeof(int64_t)
2020 + )
2021 + else:
2022 + # default is to assume int, which is what most new sockopts will be
2023 + # this lets pyzmq work with newer libzmq which may add constants
2024 + # pyzmq has not yet added, rather than artificially raising. Invali d
2025 + # sockopts will still raise just the same, but it will be libzmq do ing
2026 + # the raising.
2027 + if not isinstance(optval, int):
2028 + raise TypeError('expected int, got: %r' % optval)
2029 + optval_int_c = optval
2030 + with nogil:
2031 + rc = zmq_setsockopt(
2032 + self.handle, option,
2033 + &optval_int_c, sizeof(int)
2034 + )
2035 +
2036 + _check_rc(rc)
2037 +
2038 + def get(self, int option):
2039 + """s.get(option)
2040 +
2041 + Get the value of a socket option.
2042 +
2043 + See the 0MQ API documentation for details on specific options.
2044 +
2045 + Parameters
2046 + ----------
2047 + option : int
2048 + The option to get. Available values will depend on your
2049 + version of libzmq. Examples include::
2050 +
2051 + zmq.IDENTITY, HWM, LINGER, FD, EVENTS
2052 +
2053 + Returns
2054 + -------
2055 + optval : int or bytes
2056 + The value of the option as a bytestring or int.
2057 + """
2058 + cdef int64_t optval_int64_c
2059 + cdef int optval_int_c
2060 + cdef fd_t optval_fd_c
2061 + cdef char identity_str_c [255]
2062 + cdef size_t sz
2063 + cdef int rc
2064 +
2065 + _check_closed(self, True)
2066 +
2067 + if option in zmq.constants.bytes_sockopts:
2068 + sz = 255
2069 + with nogil:
2070 + rc = zmq_getsockopt(self.handle, option, <void *>identity_str_c , &sz)
2071 + _check_rc(rc)
2072 + result = PyBytes_FromStringAndSize(<char *>identity_str_c, sz)
2073 + elif option in zmq.constants.int64_sockopts:
2074 + sz = sizeof(int64_t)
2075 + with nogil:
2076 + rc = zmq_getsockopt(self.handle, option, <void *>&optval_int64_ c, &sz)
2077 + _check_rc(rc)
2078 + result = optval_int64_c
2079 + elif option == ZMQ_FD:
2080 + sz = sizeof(fd_t)
2081 + with nogil:
2082 + rc = zmq_getsockopt(self.handle, option, <void *>&optval_fd_c, &sz)
2083 + _check_rc(rc)
2084 + result = optval_fd_c
2085 + else:
2086 + # default is to assume int, which is what most new sockopts will be
2087 + # this lets pyzmq work with newer libzmq which may add constants
2088 + # pyzmq has not yet added, rather than artificially raising. Invali d
2089 + # sockopts will still raise just the same, but it will be libzmq do ing
2090 + # the raising.
2091 + sz = sizeof(int)
2092 + with nogil:
2093 + rc = zmq_getsockopt(self.handle, option, <void *>&optval_int_c, &sz)
2094 + _check_rc(rc)
2095 + result = optval_int_c
2096 +
2097 + return result
2098 +
2099 + def bind(self, addr):
2100 + """s.bind(addr)
2101 +
2102 + Bind the socket to an address.
2103 +
2104 + This causes the socket to listen on a network port. Sockets on the
2105 + other side of this connection will use ``Socket.connect(addr)`` to
2106 + connect to this socket.
2107 +
2108 + Parameters
2109 + ----------
2110 + addr : str
2111 + The address string. This has the form 'protocol://interface:port',
2112 + for example 'tcp://127.0.0.1:5555'. Protocols supported include
2113 + tcp, udp, pgm, epgm, inproc and ipc. If the address is unicode, it is
2114 + encoded to utf-8 first.
2115 + """
2116 + cdef int rc
2117 + cdef char* c_addr
2118 +
2119 + _check_closed(self, True)
2120 + if isinstance(addr, unicode):
2121 + addr = addr.encode('utf-8')
2122 + if not isinstance(addr, bytes):
2123 + raise TypeError('expected str, got: %r' % addr)
2124 + c_addr = addr
2125 + rc = zmq_bind(self.handle, c_addr)
2126 + if rc != 0:
2127 + if IPC_PATH_MAX_LEN and zmq_errno() == ENAMETOOLONG:
2128 + # py3compat: addr is bytes, but msg wants str
2129 + if str is unicode:
2130 + addr = addr.decode('utf-8', 'replace')
2131 + path = addr.split('://', 1)[-1]
2132 + msg = ('ipc path "{0}" is longer than {1} '
2133 + 'characters (sizeof(sockaddr_un.sun_path)). '
2134 + 'zmq.IPC_PATH_MAX_LEN constant can be used '
2135 + 'to check addr length (if it is defined).'
2136 + .format(path, IPC_PATH_MAX_LEN))
2137 + raise ZMQError(msg=msg)
2138 + _check_rc(rc)
2139 +
2140 + def connect(self, addr):
2141 + """s.connect(addr)
2142 +
2143 + Connect to a remote 0MQ socket.
2144 +
2145 + Parameters
2146 + ----------
2147 + addr : str
2148 + The address string. This has the form 'protocol://interface:port',
2149 + for example 'tcp://127.0.0.1:5555'. Protocols supported are
2150 + tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
2151 + encoded to utf-8 first.
2152 + """
2153 + cdef int rc
2154 + cdef char* c_addr
2155 +
2156 + _check_closed(self, True)
2157 + if isinstance(addr, unicode):
2158 + addr = addr.encode('utf-8')
2159 + if not isinstance(addr, bytes):
2160 + raise TypeError('expected str, got: %r' % addr)
2161 + c_addr = addr
2162 +
2163 + rc = zmq_connect(self.handle, c_addr)
2164 + if rc != 0:
2165 + raise ZMQError()
2166 +
2167 + def unbind(self, addr):
2168 + """s.unbind(addr)
2169 +
2170 + Unbind from an address (undoes a call to bind).
2171 +
2172 + This feature requires libzmq-3
2173 +
2174 + Parameters
2175 + ----------
2176 + addr : str
2177 + The address string. This has the form 'protocol://interface:port',
2178 + for example 'tcp://127.0.0.1:5555'. Protocols supported are
2179 + tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
2180 + encoded to utf-8 first.
2181 + """
2182 + cdef int rc
2183 + cdef char* c_addr
2184 +
2185 + if ZMQ_VERSION_MAJOR < 3:
2186 + raise NotImplementedError("unbind requires libzmq >= 3.0, have %s" % zmq.zmq_version())
2187 +
2188 +
2189 + _check_closed(self, True)
2190 + if isinstance(addr, unicode):
2191 + addr = addr.encode('utf-8')
2192 + if not isinstance(addr, bytes):
2193 + raise TypeError('expected str, got: %r' % addr)
2194 + c_addr = addr
2195 +
2196 + rc = zmq_unbind(self.handle, c_addr)
2197 + if rc != 0:
2198 + raise ZMQError()
2199 +
2200 + def disconnect(self, addr):
2201 + """s.disconnect(addr)
2202 +
2203 + Disconnect from a remote 0MQ socket (undoes a call to connect).
2204 +
2205 + This feature requires libzmq-3
2206 +
2207 + Parameters
2208 + ----------
2209 + addr : str
2210 + The address string. This has the form 'protocol://interface:port',
2211 + for example 'tcp://127.0.0.1:5555'. Protocols supported are
2212 + tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
2213 + encoded to utf-8 first.
2214 + """
2215 + cdef int rc
2216 + cdef char* c_addr
2217 +
2218 + if ZMQ_VERSION_MAJOR < 3:
2219 + raise NotImplementedError("disconnect requires libzmq >= 3.0, have %s" % zmq.zmq_version())
2220 +
2221 + _check_closed(self, True)
2222 + if isinstance(addr, unicode):
2223 + addr = addr.encode('utf-8')
2224 + if not isinstance(addr, bytes):
2225 + raise TypeError('expected str, got: %r' % addr)
2226 + c_addr = addr
2227 +
2228 + rc = zmq_disconnect(self.handle, c_addr)
2229 + if rc != 0:
2230 + raise ZMQError()
2231 +
2232 + #-------------------------------------------------------------------------
2233 + # Sending and receiving messages
2234 + #-------------------------------------------------------------------------
2235 +
2236 + cpdef object send(self, object data, int flags=0, copy=True, track=False):
2237 + """s.send(data, flags=0, copy=True, track=False)
2238 +
2239 + Send a message on this socket.
2240 +
2241 + This queues the message to be sent by the IO thread at a later time.
2242 +
2243 + Parameters
2244 + ----------
2245 + data : object, str, Frame
2246 + The content of the message.
2247 + flags : int
2248 + Any supported flag: NOBLOCK, SNDMORE.
2249 + copy : bool
2250 + Should the message be sent in a copying or non-copying manner.
2251 + track : bool
2252 + Should the message be tracked for notification that ZMQ has
2253 + finished with it? (ignored if copy=True)
2254 +
2255 + Returns
2256 + -------
2257 + None : if `copy` or not track
2258 + None if message was sent, raises an exception otherwise.
2259 + MessageTracker : if track and not copy
2260 + a MessageTracker object, whose `pending` property will
2261 + be True until the send is completed.
2262 +
2263 + Raises
2264 + ------
2265 + TypeError
2266 + If a unicode object is passed
2267 + ValueError
2268 + If `track=True`, but an untracked Frame is passed.
2269 + ZMQError
2270 + If the send does not succeed for any reason.
2271 +
2272 + """
2273 + _check_closed(self, True)
2274 +
2275 + if isinstance(data, unicode):
2276 + raise TypeError("unicode not allowed, use send_unicode")
2277 +
2278 + if copy:
2279 + # msg.bytes never returns the input data object
2280 + # it is always a copy, but always the same copy
2281 + if isinstance(data, Frame):
2282 + data = data.buffer
2283 + return _send_copy(self.handle, data, flags)
2284 + else:
2285 + if isinstance(data, Frame):
2286 + if track and not data.tracker:
2287 + raise ValueError('Not a tracked message')
2288 + msg = data
2289 + else:
2290 + msg = Frame(data, track=track)
2291 + return _send_frame(self.handle, msg, flags)
2292 +
2293 + cpdef object recv(self, int flags=0, copy=True, track=False):
2294 + """s.recv(flags=0, copy=True, track=False)
2295 +
2296 + Receive a message.
2297 +
2298 + Parameters
2299 + ----------
2300 + flags : int
2301 + Any supported flag: NOBLOCK. If NOBLOCK is set, this method
2302 + will raise a ZMQError with EAGAIN if a message is not ready.
2303 + If NOBLOCK is not set, then this method will block until a
2304 + message arrives.
2305 + copy : bool
2306 + Should the message be received in a copying or non-copying manner?
2307 + If False a Frame object is returned, if True a string copy of
2308 + message is returned.
2309 + track : bool
2310 + Should the message be tracked for notification that ZMQ has
2311 + finished with it? (ignored if copy=True)
2312 +
2313 + Returns
2314 + -------
2315 + msg : bytes, Frame
2316 + The received message frame. If `copy` is False, then it will be a Frame,
2317 + otherwise it will be bytes.
2318 +
2319 + Raises
2320 + ------
2321 + ZMQError
2322 + for any of the reasons zmq_msg_recv might fail.
2323 + """
2324 + _check_closed(self, True)
2325 +
2326 + if copy:
2327 + return _recv_copy(self.handle, flags)
2328 + else:
2329 + frame = _recv_frame(self.handle, flags, track)
2330 + frame.more = self.getsockopt(zmq.RCVMORE)
2331 + return frame
2332 +
2333 +
2334 +__all__ = ['Socket', 'IPC_PATH_MAX_LEN']
2335 diff --git a/zmq/core/_zstopwatch.pxd b/zmq/core/_zstopwatch.pxd
2336 new file mode 100644
2337 index 0000000..5d56166
2338 --- /dev/null
2339 +++ b/zmq/core/_zstopwatch.pxd
2340 @@ -0,0 +1,31 @@
2341 +"""0MQ Stopwatch class declaration."""
2342 +
2343 +#
2344 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
2345 +#
2346 +# This file is part of pyzmq.
2347 +#
2348 +# pyzmq is free software; you can redistribute it and/or modify it under
2349 +# the terms of the Lesser GNU General Public License as published by
2350 +# the Free Software Foundation; either version 3 of the License, or
2351 +# (at your option) any later version.
2352 +#
2353 +# pyzmq is distributed in the hope that it will be useful,
2354 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
2355 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2356 +# Lesser GNU General Public License for more details.
2357 +#
2358 +# You should have received a copy of the Lesser GNU General Public License
2359 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
2360 +#
2361 +
2362 +#-----------------------------------------------------------------------------
2363 +# Code
2364 +#-----------------------------------------------------------------------------
2365 +
2366 +
2367 +cdef class Stopwatch:
2368 + """A simple stopwatch based on zmq_stopwatch_start/stop."""
2369 +
2370 + cdef void *watch # The C handle for the underlying zmq object
2371 +
2372 diff --git a/zmq/core/_zstopwatch.pyx b/zmq/core/_zstopwatch.pyx
2373 new file mode 100644
2374 index 0000000..6d2fd61
2375 --- /dev/null
2376 +++ b/zmq/core/_zstopwatch.pyx
2377 @@ -0,0 +1,90 @@
2378 +"""0MQ Stopwatch class."""
2379 +
2380 +#
2381 +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
2382 +#
2383 +# This file is part of pyzmq.
2384 +#
2385 +# pyzmq is free software; you can redistribute it and/or modify it under
2386 +# the terms of the Lesser GNU General Public License as published by
2387 +# the Free Software Foundation; either version 3 of the License, or
2388 +# (at your option) any later version.
2389 +#
2390 +# pyzmq is distributed in the hope that it will be useful,
2391 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
2392 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2393 +# Lesser GNU General Public License for more details.
2394 +#
2395 +# You should have received a copy of the Lesser GNU General Public License
2396 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
2397 +#
2398 +
2399 +#-----------------------------------------------------------------------------
2400 +# Imports
2401 +#-----------------------------------------------------------------------------
2402 +
2403 +from libzmq cimport zmq_stopwatch_start, zmq_stopwatch_stop, zmq_sleep
2404 +
2405 +from zmq.error import ZMQError
2406 +
2407 +#-----------------------------------------------------------------------------
2408 +# Code
2409 +#-----------------------------------------------------------------------------
2410 +
2411 +cdef class Stopwatch:
2412 + """Stopwatch()
2413 +
2414 + A simple stopwatch based on zmq_stopwatch_start/stop.
2415 +
2416 + This class should be used for benchmarking and timing 0MQ code.
2417 + """
2418 +
2419 + def __cinit__(self):
2420 + self.watch = NULL
2421 +
2422 + def __dealloc__(self):
2423 + try:
2424 + self.stop()
2425 + except ZMQError:
2426 + pass
2427 +
2428 + def start(self):
2429 + """s.start()
2430 +
2431 + Start the stopwatch.
2432 + """
2433 + if self.watch == NULL:
2434 + with nogil:
2435 + self.watch = zmq_stopwatch_start()
2436 + else:
2437 + raise ZMQError('Stopwatch is already runing.')
2438 +
2439 + def stop(self):
2440 + """s.stop()
2441 +
2442 + Stop the stopwatch.
2443 +
2444 + Returns
2445 + -------
2446 + t : unsigned long int
2447 + the number of microseconds since ``start()`` was called.
2448 + """
2449 + cdef unsigned long time
2450 + if self.watch == NULL:
2451 + raise ZMQError('Must start the Stopwatch before calling stop.')
2452 + else:
2453 + with nogil:
2454 + time = zmq_stopwatch_stop(self.watch)
2455 + self.watch = NULL
2456 + return time
2457 +
2458 + def sleep(self, int seconds):
2459 + """s.sleep(seconds)
2460 +
2461 + Sleep for an integer number of seconds.
2462 + """
2463 + with nogil:
2464 + zmq_sleep(seconds)
2465 +
2466 +
2467 +__all__ = ['Stopwatch']
2468 diff --git a/zmq/core/constants.pyx b/zmq/core/constants.pyx
2469 deleted file mode 100644
2470 index fa2695d..0000000
2471 --- a/zmq/core/constants.pyx
2472 +++ /dev/null
2473 @@ -1,190 +0,0 @@
2474 -"""0MQ Constants."""
2475 -
2476 -#
2477 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
2478 -#
2479 -# This file is part of pyzmq.
2480 -#
2481 -# pyzmq is free software; you can redistribute it and/or modify it under
2482 -# the terms of the Lesser GNU General Public License as published by
2483 -# the Free Software Foundation; either version 3 of the License, or
2484 -# (at your option) any later version.
2485 -#
2486 -# pyzmq is distributed in the hope that it will be useful,
2487 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
2488 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2489 -# Lesser GNU General Public License for more details.
2490 -#
2491 -# You should have received a copy of the Lesser GNU General Public License
2492 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
2493 -#
2494 -
2495 -#-----------------------------------------------------------------------------
2496 -# Imports
2497 -#-----------------------------------------------------------------------------
2498 -
2499 -from libzmq cimport *
2500 -
2501 -#-----------------------------------------------------------------------------
2502 -# Python module level constants
2503 -#-----------------------------------------------------------------------------
2504 -
2505 -_optionals = []
2506 -
2507 -if ZMQ_VERSION < 30000:
2508 - # backport DONTWAIT as alias to NOBLOCK
2509 - NOBLOCK = ZMQ_NOBLOCK
2510 - DONTWAIT = ZMQ_NOBLOCK
2511 -else:
2512 - # keep NOBLOCK as alias for new DONTWAIT
2513 - NOBLOCK = ZMQ_DONTWAIT
2514 - DONTWAIT = ZMQ_DONTWAIT
2515 -
2516 -VERSION = ZMQ_VERSION
2517 -
2518 -# socket types
2519 -PAIR = ZMQ_PAIR
2520 -PUB = ZMQ_PUB
2521 -SUB = ZMQ_SUB
2522 -REQ = ZMQ_REQ
2523 -REP = ZMQ_REP
2524 -DEALER = ZMQ_DEALER
2525 -ROUTER = ZMQ_ROUTER
2526 -PULL = ZMQ_PULL
2527 -PUSH = ZMQ_PUSH
2528 -XPUB = ZMQ_XPUB
2529 -XSUB = ZMQ_XSUB
2530 -
2531 -# keep deprecated aliases
2532 -XREQ = DEALER
2533 -XREP = ROUTER
2534 -UPSTREAM = PULL
2535 -DOWNSTREAM = PUSH
2536 -
2537 -
2538 -# socket options
2539 -AFFINITY = ZMQ_AFFINITY
2540 -IDENTITY = ZMQ_IDENTITY
2541 -SUBSCRIBE = ZMQ_SUBSCRIBE
2542 -UNSUBSCRIBE = ZMQ_UNSUBSCRIBE
2543 -RATE = ZMQ_RATE
2544 -RECOVERY_IVL = ZMQ_RECOVERY_IVL
2545 -RECONNECT_IVL_MAX = ZMQ_RECONNECT_IVL_MAX
2546 -SNDBUF = ZMQ_SNDBUF
2547 -RCVBUF = ZMQ_RCVBUF
2548 -RCVMORE = ZMQ_RCVMORE
2549 -SNDMORE = ZMQ_SNDMORE
2550 -POLLIN = ZMQ_POLLIN
2551 -POLLOUT = ZMQ_POLLOUT
2552 -POLLERR = ZMQ_POLLERR
2553 -
2554 -STREAMER = ZMQ_STREAMER
2555 -FORWARDER = ZMQ_FORWARDER
2556 -QUEUE = ZMQ_QUEUE
2557 -
2558 -# sockopts new in 2.2.0
2559 -SNDTIMEO = ZMQ_SNDTIMEO
2560 -RCVTIMEO = ZMQ_RCVTIMEO
2561 -
2562 -# sockopts removed in 3.0.0
2563 -HWM = ZMQ_HWM
2564 -SWAP = ZMQ_SWAP
2565 -MCAST_LOOP = ZMQ_MCAST_LOOP
2566 -RECOVERY_IVL_MSEC = ZMQ_RECOVERY_IVL_MSEC
2567 -
2568 -# new in 3.x
2569 -IO_THREADS = ZMQ_IO_THREADS
2570 -MAX_SOCKETS = ZMQ_MAX_SOCKETS
2571 -
2572 -MORE = ZMQ_MORE
2573 -
2574 -MAXMSGSIZE = ZMQ_MAXMSGSIZE
2575 -SNDHWM = ZMQ_SNDHWM
2576 -RCVHWM = ZMQ_RCVHWM
2577 -MULTICAST_HOPS = ZMQ_MULTICAST_HOPS
2578 -IPV4ONLY = ZMQ_IPV4ONLY
2579 -LAST_ENDPOINT = ZMQ_LAST_ENDPOINT
2580 -
2581 -ROUTER_MANDATORY = ZMQ_ROUTER_MANDATORY
2582 -# aliases
2583 -ROUTER_BEHAVIOR = ROUTER_MANDATORY
2584 -FAIL_UNROUTABLE = ROUTER_MANDATORY
2585 -
2586 -TCP_KEEPALIVE = ZMQ_TCP_KEEPALIVE
2587 -TCP_KEEPALIVE_CNT = ZMQ_TCP_KEEPALIVE_CNT
2588 -TCP_KEEPALIVE_IDLE = ZMQ_TCP_KEEPALIVE_IDLE
2589 -TCP_KEEPALIVE_INTVL = ZMQ_TCP_KEEPALIVE_INTVL
2590 -TCP_ACCEPT_FILTER = ZMQ_TCP_ACCEPT_FILTER
2591 -DELAY_ATTACH_ON_CONNECT = ZMQ_DELAY_ATTACH_ON_CONNECT
2592 -XPUB_VERBOSE = ZMQ_XPUB_VERBOSE
2593 -ROUTER_RAW = ZMQ_ROUTER_RAW
2594 -
2595 -EVENT_CONNECTED = ZMQ_EVENT_CONNECTED
2596 -EVENT_CONNECT_DELAYED = ZMQ_EVENT_CONNECT_DELAYED
2597 -EVENT_CONNECT_RETRIED = ZMQ_EVENT_CONNECT_RETRIED
2598 -EVENT_LISTENING = ZMQ_EVENT_LISTENING
2599 -EVENT_BIND_FAILED = ZMQ_EVENT_BIND_FAILED
2600 -EVENT_ACCEPTED = ZMQ_EVENT_ACCEPTED
2601 -EVENT_ACCEPT_FAILED = ZMQ_EVENT_ACCEPT_FAILED
2602 -EVENT_CLOSED = ZMQ_EVENT_CLOSED
2603 -EVENT_CLOSE_FAILED = ZMQ_EVENT_CLOSE_FAILED
2604 -EVENT_DISCONNECTED = ZMQ_EVENT_DISCONNECTED
2605 -
2606 -FD = ZMQ_FD
2607 -EVENTS = ZMQ_EVENTS
2608 -TYPE = ZMQ_TYPE
2609 -LINGER = ZMQ_LINGER
2610 -RECONNECT_IVL = ZMQ_RECONNECT_IVL
2611 -BACKLOG = ZMQ_BACKLOG
2612 -
2613 -# As new constants are added in future versions, add a new block here
2614 -# like the two above, checking agains the relevant value for ZMQ_VERSION.
2615 -# The constants will need to be added to libzmq.pxd and utils/zmq_compat.h
2616 -# as well.
2617 -
2618 -#-----------------------------------------------------------------------------
2619 -# Error handling
2620 -#-----------------------------------------------------------------------------
2621 -
2622 -# Often used standard errnos
2623 -from errno import (
2624 - EAGAIN,
2625 - EINVAL,
2626 - EFAULT,
2627 - ENOMEM,
2628 - ENODEV
2629 -)
2630 -
2631 -# For Windows compatability
2632 -ENOTSUP = ZMQ_ENOTSUP
2633 -EPROTONOSUPPORT = ZMQ_EPROTONOSUPPORT
2634 -ENOBUFS = ZMQ_ENOBUFS
2635 -ENETDOWN = ZMQ_ENETDOWN
2636 -EADDRINUSE = ZMQ_EADDRINUSE
2637 -EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL
2638 -ECONNREFUSED = ZMQ_ECONNREFUSED
2639 -EINPROGRESS = ZMQ_EINPROGRESS
2640 -ENOTSOCK = ZMQ_ENOTSOCK
2641 -
2642 -# new errnos in zmq3
2643 -EMSGSIZE = ZMQ_EMSGSIZE
2644 -EAFNOSUPPORT = ZMQ_EAFNOSUPPORT
2645 -ENETUNREACH = ZMQ_ENETUNREACH
2646 -ECONNABORTED = ZMQ_ECONNABORTED
2647 -ECONNRESET = ZMQ_ECONNRESET
2648 -ENOTCONN = ZMQ_ENOTCONN
2649 -ETIMEDOUT = ZMQ_ETIMEDOUT
2650 -EHOSTUNREACH = ZMQ_EHOSTUNREACH
2651 -ENETRESET = ZMQ_ENETRESET
2652 -
2653 -# 0MQ Native
2654 -EFSM = ZMQ_EFSM
2655 -ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO
2656 -ETERM = ZMQ_ETERM
2657 -EMTHREAD = ZMQ_EMTHREAD
2658 -
2659 -#-----------------------------------------------------------------------------
2660 -# Symbols to export
2661 -#-----------------------------------------------------------------------------
2662 -_names = list(locals().keys())
2663 -__all__ = [ key for key in _names if not key.startswith('_') ]
2664 diff --git a/zmq/core/context.pxd b/zmq/core/context.pxd
2665 deleted file mode 100644
2666 index e399de5..0000000
2667 --- a/zmq/core/context.pxd
2668 +++ /dev/null
2669 @@ -1,40 +0,0 @@
2670 -"""0MQ Context class declaration."""
2671 -
2672 -#
2673 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
2674 -#
2675 -# This file is part of pyzmq.
2676 -#
2677 -# pyzmq is free software; you can redistribute it and/or modify it under
2678 -# the terms of the Lesser GNU General Public License as published by
2679 -# the Free Software Foundation; either version 3 of the License, or
2680 -# (at your option) any later version.
2681 -#
2682 -# pyzmq is distributed in the hope that it will be useful,
2683 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
2684 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2685 -# Lesser GNU General Public License for more details.
2686 -#
2687 -# You should have received a copy of the Lesser GNU General Public License
2688 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
2689 -#
2690 -
2691 -#-----------------------------------------------------------------------------
2692 -# Code
2693 -#-----------------------------------------------------------------------------
2694 -
2695 -cdef class Context:
2696 - """Manage the lifecycle of a 0MQ context."""
2697 -
2698 - cdef object __weakref__ # enable weakref
2699 - cdef void *handle # The C handle for the underlying zmq object.
2700 - cdef void **_sockets # A C-array containg socket handles
2701 - cdef size_t _n_sockets # the number of sockets
2702 - cdef size_t _max_sockets # the size of the _sockets array
2703 - cdef int _pid # the pid of the process which created me (for fork safety)
2704 -
2705 - cdef public object closed # bool property for a closed context.
2706 - # helpers for events on _sockets in Socket.__cinit__()/close()
2707 - cdef inline void _add_socket(self, void* handle)
2708 - cdef inline void _remove_socket(self, void* handle)
2709 -
2710 diff --git a/zmq/core/context.pyx b/zmq/core/context.pyx
2711 deleted file mode 100644
2712 index 0917c66..0000000
2713 --- a/zmq/core/context.pyx
2714 +++ /dev/null
2715 @@ -1,254 +0,0 @@
2716 -"""0MQ Context class."""
2717 -
2718 -#
2719 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
2720 -#
2721 -# This file is part of pyzmq.
2722 -#
2723 -# pyzmq is free software; you can redistribute it and/or modify it under
2724 -# the terms of the Lesser GNU General Public License as published by
2725 -# the Free Software Foundation; either version 3 of the License, or
2726 -# (at your option) any later version.
2727 -#
2728 -# pyzmq is distributed in the hope that it will be useful,
2729 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
2730 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2731 -# Lesser GNU General Public License for more details.
2732 -#
2733 -# You should have received a copy of the Lesser GNU General Public License
2734 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
2735 -#
2736 -
2737 -#-----------------------------------------------------------------------------
2738 -# Imports
2739 -#-----------------------------------------------------------------------------
2740 -
2741 -from libc.stdlib cimport free, malloc, realloc
2742 -
2743 -from libzmq cimport *
2744 -
2745 -cdef extern from "getpid_compat.h":
2746 - int getpid()
2747 -
2748 -from zmq.error import ZMQError
2749 -from zmq.core.checkrc cimport _check_rc
2750 -
2751 -#-----------------------------------------------------------------------------
2752 -# Code
2753 -#-----------------------------------------------------------------------------
2754 -
2755 -_instance = None
2756 -
2757 -cdef class Context:
2758 - """Context(io_threads=1)
2759 -
2760 - Manage the lifecycle of a 0MQ context.
2761 -
2762 - Parameters
2763 - ----------
2764 - io_threads : int
2765 - The number of IO threads.
2766 - """
2767 -
2768 - def __cinit__(self, int io_threads = 1, **kwargs):
2769 - self.handle = NULL
2770 - self._sockets = NULL
2771 -
2772 - if ZMQ_VERSION_MAJOR >= 3:
2773 - self.handle = zmq_ctx_new()
2774 - else:
2775 - self.handle = zmq_init(io_threads)
2776 -
2777 - if self.handle == NULL:
2778 - raise ZMQError()
2779 -
2780 - cdef int rc = 0
2781 - if ZMQ_VERSION_MAJOR >= 3:
2782 - rc = zmq_ctx_set(self.handle, ZMQ_IO_THREADS, io_threads)
2783 - _check_rc(rc)
2784 -
2785 - self.closed = False
2786 - self._n_sockets = 0
2787 - self._max_sockets = 32
2788 -
2789 - self._sockets = <void **>malloc(self._max_sockets*sizeof(void *))
2790 - if self._sockets == NULL:
2791 - raise MemoryError("Could not allocate _sockets array")
2792 -
2793 - self._pid = getpid()
2794 -
2795 - def __init__(self, io_threads=1):
2796 - # no-op
2797 - pass
2798 -
2799 -
2800 - def __del__(self):
2801 - """deleting a Context should terminate it, without trying non-threadsaf e destroy"""
2802 - self.term()
2803 -
2804 - def __dealloc__(self):
2805 - """don't touch members in dealloc, just cleanup allocations"""
2806 - cdef int rc
2807 - if self._sockets != NULL:
2808 - free(self._sockets)
2809 - self._sockets = NULL
2810 - self._n_sockets = 0
2811 - self.term()
2812 -
2813 - cdef inline void _add_socket(self, void* handle):
2814 - """Add a socket handle to be closed when Context terminates.
2815 -
2816 - This is to be called in the Socket constructor.
2817 - """
2818 - # print self._n_sockets, self._max_sockets
2819 - if self._n_sockets >= self._max_sockets:
2820 - self._max_sockets *= 2
2821 - self._sockets = <void **>realloc(self._sockets, self._max_sockets*s izeof(void *))
2822 - if self._sockets == NULL:
2823 - raise MemoryError("Could not reallocate _sockets array")
2824 -
2825 - self._sockets[self._n_sockets] = handle
2826 - self._n_sockets += 1
2827 - # print self._n_sockets, self._max_sockets
2828 -
2829 - cdef inline void _remove_socket(self, void* handle):
2830 - """Remove a socket from the collected handles.
2831 -
2832 - This should be called by Socket.close, to prevent trying to
2833 - close a socket a second time.
2834 - """
2835 - cdef bint found = False
2836 -
2837 - for idx in range(self._n_sockets):
2838 - if self._sockets[idx] == handle:
2839 - found=True
2840 - break
2841 -
2842 - if found:
2843 - self._n_sockets -= 1
2844 - if self._n_sockets:
2845 - # move last handle to closed socket's index
2846 - self._sockets[idx] = self._sockets[self._n_sockets]
2847 -
2848 - @property
2849 - def _handle(self):
2850 - return <Py_ssize_t> self.handle
2851 -
2852 - def term(self):
2853 - """ctx.term()
2854 -
2855 - Close or terminate the context.
2856 -
2857 - This can be called to close the context by hand. If this is not called,
2858 - the context will automatically be closed when it is garbage collected.
2859 - """
2860 - cdef int rc
2861 - cdef int i=-1
2862 -
2863 - if self.handle != NULL and not self.closed and getpid() == self._pid:
2864 - with nogil:
2865 - rc = zmq_ctx_destroy(self.handle)
2866 - _check_rc(rc)
2867 - self.handle = NULL
2868 - self.closed = True
2869 -
2870 - def set(self, int option, optval):
2871 - """ctx.set(option, optval)
2872 -
2873 - Set context options.
2874 -
2875 - See the 0MQ API documentation for zmq_ctx_set
2876 - for details on specific options.
2877 -
2878 - New in libzmq-3.2
2879 -
2880 - Parameters
2881 - ----------
2882 - option : int
2883 - The option to set. Available values will depend on your
2884 - version of libzmq. Examples include::
2885 -
2886 - zmq.IO_THREADS, zmq.MAX_SOCKETS
2887 -
2888 - optval : int
2889 - The value of the option to set.
2890 - """
2891 - cdef int optval_int_c
2892 - cdef int rc
2893 - cdef char* optval_c
2894 -
2895 - if self.closed:
2896 - raise RuntimeError("Context has been destroyed")
2897 -
2898 - if not isinstance(optval, int):
2899 - raise TypeError('expected int, got: %r' % optval)
2900 - optval_int_c = optval
2901 - rc = zmq_ctx_set(self.handle, option, optval_int_c)
2902 - _check_rc(rc)
2903 -
2904 - def get(self, int option):
2905 - """ctx.get(option)
2906 -
2907 - Get the value of a context option.
2908 -
2909 - See the 0MQ API documentation for zmq_ctx_get
2910 - for details on specific options.
2911 -
2912 - New in libzmq-3.2
2913 -
2914 - Parameters
2915 - ----------
2916 - option : int
2917 - The option to get. Available values will depend on your
2918 - version of libzmq. Examples include::
2919 -
2920 - zmq.IO_THREADS, zmq.MAX_SOCKETS
2921 -
2922 - Returns
2923 - -------
2924 - optval : int
2925 - The value of the option as an integer.
2926 - """
2927 - cdef int optval_int_c
2928 - cdef size_t sz
2929 - cdef int rc
2930 -
2931 - if self.closed:
2932 - raise RuntimeError("Context has been destroyed")
2933 -
2934 - rc = zmq_ctx_get(self.handle, option)
2935 - _check_rc(rc)
2936 -
2937 - return rc
2938 -
2939 - def destroy(self, linger=None):
2940 - """ctx.destroy(linger=None)
2941 -
2942 - Close all sockets associated with this context, and then terminate
2943 - the context. If linger is specified,
2944 - the LINGER sockopt of the sockets will be set prior to closing.
2945 -
2946 - WARNING:
2947 -
2948 - destroy involves calling zmq_close(), which is *NOT* threadsafe.
2949 - If there are active sockets in other threads, this must not be called.
2950 - """
2951 -
2952 - cdef int linger_c
2953 - cdef bint setlinger=False
2954 -
2955 - if linger is not None:
2956 - linger_c = linger
2957 - setlinger=True
2958 - if self.handle != NULL and not self.closed and self._n_sockets:
2959 - while self._n_sockets:
2960 - if setlinger:
2961 - zmq_setsockopt(self._sockets[0], ZMQ_LINGER, &linger_c, siz eof(int))
2962 - rc = zmq_close(self._sockets[0])
2963 - if rc < 0 and zmq_errno() != ZMQ_ENOTSOCK:
2964 - raise ZMQError()
2965 - self._n_sockets -= 1
2966 - self._sockets[0] = self._sockets[self._n_sockets]
2967 - self.term()
2968 -
2969 -__all__ = ['Context']
2970 diff --git a/zmq/core/error.pyx b/zmq/core/error.pyx
2971 deleted file mode 100644
2972 index 85e785f..0000000
2973 --- a/zmq/core/error.pyx
2974 +++ /dev/null
2975 @@ -1,56 +0,0 @@
2976 -"""0MQ Error classes and functions."""
2977 -
2978 -#
2979 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
2980 -#
2981 -# This file is part of pyzmq.
2982 -#
2983 -# pyzmq is free software; you can redistribute it and/or modify it under
2984 -# the terms of the Lesser GNU General Public License as published by
2985 -# the Free Software Foundation; either version 3 of the License, or
2986 -# (at your option) any later version.
2987 -#
2988 -# pyzmq is distributed in the hope that it will be useful,
2989 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
2990 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2991 -# Lesser GNU General Public License for more details.
2992 -#
2993 -# You should have received a copy of the Lesser GNU General Public License
2994 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
2995 -#
2996 -
2997 -#-----------------------------------------------------------------------------
2998 -# Imports
2999 -#-----------------------------------------------------------------------------
3000 -
3001 -# allow const char*
3002 -cdef extern from *:
3003 - ctypedef char* const_char_ptr "const char*"
3004 -
3005 -from libzmq cimport zmq_strerror, zmq_errno as zmq_errno_c
3006 -
3007 -from zmq.utils.strtypes import bytes
3008 -
3009 -def strerror(int errno):
3010 - """strerror(errno)
3011 -
3012 - Return the error string given the error number.
3013 - """
3014 - cdef const_char_ptr str_e
3015 - # char * will be a bytes object:
3016 - str_e = zmq_strerror(errno)
3017 - if str is bytes:
3018 - # Python 2: str is bytes, so we already have the right type
3019 - return str_e
3020 - else:
3021 - # Python 3: decode bytes to unicode str
3022 - return str_e.decode()
3023 -
3024 -def zmq_errno():
3025 - """zmq_errno()
3026 -
3027 - Return the integer errno of the most recent zmq error.
3028 - """
3029 - return zmq_errno_c()
3030 -
3031 -__all__ = ['strerror', 'zmq_errno']
3032 diff --git a/zmq/core/message.pxd b/zmq/core/message.pxd
3033 deleted file mode 100644
3034 index a86a8e0..0000000
3035 --- a/zmq/core/message.pxd
3036 +++ /dev/null
3037 @@ -1,66 +0,0 @@
3038 -"""0MQ Message related class declarations."""
3039 -
3040 -#
3041 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
3042 -#
3043 -# This file is part of pyzmq.
3044 -#
3045 -# pyzmq is free software; you can redistribute it and/or modify it under
3046 -# the terms of the Lesser GNU General Public License as published by
3047 -# the Free Software Foundation; either version 3 of the License, or
3048 -# (at your option) any later version.
3049 -#
3050 -# pyzmq is distributed in the hope that it will be useful,
3051 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
3052 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3053 -# Lesser GNU General Public License for more details.
3054 -#
3055 -# You should have received a copy of the Lesser GNU General Public License
3056 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
3057 -#
3058 -
3059 -#-----------------------------------------------------------------------------
3060 -# Imports
3061 -#-----------------------------------------------------------------------------
3062 -
3063 -from cpython cimport PyBytes_FromStringAndSize
3064 -
3065 -from libzmq cimport zmq_msg_t, zmq_msg_data, zmq_msg_size
3066 -
3067 -#-----------------------------------------------------------------------------
3068 -# Code
3069 -#-----------------------------------------------------------------------------
3070 -
3071 -cdef class MessageTracker(object):
3072 - """A class for tracking if 0MQ is done using one or more messages."""
3073 -
3074 - cdef set events # Message Event objects to track.
3075 - cdef set peers # Other Message or MessageTracker objects.
3076 -
3077 -
3078 -cdef class Frame:
3079 - """A Message Frame class for non-copy send/recvs."""
3080 -
3081 - cdef zmq_msg_t zmq_msg
3082 - cdef object _data # The actual message data as a Python object.
3083 - cdef object _buffer # A Python Buffer/View of the message contents
3084 - cdef object _bytes # A bytes/str copy of the message.
3085 - cdef bint _failed_init # Flag to handle failed zmq_msg_init
3086 - cdef public object tracker_event # Event for use with zmq_free_fn.
3087 - cdef public object tracker # MessageTracker object.
3088 - cdef public bint more # whether RCVMORE was set
3089 -
3090 - cdef Frame fast_copy(self) # Create shallow copy of Message object.
3091 - cdef object _getbuffer(self) # Construct self._buffer.
3092 -
3093 -
3094 -cdef inline object copy_zmq_msg_bytes(zmq_msg_t *zmq_msg):
3095 - """ Copy the data from a zmq_msg_t """
3096 - cdef char *data_c = NULL
3097 - cdef Py_ssize_t data_len_c
3098 - with nogil:
3099 - data_c = <char *>zmq_msg_data(zmq_msg)
3100 - data_len_c = zmq_msg_size(zmq_msg)
3101 - return PyBytes_FromStringAndSize(data_c, data_len_c)
3102 -
3103 -
3104 diff --git a/zmq/core/message.pyx b/zmq/core/message.pyx
3105 deleted file mode 100644
3106 index 1d358ab..0000000
3107 --- a/zmq/core/message.pyx
3108 +++ /dev/null
3109 @@ -1,297 +0,0 @@
3110 -"""0MQ Message related classes."""
3111 -
3112 -#
3113 -# Copyright (c) 2013 Brian E. Granger & Min Ragan-Kelley
3114 -#
3115 -# This file is part of pyzmq.
3116 -#
3117 -# pyzmq is free software; you can redistribute it and/or modify it under
3118 -# the terms of the Lesser GNU General Public License as published by
3119 -# the Free Software Foundation; either version 3 of the License, or
3120 -# (at your option) any later version.
3121 -#
3122 -# pyzmq is distributed in the hope that it will be useful,
3123 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
3124 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3125 -# Lesser GNU General Public License for more details.
3126 -#
3127 -# You should have received a copy of the Lesser GNU General Public License
3128 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
3129 -#
3130 -
3131 -#-----------------------------------------------------------------------------
3132 -# Imports
3133 -#-----------------------------------------------------------------------------
3134 -
3135 -# get version-independent aliases:
3136 -cdef extern from "pyversion_compat.h":
3137 - pass
3138 -
3139 -from cpython cimport Py_DECREF, Py_INCREF
3140 -
3141 -from buffers cimport asbuffer_r, viewfromobject_r
3142 -
3143 -cdef extern from "Python.h":
3144 - ctypedef int Py_ssize_t
3145 -
3146 -from libzmq cimport *
3147 -
3148 -import time
3149 -
3150 -try:
3151 - # below 3.3
3152 - from threading import _Event as Event
3153 -except (ImportError, AttributeError):
3154 - # python throws ImportError, cython throws AttributeError
3155 - from threading import Event
3156 -
3157 -import zmq
3158 -from zmq.core.checkrc cimport _check_rc
3159 -from zmq.utils.strtypes import bytes,unicode,basestring
3160 -
3161 -#-----------------------------------------------------------------------------
3162 -# Code
3163 -#-----------------------------------------------------------------------------
3164 -
3165 -
3166 -cdef void free_python_msg(void *data, void *hint) with gil:
3167 - """A function for DECREF'ing Python based messages."""
3168 - if hint != NULL:
3169 - tracker_event = (<tuple>hint)[1]
3170 - Py_DECREF(<object>hint)
3171 - if isinstance(tracker_event, Event):
3172 - # don't assert before DECREF:
3173 - # assert tracker_queue.empty(), "somebody else wrote to my Queue!"
3174 - tracker_event.set()
3175 - tracker_event = None
3176 -
3177 -
3178 -cdef class Frame:
3179 - """Frame(data=None, track=False)
3180 -
3181 - A zmq message Frame class for non-copy send/recvs.
3182 -
3183 - This class is only needed if you want to do non-copying send and recvs.
3184 - When you pass a string to this class, like ``Frame(s)``, the
3185 - ref-count of `s` is increased by two: once because the Frame saves `s` as
3186 - an instance attribute and another because a ZMQ message is created that
3187 - points to the buffer of `s`. This second ref-count increase makes sure
3188 - that `s` lives until all messages that use it have been sent. Once 0MQ
3189 - sends all the messages and it doesn't need the buffer of s, 0MQ will call
3190 - ``Py_DECREF(s)``.
3191 -
3192 - Parameters
3193 - ----------
3194 -
3195 - data : object, optional
3196 - any object that provides the buffer interface will be used to
3197 - construct the 0MQ message data.
3198 - track : bool [default: False]
3199 - whether a MessageTracker_ should be created to track this object.
3200 - Tracking a message has a cost at creation, because it creates a threads afe
3201 - Event object.
3202 -
3203 - """
3204 -
3205 - def __cinit__(self, object data=None, track=False, **kwargs):
3206 - cdef int rc
3207 - cdef char *data_c = NULL
3208 - cdef Py_ssize_t data_len_c=0
3209 - cdef object hint
3210 -
3211 - # init more as False
3212 - self.more = False
3213 -
3214 - # Save the data object in case the user wants the the data as a str.
3215 - self._data = data
3216 - self._failed_init = True # bool switch for dealloc
3217 - self._buffer = None # buffer view of data
3218 - self._bytes = None # bytes copy of data
3219 -
3220 - # Event and MessageTracker for monitoring when zmq is done with data:
3221 - if track:
3222 - evt = Event()
3223 - self.tracker_event = evt
3224 - self.tracker = zmq.MessageTracker(evt)
3225 - else:
3226 - self.tracker_event = None
3227 - self.tracker = None
3228 -
3229 - if isinstance(data, unicode):
3230 - raise TypeError("Unicode objects not allowed. Only: str/bytes, buff er interfaces.")
3231 -
3232 - if data is None:
3233 - with nogil:
3234 - rc = zmq_msg_init(&self.zmq_msg)
3235 - _check_rc(rc)
3236 - self._failed_init = False
3237 - return
3238 - else:
3239 - asbuffer_r(data, <void **>&data_c, &data_len_c)
3240 - # We INCREF the *original* Python object (not self) and pass it
3241 - # as the hint below. This allows other copies of this Frame
3242 - # object to take over the ref counting of data properly.
3243 - hint = (data, self.tracker_event)
3244 - Py_INCREF(hint)
3245 - with nogil:
3246 - rc = zmq_msg_init_data(
3247 - &self.zmq_msg, <void *>data_c, data_len_c,
3248 - <zmq_free_fn *>free_python_msg, <void *>hint
3249 - )
3250 - if rc != 0:
3251 - Py_DECREF(hint)
3252 - _check_rc(rc)
3253 - self._failed_init = False
3254 -
3255 - def __init__(self, object data=None, track=False):
3256 - """Enforce signature"""
3257 - pass
3258 -
3259 - def __dealloc__(self):
3260 - cdef int rc
3261 - if self._failed_init:
3262 - return
3263 - # This simply decreases the 0MQ ref-count of zmq_msg.
3264 - with nogil:
3265 - rc = zmq_msg_close(&self.zmq_msg)
3266 - _check_rc(rc)
3267 -
3268 - # buffer interface code adapted from petsc4py by Lisandro Dalcin, a BSD pro ject
3269 -
3270 - def __getbuffer__(self, Py_buffer* buffer, int flags):
3271 - # new-style (memoryview) buffer interface
3272 - with nogil:
3273 - buffer.buf = zmq_msg_data(&self.zmq_msg)
3274 - buffer.len = zmq_msg_size(&self.zmq_msg)
3275 -
3276 - buffer.obj = self
3277 - buffer.readonly = 1
3278 - buffer.format = "B"
3279 - buffer.ndim = 0
3280 - buffer.shape = NULL
3281 - buffer.strides = NULL
3282 - buffer.suboffsets = NULL
3283 - buffer.itemsize = 1
3284 - buffer.internal = NULL
3285 -
3286 - def __getsegcount__(self, Py_ssize_t *lenp):
3287 - # required for getreadbuffer
3288 - if lenp != NULL:
3289 - with nogil:
3290 - lenp[0] = zmq_msg_size(&self.zmq_msg)
3291 - return 1
3292 -
3293 - def __getreadbuffer__(self, Py_ssize_t idx, void **p):
3294 - # old-style (buffer) interface
3295 - cdef char *data_c = NULL
3296 - cdef Py_ssize_t data_len_c
3297 - if idx != 0:
3298 - raise SystemError("accessing non-existent buffer segment")
3299 - # read-only, because we don't want to allow
3300 - # editing of the message in-place
3301 - with nogil:
3302 - data_c = <char *>zmq_msg_data(&self.zmq_msg)
3303 - data_len_c = zmq_msg_size(&self.zmq_msg)
3304 - if p != NULL:
3305 - p[0] = <void*>data_c
3306 - return data_len_c
3307 -
3308 - # end buffer interface
3309 -
3310 - def __copy__(self):
3311 - """Create a shallow copy of the message.
3312 -
3313 - This does not copy the contents of the Frame, just the pointer.
3314 - This will increment the 0MQ ref count of the message, but not
3315 - the ref count of the Python object. That is only done once when
3316 - the Python is first turned into a 0MQ message.
3317 - """
3318 - return self.fast_copy()
3319 -
3320 - cdef Frame fast_copy(self):
3321 - """Fast, cdef'd version of shallow copy of the Frame."""
3322 - cdef Frame new_msg
3323 - new_msg = Frame()
3324 - # This does not copy the contents, but just increases the ref-count
3325 - # of the zmq_msg by one.
3326 - with nogil:
3327 - zmq_msg_copy(&new_msg.zmq_msg, &self.zmq_msg)
3328 - # Copy the ref to data so the copy won't create a copy when str is
3329 - # called.
3330 - if self._data is not None:
3331 - new_msg._data = self._data
3332 - if self._buffer is not None:
3333 - new_msg._buffer = self._buffer
3334 - if self._bytes is not None:
3335 - new_msg._bytes = self._bytes
3336 -
3337 - # Frame copies share the tracker and tracker_event
3338 - new_msg.tracker_event = self.tracker_event
3339 - new_msg.tracker = self.tracker
3340 -
3341 - return new_msg
3342 -
3343 - def __len__(self):
3344 - """Return the length of the message in bytes."""
3345 - cdef size_t sz
3346 - with nogil:
3347 - sz = zmq_msg_size(&self.zmq_msg)
3348 - return sz
3349 - # return <int>zmq_msg_size(&self.zmq_msg)
3350 -
3351 - def __str__(self):
3352 - """Return the str form of the message."""
3353 - if isinstance(self._data, bytes):
3354 - b = self._data
3355 - else:
3356 - b = self.bytes
3357 - if str is unicode:
3358 - return b.decode()
3359 - else:
3360 - return b
3361 -
3362 - cdef inline object _getbuffer(self):
3363 - """Create a Python buffer/view of the message data.
3364 -
3365 - This will be called only once, the first time the `buffer` property
3366 - is accessed. Subsequent calls use a cached copy.
3367 - """
3368 - if self._data is None:
3369 - return viewfromobject_r(self)
3370 - else:
3371 - return viewfromobject_r(self._data)
3372 -
3373 - @property
3374 - def buffer(self):
3375 - """Get a read-only buffer view of the message contents."""
3376 - if self._buffer is None:
3377 - self._buffer = self._getbuffer()
3378 - return self._buffer
3379 -
3380 - @property
3381 - def bytes(self):
3382 - """Get the message content as a Python str/bytes object.
3383 -
3384 - The first time this property is accessed, a copy of the message
3385 - contents is made. From then on that same copy of the message is
3386 - returned.
3387 - """
3388 - if self._bytes is None:
3389 - self._bytes = copy_zmq_msg_bytes(&self.zmq_msg)
3390 - return self._bytes
3391 -
3392 - def set(self, int option, int value):
3393 - """Set a message property"""
3394 - cdef int rc = zmq_msg_set(&self.zmq_msg, option, value)
3395 - _check_rc(rc)
3396 -
3397 - def get(self, int option):
3398 - """Get a message property"""
3399 - cdef int rc = zmq_msg_get(&self.zmq_msg, option)
3400 - _check_rc(rc)
3401 - return rc
3402 -
3403 -# legacy Message name
3404 -Message = Frame
3405 -
3406 -__all__ = ['Frame', 'Message']
3407 diff --git a/zmq/core/socket.pxd b/zmq/core/socket.pxd
3408 deleted file mode 100644
3409 index 92253eb..0000000
3410 --- a/zmq/core/socket.pxd
3411 +++ /dev/null
3412 @@ -1,48 +0,0 @@
3413 -"""0MQ Socket class declaration."""
3414 -
3415 -#
3416 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
3417 -#
3418 -# This file is part of pyzmq.
3419 -#
3420 -# pyzmq is free software; you can redistribute it and/or modify it under
3421 -# the terms of the Lesser GNU General Public License as published by
3422 -# the Free Software Foundation; either version 3 of the License, or
3423 -# (at your option) any later version.
3424 -#
3425 -# pyzmq is distributed in the hope that it will be useful,
3426 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
3427 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3428 -# Lesser GNU General Public License for more details.
3429 -#
3430 -# You should have received a copy of the Lesser GNU General Public License
3431 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
3432 -#
3433 -
3434 -#-----------------------------------------------------------------------------
3435 -# Imports
3436 -#-----------------------------------------------------------------------------
3437 -
3438 -from context cimport Context
3439 -
3440 -#-----------------------------------------------------------------------------
3441 -# Code
3442 -#-----------------------------------------------------------------------------
3443 -
3444 -
3445 -cdef class Socket:
3446 - """A 0MQ socket."""
3447 -
3448 - cdef object __weakref__ # enable weakref
3449 - cdef void *handle # The C handle for the underlying zmq object.
3450 - cdef public int socket_type # The 0MQ socket type - REQ,REP, etc.
3451 - # Hold on to a reference to the context to make sure it is not garbage
3452 - # collected until the socket it done with it.
3453 - cdef public Context context # The zmq Context object that owns this.
3454 - cdef public bint _closed # bool property for a closed socket.
3455 - cdef int _pid # the pid of the process which created me (for fork safety)
3456 -
3457 - # cpdef methods for direct-cython access:
3458 - cpdef object send(self, object data, int flags=*, copy=*, track=*)
3459 - cpdef object recv(self, int flags=*, copy=*, track=*)
3460 -
3461 diff --git a/zmq/core/socket.pyx b/zmq/core/socket.pyx
3462 deleted file mode 100644
3463 index 16fbf7f..0000000
3464 --- a/zmq/core/socket.pyx
3465 +++ /dev/null
3466 @@ -1,628 +0,0 @@
3467 -"""0MQ Socket class."""
3468 -
3469 -#
3470 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
3471 -#
3472 -# This file is part of pyzmq.
3473 -#
3474 -# pyzmq is free software; you can redistribute it and/or modify it under
3475 -# the terms of the Lesser GNU General Public License as published by
3476 -# the Free Software Foundation; either version 3 of the License, or
3477 -# (at your option) any later version.
3478 -#
3479 -# pyzmq is distributed in the hope that it will be useful,
3480 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
3481 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3482 -# Lesser GNU General Public License for more details.
3483 -#
3484 -# You should have received a copy of the Lesser GNU General Public License
3485 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
3486 -#
3487 -
3488 -#-----------------------------------------------------------------------------
3489 -# Cython Imports
3490 -#-----------------------------------------------------------------------------
3491 -
3492 -# get version-independent aliases:
3493 -cdef extern from "pyversion_compat.h":
3494 - pass
3495 -
3496 -from libc.errno cimport ENAMETOOLONG
3497 -from libc.string cimport memcpy
3498 -
3499 -from cpython cimport PyBytes_FromStringAndSize
3500 -from cpython cimport PyBytes_AsString, PyBytes_Size
3501 -from cpython cimport Py_DECREF, Py_INCREF
3502 -
3503 -from buffers cimport asbuffer_r, viewfromobject_r
3504 -
3505 -from libzmq cimport *
3506 -from message cimport Frame, copy_zmq_msg_bytes
3507 -
3508 -from context cimport Context
3509 -
3510 -cdef extern from "Python.h":
3511 - ctypedef int Py_ssize_t
3512 -
3513 -cdef extern from "ipcmaxlen.h":
3514 - int get_ipc_path_max_len()
3515 -
3516 -cdef extern from "getpid_compat.h":
3517 - int getpid()
3518 -
3519 -
3520 -#-----------------------------------------------------------------------------
3521 -# Python Imports
3522 -#-----------------------------------------------------------------------------
3523 -
3524 -import copy as copy_mod
3525 -import time
3526 -import sys
3527 -import random
3528 -import struct
3529 -import codecs
3530 -
3531 -from zmq.utils import jsonapi
3532 -
3533 -try:
3534 - import cPickle
3535 - pickle = cPickle
3536 -except:
3537 - cPickle = None
3538 - import pickle
3539 -
3540 -import zmq
3541 -from zmq.core import constants
3542 -from zmq.core.constants import *
3543 -from zmq.core.checkrc cimport _check_rc
3544 -from zmq.error import ZMQError, ZMQBindError
3545 -from zmq.utils.strtypes import bytes,unicode,basestring
3546 -
3547 -#-----------------------------------------------------------------------------
3548 -# Code
3549 -#-----------------------------------------------------------------------------
3550 -
3551 -IPC_PATH_MAX_LEN = get_ipc_path_max_len()
3552 -
3553 -# inline some small socket submethods:
3554 -# true methods frequently cannot be inlined, acc. Cython docs
3555 -
3556 -cdef inline _check_closed(Socket s, bint raise_notsup):
3557 - cdef int rc
3558 - cdef int errno
3559 - cdef int stype
3560 - cdef size_t sz=sizeof(int)
3561 - if s._closed:
3562 - if raise_notsup:
3563 - raise ZMQError(ENOTSUP)
3564 - else:
3565 - return True
3566 - else:
3567 - rc = zmq_getsockopt(s.handle, ZMQ_TYPE, <void *>&stype, &sz)
3568 - if rc < 0 and zmq_errno() == ENOTSOCK:
3569 - s._closed = True
3570 - if raise_notsup:
3571 - raise ZMQError(ENOTSUP)
3572 - else:
3573 - return True
3574 - else:
3575 - _check_rc(rc)
3576 - return False
3577 -
3578 -cdef inline Frame _recv_frame(void *handle, int flags=0, track=False):
3579 - """Receive a message in a non-copying manner and return a Frame."""
3580 - cdef int rc
3581 - cdef Frame msg
3582 - msg = Frame(track=track)
3583 -
3584 - with nogil:
3585 - rc = zmq_msg_recv(&msg.zmq_msg, handle, flags)
3586 -
3587 - _check_rc(rc)
3588 - return msg
3589 -
3590 -cdef inline object _recv_copy(void *handle, int flags=0):
3591 - """Receive a message and return a copy"""
3592 - cdef zmq_msg_t zmq_msg
3593 - with nogil:
3594 - zmq_msg_init (&zmq_msg)
3595 - rc = zmq_msg_recv(&zmq_msg, handle, flags)
3596 - _check_rc(rc)
3597 - msg_bytes = copy_zmq_msg_bytes(&zmq_msg)
3598 - with nogil:
3599 - zmq_msg_close(&zmq_msg)
3600 - return msg_bytes
3601 -
3602 -cdef inline object _send_frame(void *handle, Frame msg, int flags=0):
3603 - """Send a Frame on this socket in a non-copy manner."""
3604 - cdef int rc
3605 - cdef Frame msg_copy
3606 -
3607 - # Always copy so the original message isn't garbage collected.
3608 - # This doesn't do a real copy, just a reference.
3609 - msg_copy = msg.fast_copy()
3610 -
3611 - with nogil:
3612 - rc = zmq_msg_send(&msg_copy.zmq_msg, handle, flags)
3613 -
3614 - _check_rc(rc)
3615 - return msg.tracker
3616 -
3617 -
3618 -cdef inline object _send_copy(void *handle, object msg, int flags=0):
3619 - """Send a message on this socket by copying its content."""
3620 - cdef int rc, rc2
3621 - cdef zmq_msg_t data
3622 - cdef char *msg_c
3623 - cdef Py_ssize_t msg_c_len=0
3624 -
3625 - # copy to c array:
3626 - asbuffer_r(msg, <void **>&msg_c, &msg_c_len)
3627 -
3628 - # Copy the msg before sending. This avoids any complications with
3629 - # the GIL, etc.
3630 - # If zmq_msg_init_* fails we must not call zmq_msg_close (Bus Error)
3631 - with nogil:
3632 - rc = zmq_msg_init_size(&data, msg_c_len)
3633 -
3634 - _check_rc(rc)
3635 -
3636 - with nogil:
3637 - memcpy(zmq_msg_data(&data), msg_c, zmq_msg_size(&data))
3638 - rc = zmq_msg_send(&data, handle, flags)
3639 - rc2 = zmq_msg_close(&data)
3640 - _check_rc(rc)
3641 - _check_rc(rc2)
3642 -
3643 -
3644 -cdef class Socket:
3645 - """Socket(context, socket_type)
3646 -
3647 - A 0MQ socket.
3648 -
3649 - These objects will generally be constructed via the socket() method of a Co ntext object.
3650 -
3651 - Note: 0MQ Sockets are *not* threadsafe. **DO NOT** share them across thread s.
3652 -
3653 - Parameters
3654 - ----------
3655 - context : Context
3656 - The 0MQ Context this Socket belongs to.
3657 - socket_type : int
3658 - The socket type, which can be any of the 0MQ socket types:
3659 - REQ, REP, PUB, SUB, PAIR, DEALER, ROUTER, PULL, PUSH, XPUB, XSUB.
3660 -
3661 - See Also
3662 - --------
3663 - .Context.socket : method for creating a socket bound to a Context.
3664 - """
3665 -
3666 - def __cinit__(self, Context context, int socket_type, *args, **kwrags):
3667 - cdef Py_ssize_t c_handle
3668 - c_handle = context._handle
3669 -
3670 - self.handle = NULL
3671 - self.context = context
3672 - self.socket_type = socket_type
3673 - with nogil:
3674 - self.handle = zmq_socket(<void *>c_handle, socket_type)
3675 - if self.handle == NULL:
3676 - raise ZMQError()
3677 - self._closed = False
3678 - self._pid = getpid()
3679 - context._add_socket(self.handle)
3680 -
3681 - def __dealloc__(self):
3682 - """close *and* remove from context's list
3683 -
3684 - But be careful that context might not exist if called during gc
3685 - """
3686 - if self.handle != NULL and getpid() == self._pid:
3687 - rc = zmq_close(self.handle)
3688 - if rc != 0 and zmq_errno() != ENOTSOCK:
3689 - # ignore ENOTSOCK (closed by Context)
3690 - _check_rc(rc)
3691 - # during gc, self.context might be NULL
3692 - if self.context:
3693 - self.context._remove_socket(self.handle)
3694 -
3695 - def __init__(self, context, socket_type):
3696 - pass
3697 -
3698 - @property
3699 - def closed(self):
3700 - return _check_closed(self, False)
3701 -
3702 - def close(self, linger=None):
3703 - """s.close(linger=None)
3704 -
3705 - Close the socket.
3706 -
3707 - If linger is specified, LINGER sockopt will be set prior to closing.
3708 -
3709 - This can be called to close the socket by hand. If this is not
3710 - called, the socket will automatically be closed when it is
3711 - garbage collected.
3712 - """
3713 - cdef int rc=0
3714 - cdef int linger_c
3715 - cdef bint setlinger=False
3716 -
3717 - if linger is not None:
3718 - linger_c = linger
3719 - setlinger=True
3720 -
3721 - if self.handle != NULL and not self._closed and getpid() == self._pid:
3722 - if setlinger:
3723 - zmq_setsockopt(self.handle, ZMQ_LINGER, &linger_c, sizeof(int))
3724 - rc = zmq_close(self.handle)
3725 - if rc != 0 and zmq_errno() != ENOTSOCK:
3726 - # ignore ENOTSOCK (closed by Context)
3727 - _check_rc(rc)
3728 - self._closed = True
3729 - # during gc, self.context might be NULL
3730 - if self.context:
3731 - self.context._remove_socket(self.handle)
3732 - self.handle = NULL
3733 -
3734 - def set(self, int option, optval):
3735 - """s.set(option, optval)
3736 -
3737 - Set socket options.
3738 -
3739 - See the 0MQ API documentation for details on specific options.
3740 -
3741 - Parameters
3742 - ----------
3743 - option : int
3744 - The option to set. Available values will depend on your
3745 - version of libzmq. Examples include::
3746 -
3747 - zmq.SUBSCRIBE, UNSUBSCRIBE, IDENTITY, HWM, LINGER, FD
3748 -
3749 - optval : int or bytes
3750 - The value of the option to set.
3751 - """
3752 - cdef int64_t optval_int64_c
3753 - cdef int optval_int_c
3754 - cdef int rc
3755 - cdef char* optval_c
3756 - cdef Py_ssize_t sz
3757 -
3758 - _check_closed(self, True)
3759 - if isinstance(optval, unicode):
3760 - raise TypeError("unicode not allowed, use setsockopt_string")
3761 -
3762 - if option in zmq.constants.bytes_sockopts:
3763 - if not isinstance(optval, bytes):
3764 - raise TypeError('expected bytes, got: %r' % optval)
3765 - optval_c = PyBytes_AsString(optval)
3766 - sz = PyBytes_Size(optval)
3767 - with nogil:
3768 - rc = zmq_setsockopt(
3769 - self.handle, option,
3770 - optval_c, sz
3771 - )
3772 - elif option in zmq.constants.int64_sockopts:
3773 - if not isinstance(optval, int):
3774 - raise TypeError('expected int, got: %r' % optval)
3775 - optval_int64_c = optval
3776 - with nogil:
3777 - rc = zmq_setsockopt(
3778 - self.handle, option,
3779 - &optval_int64_c, sizeof(int64_t)
3780 - )
3781 - else:
3782 - # default is to assume int, which is what most new sockopts will be
3783 - # this lets pyzmq work with newer libzmq which may add constants
3784 - # pyzmq has not yet added, rather than artificially raising. Invali d
3785 - # sockopts will still raise just the same, but it will be libzmq do ing
3786 - # the raising.
3787 - if not isinstance(optval, int):
3788 - raise TypeError('expected int, got: %r' % optval)
3789 - optval_int_c = optval
3790 - with nogil:
3791 - rc = zmq_setsockopt(
3792 - self.handle, option,
3793 - &optval_int_c, sizeof(int)
3794 - )
3795 -
3796 - _check_rc(rc)
3797 -
3798 - def get(self, int option):
3799 - """s.get(option)
3800 -
3801 - Get the value of a socket option.
3802 -
3803 - See the 0MQ API documentation for details on specific options.
3804 -
3805 - Parameters
3806 - ----------
3807 - option : int
3808 - The option to get. Available values will depend on your
3809 - version of libzmq. Examples include::
3810 -
3811 - zmq.IDENTITY, HWM, LINGER, FD, EVENTS
3812 -
3813 - Returns
3814 - -------
3815 - optval : int or bytes
3816 - The value of the option as a bytestring or int.
3817 - """
3818 - cdef int64_t optval_int64_c
3819 - cdef int optval_int_c
3820 - cdef fd_t optval_fd_c
3821 - cdef char identity_str_c [255]
3822 - cdef size_t sz
3823 - cdef int rc
3824 -
3825 - _check_closed(self, True)
3826 -
3827 - if option in zmq.constants.bytes_sockopts:
3828 - sz = 255
3829 - with nogil:
3830 - rc = zmq_getsockopt(self.handle, option, <void *>identity_str_c , &sz)
3831 - _check_rc(rc)
3832 - result = PyBytes_FromStringAndSize(<char *>identity_str_c, sz)
3833 - elif option in zmq.constants.int64_sockopts:
3834 - sz = sizeof(int64_t)
3835 - with nogil:
3836 - rc = zmq_getsockopt(self.handle, option, <void *>&optval_int64_ c, &sz)
3837 - _check_rc(rc)
3838 - result = optval_int64_c
3839 - elif option == ZMQ_FD:
3840 - sz = sizeof(fd_t)
3841 - with nogil:
3842 - rc = zmq_getsockopt(self.handle, option, <void *>&optval_fd_c, &sz)
3843 - _check_rc(rc)
3844 - result = optval_fd_c
3845 - else:
3846 - # default is to assume int, which is what most new sockopts will be
3847 - # this lets pyzmq work with newer libzmq which may add constants
3848 - # pyzmq has not yet added, rather than artificially raising. Invali d
3849 - # sockopts will still raise just the same, but it will be libzmq do ing
3850 - # the raising.
3851 - sz = sizeof(int)
3852 - with nogil:
3853 - rc = zmq_getsockopt(self.handle, option, <void *>&optval_int_c, &sz)
3854 - _check_rc(rc)
3855 - result = optval_int_c
3856 -
3857 - return result
3858 -
3859 - def bind(self, addr):
3860 - """s.bind(addr)
3861 -
3862 - Bind the socket to an address.
3863 -
3864 - This causes the socket to listen on a network port. Sockets on the
3865 - other side of this connection will use ``Socket.connect(addr)`` to
3866 - connect to this socket.
3867 -
3868 - Parameters
3869 - ----------
3870 - addr : str
3871 - The address string. This has the form 'protocol://interface:port',
3872 - for example 'tcp://127.0.0.1:5555'. Protocols supported include
3873 - tcp, udp, pgm, epgm, inproc and ipc. If the address is unicode, it is
3874 - encoded to utf-8 first.
3875 - """
3876 - cdef int rc
3877 - cdef char* c_addr
3878 -
3879 - _check_closed(self, True)
3880 - if isinstance(addr, unicode):
3881 - addr = addr.encode('utf-8')
3882 - if not isinstance(addr, bytes):
3883 - raise TypeError('expected str, got: %r' % addr)
3884 - c_addr = addr
3885 - rc = zmq_bind(self.handle, c_addr)
3886 - if rc != 0:
3887 - if IPC_PATH_MAX_LEN and zmq_errno() == ENAMETOOLONG:
3888 - # py3compat: addr is bytes, but msg wants str
3889 - if str is unicode:
3890 - addr = addr.decode('utf-8', 'replace')
3891 - path = addr.split('://', 1)[-1]
3892 - msg = ('ipc path "{0}" is longer than {1} '
3893 - 'characters (sizeof(sockaddr_un.sun_path)). '
3894 - 'zmq.IPC_PATH_MAX_LEN constant can be used '
3895 - 'to check addr length (if it is defined).'
3896 - .format(path, IPC_PATH_MAX_LEN))
3897 - raise ZMQError(msg=msg)
3898 - _check_rc(rc)
3899 -
3900 - def connect(self, addr):
3901 - """s.connect(addr)
3902 -
3903 - Connect to a remote 0MQ socket.
3904 -
3905 - Parameters
3906 - ----------
3907 - addr : str
3908 - The address string. This has the form 'protocol://interface:port',
3909 - for example 'tcp://127.0.0.1:5555'. Protocols supported are
3910 - tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
3911 - encoded to utf-8 first.
3912 - """
3913 - cdef int rc
3914 - cdef char* c_addr
3915 -
3916 - _check_closed(self, True)
3917 - if isinstance(addr, unicode):
3918 - addr = addr.encode('utf-8')
3919 - if not isinstance(addr, bytes):
3920 - raise TypeError('expected str, got: %r' % addr)
3921 - c_addr = addr
3922 -
3923 - rc = zmq_connect(self.handle, c_addr)
3924 - if rc != 0:
3925 - raise ZMQError()
3926 -
3927 - def unbind(self, addr):
3928 - """s.unbind(addr)
3929 -
3930 - Unbind from an address (undoes a call to bind).
3931 -
3932 - This feature requires libzmq-3
3933 -
3934 - Parameters
3935 - ----------
3936 - addr : str
3937 - The address string. This has the form 'protocol://interface:port',
3938 - for example 'tcp://127.0.0.1:5555'. Protocols supported are
3939 - tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
3940 - encoded to utf-8 first.
3941 - """
3942 - cdef int rc
3943 - cdef char* c_addr
3944 -
3945 - if ZMQ_VERSION_MAJOR < 3:
3946 - raise NotImplementedError("unbind requires libzmq >= 3.0, have %s" % zmq.zmq_version())
3947 -
3948 -
3949 - _check_closed(self, True)
3950 - if isinstance(addr, unicode):
3951 - addr = addr.encode('utf-8')
3952 - if not isinstance(addr, bytes):
3953 - raise TypeError('expected str, got: %r' % addr)
3954 - c_addr = addr
3955 -
3956 - rc = zmq_unbind(self.handle, c_addr)
3957 - if rc != 0:
3958 - raise ZMQError()
3959 -
3960 - def disconnect(self, addr):
3961 - """s.disconnect(addr)
3962 -
3963 - Disconnect from a remote 0MQ socket (undoes a call to connect).
3964 -
3965 - This feature requires libzmq-3
3966 -
3967 - Parameters
3968 - ----------
3969 - addr : str
3970 - The address string. This has the form 'protocol://interface:port',
3971 - for example 'tcp://127.0.0.1:5555'. Protocols supported are
3972 - tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
3973 - encoded to utf-8 first.
3974 - """
3975 - cdef int rc
3976 - cdef char* c_addr
3977 -
3978 - if ZMQ_VERSION_MAJOR < 3:
3979 - raise NotImplementedError("disconnect requires libzmq >= 3.0, have %s" % zmq.zmq_version())
3980 -
3981 - _check_closed(self, True)
3982 - if isinstance(addr, unicode):
3983 - addr = addr.encode('utf-8')
3984 - if not isinstance(addr, bytes):
3985 - raise TypeError('expected str, got: %r' % addr)
3986 - c_addr = addr
3987 -
3988 - rc = zmq_disconnect(self.handle, c_addr)
3989 - if rc != 0:
3990 - raise ZMQError()
3991 -
3992 - #-------------------------------------------------------------------------
3993 - # Sending and receiving messages
3994 - #-------------------------------------------------------------------------
3995 -
3996 - cpdef object send(self, object data, int flags=0, copy=True, track=False):
3997 - """s.send(data, flags=0, copy=True, track=False)
3998 -
3999 - Send a message on this socket.
4000 -
4001 - This queues the message to be sent by the IO thread at a later time.
4002 -
4003 - Parameters
4004 - ----------
4005 - data : object, str, Frame
4006 - The content of the message.
4007 - flags : int
4008 - Any supported flag: NOBLOCK, SNDMORE.
4009 - copy : bool
4010 - Should the message be sent in a copying or non-copying manner.
4011 - track : bool
4012 - Should the message be tracked for notification that ZMQ has
4013 - finished with it? (ignored if copy=True)
4014 -
4015 - Returns
4016 - -------
4017 - None : if `copy` or not track
4018 - None if message was sent, raises an exception otherwise.
4019 - MessageTracker : if track and not copy
4020 - a MessageTracker object, whose `pending` property will
4021 - be True until the send is completed.
4022 -
4023 - Raises
4024 - ------
4025 - TypeError
4026 - If a unicode object is passed
4027 - ValueError
4028 - If `track=True`, but an untracked Frame is passed.
4029 - ZMQError
4030 - If the send does not succeed for any reason.
4031 -
4032 - """
4033 - _check_closed(self, True)
4034 -
4035 - if isinstance(data, unicode):
4036 - raise TypeError("unicode not allowed, use send_unicode")
4037 -
4038 - if copy:
4039 - # msg.bytes never returns the input data object
4040 - # it is always a copy, but always the same copy
4041 - if isinstance(data, Frame):
4042 - data = data.buffer
4043 - return _send_copy(self.handle, data, flags)
4044 - else:
4045 - if isinstance(data, Frame):
4046 - if track and not data.tracker:
4047 - raise ValueError('Not a tracked message')
4048 - msg = data
4049 - else:
4050 - msg = Frame(data, track=track)
4051 - return _send_frame(self.handle, msg, flags)
4052 -
4053 - cpdef object recv(self, int flags=0, copy=True, track=False):
4054 - """s.recv(flags=0, copy=True, track=False)
4055 -
4056 - Receive a message.
4057 -
4058 - Parameters
4059 - ----------
4060 - flags : int
4061 - Any supported flag: NOBLOCK. If NOBLOCK is set, this method
4062 - will raise a ZMQError with EAGAIN if a message is not ready.
4063 - If NOBLOCK is not set, then this method will block until a
4064 - message arrives.
4065 - copy : bool
4066 - Should the message be received in a copying or non-copying manner?
4067 - If False a Frame object is returned, if True a string copy of
4068 - message is returned.
4069 - track : bool
4070 - Should the message be tracked for notification that ZMQ has
4071 - finished with it? (ignored if copy=True)
4072 -
4073 - Returns
4074 - -------
4075 - msg : bytes, Frame
4076 - The received message frame. If `copy` is False, then it will be a Frame,
4077 - otherwise it will be bytes.
4078 -
4079 - Raises
4080 - ------
4081 - ZMQError
4082 - for any of the reasons zmq_msg_recv might fail.
4083 - """
4084 - _check_closed(self, True)
4085 -
4086 - if copy:
4087 - return _recv_copy(self.handle, flags)
4088 - else:
4089 - frame = _recv_frame(self.handle, flags, track)
4090 - frame.more = self.getsockopt(zmq.RCVMORE)
4091 - return frame
4092 -
4093 -
4094 -__all__ = ['Socket', 'IPC_PATH_MAX_LEN']
4095 diff --git a/zmq/core/stopwatch.pxd b/zmq/core/stopwatch.pxd
4096 deleted file mode 100644
4097 index 5d56166..0000000
4098 --- a/zmq/core/stopwatch.pxd
4099 +++ /dev/null
4100 @@ -1,31 +0,0 @@
4101 -"""0MQ Stopwatch class declaration."""
4102 -
4103 -#
4104 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
4105 -#
4106 -# This file is part of pyzmq.
4107 -#
4108 -# pyzmq is free software; you can redistribute it and/or modify it under
4109 -# the terms of the Lesser GNU General Public License as published by
4110 -# the Free Software Foundation; either version 3 of the License, or
4111 -# (at your option) any later version.
4112 -#
4113 -# pyzmq is distributed in the hope that it will be useful,
4114 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
4115 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4116 -# Lesser GNU General Public License for more details.
4117 -#
4118 -# You should have received a copy of the Lesser GNU General Public License
4119 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
4120 -#
4121 -
4122 -#-----------------------------------------------------------------------------
4123 -# Code
4124 -#-----------------------------------------------------------------------------
4125 -
4126 -
4127 -cdef class Stopwatch:
4128 - """A simple stopwatch based on zmq_stopwatch_start/stop."""
4129 -
4130 - cdef void *watch # The C handle for the underlying zmq object
4131 -
4132 diff --git a/zmq/core/stopwatch.pyx b/zmq/core/stopwatch.pyx
4133 deleted file mode 100644
4134 index 6d2fd61..0000000
4135 --- a/zmq/core/stopwatch.pyx
4136 +++ /dev/null
4137 @@ -1,90 +0,0 @@
4138 -"""0MQ Stopwatch class."""
4139 -
4140 -#
4141 -# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
4142 -#
4143 -# This file is part of pyzmq.
4144 -#
4145 -# pyzmq is free software; you can redistribute it and/or modify it under
4146 -# the terms of the Lesser GNU General Public License as published by
4147 -# the Free Software Foundation; either version 3 of the License, or
4148 -# (at your option) any later version.
4149 -#
4150 -# pyzmq is distributed in the hope that it will be useful,
4151 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
4152 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4153 -# Lesser GNU General Public License for more details.
4154 -#
4155 -# You should have received a copy of the Lesser GNU General Public License
4156 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
4157 -#
4158 -
4159 -#-----------------------------------------------------------------------------
4160 -# Imports
4161 -#-----------------------------------------------------------------------------
4162 -
4163 -from libzmq cimport zmq_stopwatch_start, zmq_stopwatch_stop, zmq_sleep
4164 -
4165 -from zmq.error import ZMQError
4166 -
4167 -#-----------------------------------------------------------------------------
4168 -# Code
4169 -#-----------------------------------------------------------------------------
4170 -
4171 -cdef class Stopwatch:
4172 - """Stopwatch()
4173 -
4174 - A simple stopwatch based on zmq_stopwatch_start/stop.
4175 -
4176 - This class should be used for benchmarking and timing 0MQ code.
4177 - """
4178 -
4179 - def __cinit__(self):
4180 - self.watch = NULL
4181 -
4182 - def __dealloc__(self):
4183 - try:
4184 - self.stop()
4185 - except ZMQError:
4186 - pass
4187 -
4188 - def start(self):
4189 - """s.start()
4190 -
4191 - Start the stopwatch.
4192 - """
4193 - if self.watch == NULL:
4194 - with nogil:
4195 - self.watch = zmq_stopwatch_start()
4196 - else:
4197 - raise ZMQError('Stopwatch is already runing.')
4198 -
4199 - def stop(self):
4200 - """s.stop()
4201 -
4202 - Stop the stopwatch.
4203 -
4204 - Returns
4205 - -------
4206 - t : unsigned long int
4207 - the number of microseconds since ``start()`` was called.
4208 - """
4209 - cdef unsigned long time
4210 - if self.watch == NULL:
4211 - raise ZMQError('Must start the Stopwatch before calling stop.')
4212 - else:
4213 - with nogil:
4214 - time = zmq_stopwatch_stop(self.watch)
4215 - self.watch = NULL
4216 - return time
4217 -
4218 - def sleep(self, int seconds):
4219 - """s.sleep(seconds)
4220 -
4221 - Sleep for an integer number of seconds.
4222 - """
4223 - with nogil:
4224 - zmq_sleep(seconds)
4225 -
4226 -
4227 -__all__ = ['Stopwatch']
4228 diff --git a/zmq/devices/__init__.py b/zmq/devices/__init__.py
4229 index b5c8eb3..dcae13d 100644
4230 --- a/zmq/devices/__init__.py
4231 +++ b/zmq/devices/__init__.py
4232 @@ -14,11 +14,12 @@
4233 #-----------------------------------------------------------------------------
4234
4235 from zmq import device
4236 -from zmq.devices import basedevice, proxydevice, monitoredqueue, monitoredqueue device
4237 +from zmq.devices import basedevice, proxydevice, monitoredqueuedevice
4238 +from zmq.devices import _zmonitoredqueue as monitoredqueue
4239
4240 from zmq.devices.basedevice import *
4241 from zmq.devices.proxydevice import *
4242 -from zmq.devices.monitoredqueue import *
4243 +from zmq.devices._zmonitoredqueue import *
4244 from zmq.devices.monitoredqueuedevice import *
4245
4246 __all__ = ['device']
4247 diff --git a/zmq/devices/_zmonitoredqueue.pxd b/zmq/devices/_zmonitoredqueue.pxd
4248 new file mode 100644
4249 index 0000000..e04354a
4250 --- /dev/null
4251 +++ b/zmq/devices/_zmonitoredqueue.pxd
4252 @@ -0,0 +1,166 @@
4253 +"""MonitoredQueue class declarations.
4254 +
4255 +Authors
4256 +-------
4257 +* MinRK
4258 +* Brian Granger
4259 +"""
4260 +
4261 +#
4262 +# Copyright (c) 2010 Min Ragan-Kelley, Brian Granger
4263 +#
4264 +# This file is part of pyzmq, but is derived and adapted from zmq_queue.cpp
4265 +# originally from libzmq-2.1.6, used under LGPLv3
4266 +#
4267 +# pyzmq is free software; you can redistribute it and/or modify it under
4268 +# the terms of the Lesser GNU General Public License as published by
4269 +# the Free Software Foundation; either version 3 of the License, or
4270 +# (at your option) any later version.
4271 +#
4272 +# pyzmq is distributed in the hope that it will be useful,
4273 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
4274 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4275 +# Lesser GNU General Public License for more details.
4276 +#
4277 +# You should have received a copy of the Lesser GNU General Public License
4278 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
4279 +#
4280 +
4281 +#-----------------------------------------------------------------------------
4282 +# Imports
4283 +#-----------------------------------------------------------------------------
4284 +
4285 +from libzmq cimport *
4286 +
4287 +#-----------------------------------------------------------------------------
4288 +# MonitoredQueue C functions
4289 +#-----------------------------------------------------------------------------
4290 +
4291 +cdef inline int _relay(void *insocket_, void *outsocket_, void *sidesocket_,
4292 + zmq_msg_t msg, zmq_msg_t side_msg, zmq_msg_t id_msg,
4293 + bint swap_ids) nogil:
4294 + cdef int rc
4295 + cdef int64_t flag_2
4296 + cdef int flag_3
4297 + cdef int flags
4298 + cdef bint more
4299 + cdef size_t flagsz
4300 + cdef void * flag_ptr
4301 +
4302 + if ZMQ_VERSION_MAJOR < 3:
4303 + flagsz = sizeof (int64_t)
4304 + flag_ptr = &flag_2
4305 + else:
4306 + flagsz = sizeof (int)
4307 + flag_ptr = &flag_3
4308 +
4309 + if swap_ids:# both router, must send second identity first
4310 + # recv two ids into msg, id_msg
4311 + rc = zmq_msg_recv(&msg, insocket_, 0)
4312 + rc = zmq_msg_recv(&id_msg, insocket_, 0)
4313 +
4314 + # send second id (id_msg) first
4315 + #!!!! always send a copy before the original !!!!
4316 + rc = zmq_msg_copy(&side_msg, &id_msg)
4317 + rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE)
4318 + rc = zmq_msg_send(&id_msg, sidesocket_, ZMQ_SNDMORE)
4319 + # send first id (msg) second
4320 + rc = zmq_msg_copy(&side_msg, &msg)
4321 + rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE)
4322 + rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE)
4323 + if rc < 0:
4324 + return rc
4325 + while (True):
4326 + rc = zmq_msg_recv(&msg, insocket_, 0)
4327 + # assert (rc == 0)
4328 + rc = zmq_getsockopt (insocket_, ZMQ_RCVMORE, flag_ptr, &flagsz)
4329 + flags = 0
4330 + if ZMQ_VERSION_MAJOR < 3:
4331 + if flag_2:
4332 + flags |= ZMQ_SNDMORE
4333 + else:
4334 + if flag_3:
4335 + flags |= ZMQ_SNDMORE
4336 + # LABEL has been removed:
4337 + # rc = zmq_getsockopt (insocket_, ZMQ_RCVLABEL, flag_ptr, &flagsz)
4338 + # if flag_3:
4339 + # flags |= ZMQ_SNDLABEL
4340 + # assert (rc == 0)
4341 +
4342 + rc = zmq_msg_copy(&side_msg, &msg)
4343 + if flags:
4344 + rc = zmq_msg_send(&side_msg, outsocket_, flags)
4345 + # only SNDMORE for side-socket
4346 + rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE)
4347 + else:
4348 + rc = zmq_msg_send(&side_msg, outsocket_, 0)
4349 + rc = zmq_msg_send(&msg, sidesocket_, 0)
4350 + break
4351 + return rc
4352 +
4353 +# the MonitoredQueue C function, adapted from zmq::queue.cpp :
4354 +cdef inline int c_monitored_queue (void *insocket_, void *outsocket_,
4355 + void *sidesocket_, zmq_msg_t *in_msg_ptr,
4356 + zmq_msg_t *out_msg_ptr, int swap_ids) nogil:
4357 + """The actual C function for a monitored queue device.
4358 +
4359 + See ``monitored_queue()`` for details.
4360 + """
4361 +
4362 + cdef zmq_msg_t msg
4363 + cdef int rc = zmq_msg_init (&msg)
4364 + cdef zmq_msg_t id_msg
4365 + rc = zmq_msg_init (&id_msg)
4366 + cdef zmq_msg_t side_msg
4367 + rc = zmq_msg_init (&side_msg)
4368 + # assert (rc == 0)
4369 +
4370 +
4371 + cdef zmq_pollitem_t items [2]
4372 + items [0].socket = insocket_
4373 + items [0].fd = 0
4374 + items [0].events = ZMQ_POLLIN
4375 + items [0].revents = 0
4376 + items [1].socket = outsocket_
4377 + items [1].fd = 0
4378 + items [1].events = ZMQ_POLLIN
4379 + items [1].revents = 0
4380 + # I don't think sidesocket should be polled?
4381 + # items [2].socket = sidesocket_
4382 + # items [2].fd = 0
4383 + # items [2].events = ZMQ_POLLIN
4384 + # items [2].revents = 0
4385 +
4386 + while (True):
4387 +
4388 + # // Wait while there are either requests or replies to process.
4389 + rc = zmq_poll (&items [0], 2, -1)
4390 + if rc < 0:
4391 + return rc
4392 + # // The algorithm below asumes ratio of request and replies processed
4393 + # // under full load to be 1:1. Although processing requests replies
4394 + # // first is tempting it is suspectible to DoS attacks (overloading
4395 + # // the system with unsolicited replies).
4396 + #
4397 + # // Process a request.
4398 + if (items [0].revents & ZMQ_POLLIN):
4399 + # send in_prefix to side socket
4400 + rc = zmq_msg_copy(&side_msg, in_msg_ptr)
4401 + rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE)
4402 + if rc < 0:
4403 + return rc
4404 + # relay the rest of the message
4405 + rc = _relay(insocket_, outsocket_, sidesocket_, msg, side_msg, id_m sg, swap_ids)
4406 + if rc < 0:
4407 + return rc
4408 + if (items [1].revents & ZMQ_POLLIN):
4409 + # send out_prefix to side socket
4410 + rc = zmq_msg_copy(&side_msg, out_msg_ptr)
4411 + rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE)
4412 + if rc < 0:
4413 + return rc
4414 + # relay the rest of the message
4415 + rc = _relay(outsocket_, insocket_, sidesocket_, msg, side_msg, id_m sg, swap_ids)
4416 + if rc < 0:
4417 + return rc
4418 + return 0
4419 diff --git a/zmq/devices/_zmonitoredqueue.pyx b/zmq/devices/_zmonitoredqueue.pyx
4420 new file mode 100644
4421 index 0000000..a74ae8e
4422 --- /dev/null
4423 +++ b/zmq/devices/_zmonitoredqueue.pyx
4424 @@ -0,0 +1,108 @@
4425 +"""MonitoredQueue classes and functions.
4426 +
4427 +Authors
4428 +-------
4429 +* MinRK
4430 +* Brian Granger
4431 +"""
4432 +
4433 +#-----------------------------------------------------------------------------
4434 +# Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley
4435 +#
4436 +# This file is part of pyzmq
4437 +#
4438 +# Distributed under the terms of the New BSD License. The full license is in
4439 +# the file COPYING.BSD, distributed as part of this software.
4440 +#-----------------------------------------------------------------------------
4441 +
4442 +#-----------------------------------------------------------------------------
4443 +# Imports
4444 +#-----------------------------------------------------------------------------
4445 +
4446 +cdef extern from "Python.h":
4447 + ctypedef int Py_ssize_t
4448 +
4449 +from libc.string cimport memcpy
4450 +
4451 +from buffers cimport asbuffer_r
4452 +from libzmq cimport *
4453 +
4454 +from zmq.core._zsocket cimport Socket
4455 +from zmq.core.checkrc cimport _check_rc
4456 +
4457 +from zmq import ROUTER, ZMQError
4458 +
4459 +#-----------------------------------------------------------------------------
4460 +# MonitoredQueue functions
4461 +#-----------------------------------------------------------------------------
4462 +
4463 +
4464 +def monitored_queue(Socket in_socket, Socket out_socket, Socket mon_socket,
4465 + bytes in_prefix=b'in', bytes out_prefix=b'out'):
4466 + """monitored_queue(in_socket, out_socket, mon_socket,
4467 + in_prefix='in', out_prefix='out')
4468 +
4469 + Start a monitored queue device.
4470 +
4471 + A monitored queue behaves just like a zmq QUEUE device as far as in_socket
4472 + and out_socket are concerned, except that all messages *also* go out on
4473 + mon_socket. mon_socket also prefixes the messages coming from each with a
4474 + prefix, by default 'in' and 'out', so all messages sent by mon_socket are
4475 + multipart.
4476 +
4477 + The only difference between this and a QUEUE as far as in/out are
4478 + concerned is that it works with two ROUTER sockets by swapping the IDENT
4479 + prefixes.
4480 +
4481 + Parameters
4482 + ----------
4483 + in_socket : Socket
4484 + One of the sockets to the Queue. Its messages will be prefixed with
4485 + 'in'.
4486 + out_socket : Socket
4487 + One of the sockets to the Queue. Its messages will be prefixed with
4488 + 'out'. The only difference between in/out socket is this prefix.
4489 + mon_socket : Socket
4490 + This socket sends out every message received by each of the others
4491 + with an in/out prefix specifying which one it was.
4492 + in_prefix : str
4493 + Prefix added to broadcast messages from in_socket.
4494 + out_prefix : str
4495 + Prefix added to broadcast messages from out_socket.
4496 + """
4497 +
4498 + cdef void *ins=in_socket.handle
4499 + cdef void *outs=out_socket.handle
4500 + cdef void *mons=mon_socket.handle
4501 + cdef zmq_msg_t in_msg
4502 + cdef zmq_msg_t out_msg
4503 + cdef bint swap_ids
4504 + cdef char *msg_c = NULL
4505 + cdef Py_ssize_t msg_c_len
4506 + cdef int rc
4507 +
4508 + # force swap_ids if both ROUTERs
4509 + swap_ids = (in_socket.socket_type == ROUTER and
4510 + out_socket.socket_type == ROUTER)
4511 +
4512 + # build zmq_msg objects from str prefixes
4513 + asbuffer_r(in_prefix, <void **>&msg_c, &msg_c_len)
4514 + with nogil:
4515 + rc = zmq_msg_init_size(&in_msg, msg_c_len)
4516 + _check_rc(rc)
4517 +
4518 + with nogil:
4519 + memcpy(zmq_msg_data(&in_msg), msg_c, zmq_msg_size(&in_msg))
4520 +
4521 + asbuffer_r(out_prefix, <void **>&msg_c, &msg_c_len)
4522 +
4523 + with nogil:
4524 + rc = zmq_msg_init_size(&out_msg, msg_c_len)
4525 + _check_rc(rc)
4526 +
4527 + with nogil:
4528 + memcpy(zmq_msg_data(&out_msg), msg_c, zmq_msg_size(&out_msg))
4529 + rc = c_monitored_queue(ins, outs, mons, &in_msg, &out_msg, swap_ids)
4530 + return rc
4531 +
4532 +__all__ = ['monitored_queue']
4533 diff --git a/zmq/devices/basedevice.py b/zmq/devices/basedevice.py
4534 index f65ba1f..4b2c42b 100644
4535 --- a/zmq/devices/basedevice.py
4536 +++ b/zmq/devices/basedevice.py
4537 @@ -20,8 +20,15 @@ Authors
4538 #-----------------------------------------------------------------------------
4539
4540 import time
4541 -from threading import Thread
4542 -from multiprocessing import Process
4543 +try:
4544 + from threading import Thread
4545 +except ImportError:
4546 + Thread = None
4547 +
4548 +try:
4549 + from multiprocessing import Process
4550 +except ImportError:
4551 + Process = None
4552
4553 from zmq import device, QUEUE, Context
4554
4555 diff --git a/zmq/devices/monitoredqueue.pxd b/zmq/devices/monitoredqueue.pxd
4556 deleted file mode 100644
4557 index e04354a..0000000
4558 --- a/zmq/devices/monitoredqueue.pxd
4559 +++ /dev/null
4560 @@ -1,166 +0,0 @@
4561 -"""MonitoredQueue class declarations.
4562 -
4563 -Authors
4564 --------
4565 -* MinRK
4566 -* Brian Granger
4567 -"""
4568 -
4569 -#
4570 -# Copyright (c) 2010 Min Ragan-Kelley, Brian Granger
4571 -#
4572 -# This file is part of pyzmq, but is derived and adapted from zmq_queue.cpp
4573 -# originally from libzmq-2.1.6, used under LGPLv3
4574 -#
4575 -# pyzmq is free software; you can redistribute it and/or modify it under
4576 -# the terms of the Lesser GNU General Public License as published by
4577 -# the Free Software Foundation; either version 3 of the License, or
4578 -# (at your option) any later version.
4579 -#
4580 -# pyzmq is distributed in the hope that it will be useful,
4581 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
4582 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4583 -# Lesser GNU General Public License for more details.
4584 -#
4585 -# You should have received a copy of the Lesser GNU General Public License
4586 -# along with this program. If not, see <http://www.gnu.org/licenses/>.
4587 -#
4588 -
4589 -#-----------------------------------------------------------------------------
4590 -# Imports
4591 -#-----------------------------------------------------------------------------
4592 -
4593 -from libzmq cimport *
4594 -
4595 -#-----------------------------------------------------------------------------
4596 -# MonitoredQueue C functions
4597 -#-----------------------------------------------------------------------------
4598 -
4599 -cdef inline int _relay(void *insocket_, void *outsocket_, void *sidesocket_,
4600 - zmq_msg_t msg, zmq_msg_t side_msg, zmq_msg_t id_msg,
4601 - bint swap_ids) nogil:
4602 - cdef int rc
4603 - cdef int64_t flag_2
4604 - cdef int flag_3
4605 - cdef int flags
4606 - cdef bint more
4607 - cdef size_t flagsz
4608 - cdef void * flag_ptr
4609 -
4610 - if ZMQ_VERSION_MAJOR < 3:
4611 - flagsz = sizeof (int64_t)
4612 - flag_ptr = &flag_2
4613 - else:
4614 - flagsz = sizeof (int)
4615 - flag_ptr = &flag_3
4616 -
4617 - if swap_ids:# both router, must send second identity first
4618 - # recv two ids into msg, id_msg
4619 - rc = zmq_msg_recv(&msg, insocket_, 0)
4620 - rc = zmq_msg_recv(&id_msg, insocket_, 0)
4621 -
4622 - # send second id (id_msg) first
4623 - #!!!! always send a copy before the original !!!!
4624 - rc = zmq_msg_copy(&side_msg, &id_msg)
4625 - rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE)
4626 - rc = zmq_msg_send(&id_msg, sidesocket_, ZMQ_SNDMORE)
4627 - # send first id (msg) second
4628 - rc = zmq_msg_copy(&side_msg, &msg)
4629 - rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE)
4630 - rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE)
4631 - if rc < 0:
4632 - return rc
4633 - while (True):
4634 - rc = zmq_msg_recv(&msg, insocket_, 0)
4635 - # assert (rc == 0)
4636 - rc = zmq_getsockopt (insocket_, ZMQ_RCVMORE, flag_ptr, &flagsz)
4637 - flags = 0
4638 - if ZMQ_VERSION_MAJOR < 3:
4639 - if flag_2:
4640 - flags |= ZMQ_SNDMORE
4641 - else:
4642 - if flag_3:
4643 - flags |= ZMQ_SNDMORE
4644 - # LABEL has been removed:
4645 - # rc = zmq_getsockopt (insocket_, ZMQ_RCVLABEL, flag_ptr, &flagsz)
4646 - # if flag_3:
4647 - # flags |= ZMQ_SNDLABEL
4648 - # assert (rc == 0)
4649 -
4650 - rc = zmq_msg_copy(&side_msg, &msg)
4651 - if flags:
4652 - rc = zmq_msg_send(&side_msg, outsocket_, flags)
4653 - # only SNDMORE for side-socket
4654 - rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE)
4655 - else:
4656 - rc = zmq_msg_send(&side_msg, outsocket_, 0)
4657 - rc = zmq_msg_send(&msg, sidesocket_, 0)
4658 - break
4659 - return rc
4660 -
4661 -# the MonitoredQueue C function, adapted from zmq::queue.cpp :
4662 -cdef inline int c_monitored_queue (void *insocket_, void *outsocket_,
4663 - void *sidesocket_, zmq_msg_t *in_msg_ptr,
4664 - zmq_msg_t *out_msg_ptr, int swap_ids) nogil:
4665 - """The actual C function for a monitored queue device.
4666 -
4667 - See ``monitored_queue()`` for details.
4668 - """
4669 -
4670 - cdef zmq_msg_t msg
4671 - cdef int rc = zmq_msg_init (&msg)
4672 - cdef zmq_msg_t id_msg
4673 - rc = zmq_msg_init (&id_msg)
4674 - cdef zmq_msg_t side_msg
4675 - rc = zmq_msg_init (&side_msg)
4676 - # assert (rc == 0)
4677 -
4678 -
4679 - cdef zmq_pollitem_t items [2]
4680 - items [0].socket = insocket_
4681 - items [0].fd = 0
4682 - items [0].events = ZMQ_POLLIN
4683 - items [0].revents = 0
4684 - items [1].socket = outsocket_
4685 - items [1].fd = 0
4686 - items [1].events = ZMQ_POLLIN
4687 - items [1].revents = 0
4688 - # I don't think sidesocket should be polled?
4689 - # items [2].socket = sidesocket_
4690 - # items [2].fd = 0
4691 - # items [2].events = ZMQ_POLLIN
4692 - # items [2].revents = 0
4693 -
4694 - while (True):
4695 -
4696 - # // Wait while there are either requests or replies to process.
4697 - rc = zmq_poll (&items [0], 2, -1)
4698 - if rc < 0:
4699 - return rc
4700 - # // The algorithm below asumes ratio of request and replies processed
4701 - # // under full load to be 1:1. Although processing requests replies
4702 - # // first is tempting it is suspectible to DoS attacks (overloading
4703 - # // the system with unsolicited replies).
4704 - #
4705 - # // Process a request.
4706 - if (items [0].revents & ZMQ_POLLIN):
4707 - # send in_prefix to side socket
4708 - rc = zmq_msg_copy(&side_msg, in_msg_ptr)
4709 - rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE)
4710 - if rc < 0:
4711 - return rc
4712 - # relay the rest of the message
4713 - rc = _relay(insocket_, outsocket_, sidesocket_, msg, side_msg, id_m sg, swap_ids)
4714 - if rc < 0:
4715 - return rc
4716 - if (items [1].revents & ZMQ_POLLIN):
4717 - # send out_prefix to side socket
4718 - rc = zmq_msg_copy(&side_msg, out_msg_ptr)
4719 - rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE)
4720 - if rc < 0:
4721 - return rc
4722 - # relay the rest of the message
4723 - rc = _relay(outsocket_, insocket_, sidesocket_, msg, side_msg, id_m sg, swap_ids)
4724 - if rc < 0:
4725 - return rc
4726 - return 0
4727 diff --git a/zmq/devices/monitoredqueue.pyx b/zmq/devices/monitoredqueue.pyx
4728 deleted file mode 100644
4729 index 65db882..0000000
4730 --- a/zmq/devices/monitoredqueue.pyx
4731 +++ /dev/null
4732 @@ -1,108 +0,0 @@
4733 -"""MonitoredQueue classes and functions.
4734 -
4735 -Authors
4736 --------
4737 -* MinRK
4738 -* Brian Granger
4739 -"""
4740 -
4741 -#-----------------------------------------------------------------------------
4742 -# Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley
4743 -#
4744 -# This file is part of pyzmq
4745 -#
4746 -# Distributed under the terms of the New BSD License. The full license is in
4747 -# the file COPYING.BSD, distributed as part of this software.
4748 -#-----------------------------------------------------------------------------
4749 -
4750 -#-----------------------------------------------------------------------------
4751 -# Imports
4752 -#-----------------------------------------------------------------------------
4753 -
4754 -cdef extern from "Python.h":
4755 - ctypedef int Py_ssize_t
4756 -
4757 -from libc.string cimport memcpy
4758 -
4759 -from buffers cimport asbuffer_r
4760 -from libzmq cimport *
4761 -
4762 -from zmq.core.socket cimport Socket
4763 -from zmq.core.checkrc cimport _check_rc
4764 -
4765 -from zmq import ROUTER, ZMQError
4766 -
4767 -#-----------------------------------------------------------------------------
4768 -# MonitoredQueue functions
4769 -#-----------------------------------------------------------------------------
4770 -
4771 -
4772 -def monitored_queue(Socket in_socket, Socket out_socket, Socket mon_socket,
4773 - bytes in_prefix=b'in', bytes out_prefix=b'out'):
4774 - """monitored_queue(in_socket, out_socket, mon_socket,
4775 - in_prefix='in', out_prefix='out')
4776 -
4777 - Start a monitored queue device.
4778 -
4779 - A monitored queue behaves just like a zmq QUEUE device as far as in_socket
4780 - and out_socket are concerned, except that all messages *also* go out on
4781 - mon_socket. mon_socket also prefixes the messages coming from each with a
4782 - prefix, by default 'in' and 'out', so all messages sent by mon_socket are
4783 - multipart.
4784 -
4785 - The only difference between this and a QUEUE as far as in/out are
4786 - concerned is that it works with two ROUTER sockets by swapping the IDENT
4787 - prefixes.
4788 -
4789 - Parameters
4790 - ----------
4791 - in_socket : Socket
4792 - One of the sockets to the Queue. Its messages will be prefixed with
4793 - 'in'.
4794 - out_socket : Socket
4795 - One of the sockets to the Queue. Its messages will be prefixed with
4796 - 'out'. The only difference between in/out socket is this prefix.
4797 - mon_socket : Socket
4798 - This socket sends out every message received by each of the others
4799 - with an in/out prefix specifying which one it was.
4800 - in_prefix : str
4801 - Prefix added to broadcast messages from in_socket.
4802 - out_prefix : str
4803 - Prefix added to broadcast messages from out_socket.
4804 - """
4805 -
4806 - cdef void *ins=in_socket.handle
4807 - cdef void *outs=out_socket.handle
4808 - cdef void *mons=mon_socket.handle
4809 - cdef zmq_msg_t in_msg
4810 - cdef zmq_msg_t out_msg
4811 - cdef bint swap_ids
4812 - cdef char *msg_c = NULL
4813 - cdef Py_ssize_t msg_c_len
4814 - cdef int rc
4815 -
4816 - # force swap_ids if both ROUTERs
4817 - swap_ids = (in_socket.socket_type == ROUTER and
4818 - out_socket.socket_type == ROUTER)
4819 -
4820 - # build zmq_msg objects from str prefixes
4821 - asbuffer_r(in_prefix, <void **>&msg_c, &msg_c_len)
4822 - with nogil:
4823 - rc = zmq_msg_init_size(&in_msg, msg_c_len)
4824 - _check_rc(rc)
4825 -
4826 - with nogil:
4827 - memcpy(zmq_msg_data(&in_msg), msg_c, zmq_msg_size(&in_msg))
4828 -
4829 - asbuffer_r(out_prefix, <void **>&msg_c, &msg_c_len)
4830 -
4831 - with nogil:
4832 - rc = zmq_msg_init_size(&out_msg, msg_c_len)
4833 - _check_rc(rc)
4834 -
4835 - with nogil:
4836 - memcpy(zmq_msg_data(&out_msg), msg_c, zmq_msg_size(&out_msg))
4837 - rc = c_monitored_queue(ins, outs, mons, &in_msg, &out_msg, swap_ids)
4838 - return rc
4839 -
4840 -__all__ = ['monitored_queue']
4841 diff --git a/zmq/devices/monitoredqueuedevice.py b/zmq/devices/monitoredqueuedev ice.py
4842 index a9f5c3f..422715c 100644
4843 --- a/zmq/devices/monitoredqueuedevice.py
4844 +++ b/zmq/devices/monitoredqueuedevice.py
4845 @@ -24,7 +24,7 @@ import time
4846
4847 from zmq import ZMQError, PUB
4848 from zmq.devices.proxydevice import ProxyBase, Proxy, ThreadProxy, ProcessProxy
4849 -from zmq.devices.monitoredqueue import monitored_queue
4850 +from zmq.devices._zmonitoredqueue import monitored_queue
4851
4852 #-----------------------------------------------------------------------------
4853 # Classes
4854 diff --git a/zmq/sugar/backend.py b/zmq/sugar/backend.py
4855 index ad07379..6f87c1b 100644
4856 --- a/zmq/sugar/backend.py
4857 +++ b/zmq/sugar/backend.py
4858 @@ -23,8 +23,9 @@ try:
4859 strerror, zmq_errno,
4860 zmq_poll,
4861 zmq_version_info,
4862 - constants,
4863 + _zconstants,
4864 )
4865 + constants = _zconstants
4866 except ImportError:
4867 from zmq.cffi_core import (
4868 Context,
4869 diff --git a/zmq/sugar/context.py b/zmq/sugar/context.py
4870 index bcc4686..f0f3325 100644
4871 --- a/zmq/sugar/context.py
4872 +++ b/zmq/sugar/context.py
4873 @@ -128,4 +128,4 @@ class Context(ContextBase, AttributeSetter):
4874 else:
4875 del self.sockopts[opt]
4876
4877 -__all__ = ['Context']
4878 \ No newline at end of file
4879 +__all__ = ['Context']
4880 diff --git a/zmq/utils/_zinitthreads.pyx b/zmq/utils/_zinitthreads.pyx
4881 new file mode 100644
4882 index 0000000..6c57c9f
4883 --- /dev/null
4884 +++ b/zmq/utils/_zinitthreads.pyx
4885 @@ -0,0 +1,23 @@
4886 +"""Utility to initialize threads."""
4887 +
4888 +#-----------------------------------------------------------------------------
4889 +# Copyright (c) 2010 Brian Granger, Min Ragan-Kelley
4890 +#
4891 +# Distributed under the terms of the New BSD License. The full license is in
4892 +# the file COPYING.BSD, distributed as part of this software.
4893 +#-----------------------------------------------------------------------------
4894 +
4895 +#-----------------------------------------------------------------------------
4896 +# Imports
4897 +#-----------------------------------------------------------------------------
4898 +
4899 +cdef extern from "Python.h":
4900 + cdef void PyEval_InitThreads()
4901 +
4902 +# It seems that in only *some* version of Python/Cython we need to call this
4903 +# by hand to get threads initialized. Not clear why this is the case though.
4904 +# If we don't have this, pyzmq will segfault.
4905 +def init_threads():
4906 + PyEval_InitThreads()
4907 +
4908 +__all__ = ['init_threads']
4909 diff --git a/zmq/utils/_zrebuffer.pyx b/zmq/utils/_zrebuffer.pyx
4910 new file mode 100644
4911 index 0000000..ca240d3
4912 --- /dev/null
4913 +++ b/zmq/utils/_zrebuffer.pyx
4914 @@ -0,0 +1,104 @@
4915 +"""
4916 +Utility for changing itemsize of memoryviews, and getting
4917 +numpy arrays from byte-arrays that should be interpreted with a different
4918 +itemsize.
4919 +
4920 +Authors
4921 +-------
4922 +* MinRK
4923 +"""
4924 +
4925 +#-----------------------------------------------------------------------------
4926 +# Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley
4927 +#
4928 +# This file is part of pyzmq
4929 +#
4930 +# Distributed under the terms of the New BSD License. The full license is in
4931 +# the file COPYING.BSD, distributed as part of this software.
4932 +#-----------------------------------------------------------------------------
4933 +
4934 +from libc.stdlib cimport malloc
4935 +from buffers cimport *
4936 +
4937 +cdef inline object _rebuffer(object obj, char * format, int itemsize):
4938 + """clobber the format & itemsize of a 1-D
4939 +
4940 + This is the Python 3 model, but will work on Python >= 2.6. Currently,
4941 + we use it only on >= 3.0.
4942 + """
4943 + cdef Py_buffer view
4944 + cdef int flags = PyBUF_SIMPLE
4945 + cdef int mode = 0
4946 + # cdef Py_ssize_t *shape, *strides, *suboffsets
4947 +
4948 + mode = check_buffer(obj)
4949 + if mode == 0:
4950 + raise TypeError("%r does not provide a buffer interface."%obj)
4951 +
4952 + if mode == 3:
4953 + flags = PyBUF_ANY_CONTIGUOUS
4954 + if format:
4955 + flags |= PyBUF_FORMAT
4956 + PyObject_GetBuffer(obj, &view, flags)
4957 + assert view.ndim <= 1, "Can only reinterpret 1-D memoryviews"
4958 + assert view.len % itemsize == 0, "Buffer of length %i not divisible int o items of size %i"%(view.len, itemsize)
4959 + # hack the format
4960 + view.ndim = 1
4961 + view.format = format
4962 + view.itemsize = itemsize
4963 + view.strides = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
4964 + view.strides[0] = itemsize
4965 + view.shape = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
4966 + view.shape[0] = view.len/itemsize
4967 + view.suboffsets = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
4968 + view.suboffsets[0] = 0
4969 + # for debug: make buffer writable, for zero-copy testing
4970 + # view.readonly = 0
4971 +
4972 + return PyMemoryView_FromBuffer(&view)
4973 + else:
4974 + raise TypeError("This funciton is only for new-style buffer objects.")
4975 +
4976 +def rebuffer(obj, format, itemsize):
4977 + """Change the itemsize of a memoryview.
4978 +
4979 + Only for 1D contiguous buffers.
4980 + """
4981 + return _rebuffer(obj, format, itemsize)
4982 +
4983 +def array_from_buffer(view, dtype, shape):
4984 + """Get a numpy array from a memoryview, regardless of the itemsize of the o riginal
4985 + memoryview. This is important, because pyzmq does not send memoryview shap e data
4986 + over the wire, so we need to change the memoryview itemsize before calling
4987 + asarray.
4988 + """
4989 + import numpy
4990 + A = numpy.array([],dtype=dtype)
4991 + ref = viewfromobject(A,0)
4992 + fmt = ref.format.encode()
4993 + buf = viewfromobject(view, 0)
4994 + buf = _rebuffer(view, fmt, ref.itemsize)
4995 + return numpy.asarray(buf, dtype=dtype).reshape(shape)
4996 +
4997 +def print_view_info(obj):
4998 + """simple utility for printing info on a new-style buffer object"""
4999 + cdef Py_buffer view
5000 + cdef int flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT
5001 + cdef int mode = 0
5002 +
5003 + mode = check_buffer(obj)
5004 + if mode == 0:
5005 + raise TypeError("%r does not provide a buffer interface."%obj)
5006 +
5007 + if mode == 3:
5008 + PyObject_GetBuffer(obj, &view, flags)
5009 + print <Py_ssize_t>view.buf, view.len, view.format, view.ndim,
5010 + if view.ndim:
5011 + if view.shape:
5012 + print view.shape[0],
5013 + if view.strides:
5014 + print view.strides[0],
5015 + if view.suboffsets:
5016 + print view.suboffsets[0],
5017 + print
5018 +
5019 \ No newline at end of file
5020 diff --git a/zmq/utils/initthreads.pyx b/zmq/utils/initthreads.pyx
5021 deleted file mode 100644
5022 index 6c57c9f..0000000
5023 --- a/zmq/utils/initthreads.pyx
5024 +++ /dev/null
5025 @@ -1,23 +0,0 @@
5026 -"""Utility to initialize threads."""
5027 -
5028 -#-----------------------------------------------------------------------------
5029 -# Copyright (c) 2010 Brian Granger, Min Ragan-Kelley
5030 -#
5031 -# Distributed under the terms of the New BSD License. The full license is in
5032 -# the file COPYING.BSD, distributed as part of this software.
5033 -#-----------------------------------------------------------------------------
5034 -
5035 -#-----------------------------------------------------------------------------
5036 -# Imports
5037 -#-----------------------------------------------------------------------------
5038 -
5039 -cdef extern from "Python.h":
5040 - cdef void PyEval_InitThreads()
5041 -
5042 -# It seems that in only *some* version of Python/Cython we need to call this
5043 -# by hand to get threads initialized. Not clear why this is the case though.
5044 -# If we don't have this, pyzmq will segfault.
5045 -def init_threads():
5046 - PyEval_InitThreads()
5047 -
5048 -__all__ = ['init_threads']
5049 diff --git a/zmq/utils/rebuffer.pyx b/zmq/utils/rebuffer.pyx
5050 deleted file mode 100644
5051 index ca240d3..0000000
5052 --- a/zmq/utils/rebuffer.pyx
5053 +++ /dev/null
5054 @@ -1,104 +0,0 @@
5055 -"""
5056 -Utility for changing itemsize of memoryviews, and getting
5057 -numpy arrays from byte-arrays that should be interpreted with a different
5058 -itemsize.
5059 -
5060 -Authors
5061 --------
5062 -* MinRK
5063 -"""
5064 -
5065 -#-----------------------------------------------------------------------------
5066 -# Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley
5067 -#
5068 -# This file is part of pyzmq
5069 -#
5070 -# Distributed under the terms of the New BSD License. The full license is in
5071 -# the file COPYING.BSD, distributed as part of this software.
5072 -#-----------------------------------------------------------------------------
5073 -
5074 -from libc.stdlib cimport malloc
5075 -from buffers cimport *
5076 -
5077 -cdef inline object _rebuffer(object obj, char * format, int itemsize):
5078 - """clobber the format & itemsize of a 1-D
5079 -
5080 - This is the Python 3 model, but will work on Python >= 2.6. Currently,
5081 - we use it only on >= 3.0.
5082 - """
5083 - cdef Py_buffer view
5084 - cdef int flags = PyBUF_SIMPLE
5085 - cdef int mode = 0
5086 - # cdef Py_ssize_t *shape, *strides, *suboffsets
5087 -
5088 - mode = check_buffer(obj)
5089 - if mode == 0:
5090 - raise TypeError("%r does not provide a buffer interface."%obj)
5091 -
5092 - if mode == 3:
5093 - flags = PyBUF_ANY_CONTIGUOUS
5094 - if format:
5095 - flags |= PyBUF_FORMAT
5096 - PyObject_GetBuffer(obj, &view, flags)
5097 - assert view.ndim <= 1, "Can only reinterpret 1-D memoryviews"
5098 - assert view.len % itemsize == 0, "Buffer of length %i not divisible int o items of size %i"%(view.len, itemsize)
5099 - # hack the format
5100 - view.ndim = 1
5101 - view.format = format
5102 - view.itemsize = itemsize
5103 - view.strides = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
5104 - view.strides[0] = itemsize
5105 - view.shape = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
5106 - view.shape[0] = view.len/itemsize
5107 - view.suboffsets = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
5108 - view.suboffsets[0] = 0
5109 - # for debug: make buffer writable, for zero-copy testing
5110 - # view.readonly = 0
5111 -
5112 - return PyMemoryView_FromBuffer(&view)
5113 - else:
5114 - raise TypeError("This funciton is only for new-style buffer objects.")
5115 -
5116 -def rebuffer(obj, format, itemsize):
5117 - """Change the itemsize of a memoryview.
5118 -
5119 - Only for 1D contiguous buffers.
5120 - """
5121 - return _rebuffer(obj, format, itemsize)
5122 -
5123 -def array_from_buffer(view, dtype, shape):
5124 - """Get a numpy array from a memoryview, regardless of the itemsize of the o riginal
5125 - memoryview. This is important, because pyzmq does not send memoryview shap e data
5126 - over the wire, so we need to change the memoryview itemsize before calling
5127 - asarray.
5128 - """
5129 - import numpy
5130 - A = numpy.array([],dtype=dtype)
5131 - ref = viewfromobject(A,0)
5132 - fmt = ref.format.encode()
5133 - buf = viewfromobject(view, 0)
5134 - buf = _rebuffer(view, fmt, ref.itemsize)
5135 - return numpy.asarray(buf, dtype=dtype).reshape(shape)
5136 -
5137 -def print_view_info(obj):
5138 - """simple utility for printing info on a new-style buffer object"""
5139 - cdef Py_buffer view
5140 - cdef int flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT
5141 - cdef int mode = 0
5142 -
5143 - mode = check_buffer(obj)
5144 - if mode == 0:
5145 - raise TypeError("%r does not provide a buffer interface."%obj)
5146 -
5147 - if mode == 3:
5148 - PyObject_GetBuffer(obj, &view, flags)
5149 - print <Py_ssize_t>view.buf, view.len, view.format, view.ndim,
5150 - if view.ndim:
5151 - if view.shape:
5152 - print view.shape[0],
5153 - if view.strides:
5154 - print view.strides[0],
5155 - if view.suboffsets:
5156 - print view.suboffsets[0],
5157 - print
5158 -
5159 \ No newline at end of file
OLDNEW
« no previous file with comments | « ports/python_modules/pyzmq/modules.list ('k') | ports/python_modules/pyzmq/pkg_info » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698