Commit 4b082179 authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 2.1.10

parent 1b30b35a
*.pyc
*.c
build
dist
conf
*.egg-info
*.so
*.pyd
*.dll
docs/source/api/generated
docs/gh-pages
setup.cfg
MANIFEST
include COPYING.LESSER
include README.rst
include setup.cfg.template
include setup.py
include setupegg.py
include zmqversion.py
include buildutils.py
graft docs
prune docs/build
prune docs/gh-pages
graft examples
graft zmq
graft perf
exclude setup.cfg
exclude zmq/libzmq*
# exclude docs/_static
# exclude docs/_templates
global-exclude *.so
global-exclude *.pyd
global-exclude *.pyc
global-exclude .git*
global-exclude .DS_Store
Metadata-Version: 1.0
Name: pyzmq
Version: 2.1.10
Summary: Python bindings for 0MQ.
Home-page: http://github.com/zeromq/pyzmq
Author: Brian E. Granger, Min Ragan-Kelley
Author-email: zeromq-dev@lists.zeromq.org
License: LGPL
Download-URL: http://github.com/zeromq/pyzmq/downloads
Description:
PyZMQ is a lightweight and super-fast messaging library built on top of
the ZeroMQ library (http://www.zeromq.org).
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Topic :: System :: Networking
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
...@@ -8,7 +8,7 @@ This package contains Python bindings for `ØMQ <http://www.zeromq.org>`_. ...@@ -8,7 +8,7 @@ This package contains Python bindings for `ØMQ <http://www.zeromq.org>`_.
Versioning Versioning
========== ==========
Current release of pyzmq is 2.1.9, and targets libzmq-2.1.9. For libzmq Current release of pyzmq is 2.1.10, and targets libzmq-2.1.10. For libzmq
2.0.x, use pyzmq release 2.0.10.1 or the 2.0.x development branch. 2.0.x, use pyzmq release 2.0.10.1 or the 2.0.x development branch.
PyZMQ versioning follows libzmq versioning. In general, your pyzmq version should be the same PyZMQ versioning follows libzmq versioning. In general, your pyzmq version should be the same
...@@ -20,10 +20,12 @@ intend to support libzmq >= 2.1.4 (the first 'stable' 2.1 release) for pyzmq 2.1 ...@@ -20,10 +20,12 @@ intend to support libzmq >= 2.1.4 (the first 'stable' 2.1 release) for pyzmq 2.1
--------------- ---------------
As of 2.1.7, we have experimental support for the 3.0 API of libzmq, As of 2.1.7, we have experimental support for the 3.0 API of libzmq,
developed at https://github.com/zeromq/libzmq. No code to change, no flags to pass, just developed at https://github.com/zeromq/zeromq3-0. No code to change, no flags to pass, just
build pyzmq against libzmq 3 and it should work. The pyzmq API has not changed. build pyzmq against libzmq 3 and it should work. The pyzmq API has not changed, though
some syntax has been added to support new features, such as the LABEL routing prefix in 3.0.
2.1.9 adds support for the changes in ØMQ-4.0 dev, at time of release. 2.1.9 adds support for the changes in the experimental 4.0 development branch at
https://github.com/zeromq/libzmq.
Documentation Documentation
...@@ -51,7 +53,7 @@ Eggs and MSIs ...@@ -51,7 +53,7 @@ Eggs and MSIs
------------- -------------
We have binary installers for various Pythons on OSX and Windows, so you should be able to We have binary installers for various Pythons on OSX and Windows, so you should be able to
just ``easy_install pyzmq`` in many situations. These eggs *include libzmq-2.1.9*, so they should just ``easy_install pyzmq`` in many situations. These eggs *include matching libzmq*, so they should
be the only thing you need to start using pyzmq, but we simply don't have the experience to know be the only thing you need to start using pyzmq, but we simply don't have the experience to know
when and where these installers will not work. when and where these installers will not work.
...@@ -59,9 +61,14 @@ If a binary installer fails for you, please `tell us <https://github.com/zeromq/ ...@@ -59,9 +61,14 @@ If a binary installer fails for you, please `tell us <https://github.com/zeromq/
about your system and the failure, so that we can try to fix it in later releases, and fall back about your system and the failure, so that we can try to fix it in later releases, and fall back
on building from source. on building from source.
Eggs are on PyPI, and we have them for 'current' Pythons, which are for OSX 10.6: Eggs are on `PyPI <http://pypi.python.org/pypi/pyzmq>`_, and we have them for 'current' Pythons,
which are for OSX 10.7:
* Python 2.6, 2.7, 3.2 (32b and 64b intel) * Python 2.7, 3.2 (32b+64b intel)
and OSX 10.6:
* Python 2.6 (32b+64b intel)
and Windows (x86 and x64): and Windows (x86 and x64):
...@@ -76,9 +83,12 @@ Our build scripts are much improved as of 2.1.4, so if you would like to contrib ...@@ -76,9 +83,12 @@ Our build scripts are much improved as of 2.1.4, so if you would like to contrib
Windows installers, or have any improvements on existing releases, they would be much Windows installers, or have any improvements on existing releases, they would be much
appreciated. Simply ``python setup.py bdist_msi`` or ``python setupegg.py bdist_egg`` *should* appreciated. Simply ``python setup.py bdist_msi`` or ``python setupegg.py bdist_egg`` *should*
work, once you have a libzmq and Python. We simply don't have the VMs or time in which to cover work, once you have a libzmq and Python. We simply don't have the VMs or time in which to cover
all the bases ourselves. Sometimes libzmq.so/dll/dylib doesn't get included unless ``build`` all the bases ourselves.
is specified *also*, e.g. ``python setupegg.py build bdist_egg``, but this doesn't always
seem to be true. .. note::
Sometimes libzmq.so/dll/dylib doesn't get included unless ``build`` is
specified *also*, e.g. ``python setupegg.py build bdist_egg``, but this
doesn't always seem to be true.
General General
------- -------
...@@ -94,11 +104,11 @@ or the zmq install directory on OSX/Linux: ...@@ -94,11 +104,11 @@ or the zmq install directory on OSX/Linux:
$ python setup.py configure --zmq=/usr/local $ python setup.py configure --zmq=/usr/local
The argument should be a directory containing a ``lib`` and a ``include`` directory, containing The argument should be a directory containing ``lib`` and ``include`` directories, with
``libzmq`` and ``zmq.h`` respectively. For instance (on Windows), if you have downloaded pyzmq ``libzmq`` and ``zmq.h`` respectively. For instance (on Windows), if you have downloaded pyzmq
and current libzmq into the same parent directory, this would be: and current libzmq into the same parent directory, this would be:
$ python setup.py configure --zmq=../zeromq-2.1.9 $ python setup.py configure --zmq=../zeromq-2.1.10
Second, run this command:: Second, run this command::
...@@ -229,6 +239,7 @@ The following people have contributed to the project: ...@@ -229,6 +239,7 @@ The following people have contributed to the project:
* Eugene Chernyshov (chernyshov DOT eugene AT gmail DOT com) * Eugene Chernyshov (chernyshov DOT eugene AT gmail DOT com)
* Douglas Creager (dcreager AT dcreager DOT net) * Douglas Creager (dcreager AT dcreager DOT net)
* Craig Austin (craig DOT austin AT gmail DOT com)
* Andrew Gwozdziewycz (git AT apgwoz DOT com) * Andrew Gwozdziewycz (git AT apgwoz DOT com)
* Baptiste Lepilleur (baptiste DOT lepilleur AT gmail DOT com) * Baptiste Lepilleur (baptiste DOT lepilleur AT gmail DOT com)
......
...@@ -9,9 +9,32 @@ Changes in PyZMQ ...@@ -9,9 +9,32 @@ Changes in PyZMQ
This is a coarse summary of changes in pyzmq versions. For a real changelog, consult the This is a coarse summary of changes in pyzmq versions. For a real changelog, consult the
`git log <https://github.com/zeromq/pyzmq/commits>`_ `git log <https://github.com/zeromq/pyzmq/commits>`_
2.1.10
======
2.1.9 (dev) * Add support for libzmq-3.0 LABEL prefixes:
===========
* send a message with label-prefix with:
.. sourcecode:: python
send_multipart([b'msg', b'parts'], prefix=[b'label', b'prefix'])
* :meth:`recv_multipart` returns a tuple of ``(prefix,msg)`` if a label prefix is detected
* ZMQStreams and devices also respect the LABEL prefix
* add czmq-style close&term as :meth:`ctx.destroy`, so that :meth:`ctx.term`
remains threadsafe and 1:1 with libzmq.
* :meth:`Socket.close` takes optional linger option, for setting linger prior
to closing.
* add :func:`~zmq.core.version.zmq_version_info` and
:func:`~zmq.core.version.pyzmq_version_info` for getting libzmq and pyzmq versions as
tuples of numbers. This helps with the fact that version string comparison breaks down
once versions get into double-digits.
* ioloop changes merged from upstream `Tornado <http://www.tornadoweb.org>`_ 2.1
2.1.9
=====
* added zmq.ssh tools for tunneling socket connections, copied from IPython * added zmq.ssh tools for tunneling socket connections, copied from IPython
* Expanded sockopt support to cover changes in libzmq-4.0 dev. * Expanded sockopt support to cover changes in libzmq-4.0 dev.
......
...@@ -13,8 +13,9 @@ PyZMQ Documentation ...@@ -13,8 +13,9 @@ PyZMQ Documentation
.. Note:: .. Note::
PyZMQ versioning follows zeromq, so your pyzmq version should match that of your PyZMQ versioning follows zeromq, so your pyzmq version should match that of your
zeromq. The only changes at the pyzmq user's level are the addition of a few socket zeromq. Building the same pyzmq against various versions of zeromq should only result
types and socket options. in the addition/removal of a few socket types and socket options, depending on
the active zeromq's support.
PyZMQ is the Python bindings for ØMQ_, written almost entirely in Cython_. This PyZMQ is the Python bindings for ØMQ_, written almost entirely in Cython_. This
...@@ -27,6 +28,7 @@ an overview of what the ØMQ API looks like in Python. For information on how to ...@@ -27,6 +28,7 @@ an overview of what the ØMQ API looks like in Python. For information on how to
As of PyZMQ 2.1.7, PyZMQ has experimental support for the libzmq-3.0 development version, As of PyZMQ 2.1.7, PyZMQ has experimental support for the libzmq-3.0 development version,
and has dropped support for the zeromq-2.0 series. and has dropped support for the zeromq-2.0 series.
Please don't hesitate to report pyzmq issues to our tracker_ on GitHub. Please don't hesitate to report pyzmq issues to our tracker_ on GitHub.
:ref:`Summary of Changes in PyZMQ <changelog>` :ref:`Summary of Changes in PyZMQ <changelog>`
......
import re,time
import sys
from subprocess import Popen,PIPE
from local_lat import main as local_lat
from local_thr import main as local_thr
from remote_lat import main as remote_lat
from remote_thr import main as remote_thr
def run_thr(args):
local = Popen('python local_thr.py'.split()+args,stdout=PIPE,stdin=PIPE)
remote = Popen('python remote_thr.py'.split()+args,stdout=PIPE,stdin=PIPE)
remote.wait()
local.wait()
out,_ = local.communicate()
lines = out.splitlines()
result = lines[-1]
throughput = re.findall(r'[0-9\.]+',result)[0]
return float(throughput)
def run_lat(args):
local = Popen('python local_lat.py'.split()+args,stdout=PIPE,stdin=PIPE)
remote = Popen('python remote_lat.py'.split()+args,stdout=PIPE,stdin=PIPE)
line = ''
while 'latency' not in line:
line = remote.stdout.readline()
if 'latency' in line:
latency = re.findall(r'[0-9\.]+',line)[0]
remote.wait()
local.wait()
return float(latency)
def multi_lat(args, n=3):
lats = [ run_lat(args) for i in xrange(3) ]
avg = sum(lats) / len(lats)
return avg,min(lats),max(lats)
def multi_thr(args, n=3):
thrs = [ run_thr(args) for i in xrange(3) ]
avg = sum(thrs) / len(thrs)
return avg,min(thrs),max(thrs)
def generate_vs_msg_size(nmsgs, msg_sizes=[2**p for p in range(6,21)], samples=5):
print nmsgs
x = msg_sizes
thr = []
lat = []
for msg_size in msg_sizes:
args = ('tcp://127.0.0.1:12345 %i %i'%(msg_size, nmsgs)).split()
thr.append(multi_thr(args,samples))
print 'thr: %i %s'%(msg_size, thr[-1])
lat.append(multi_lat(args,samples))
print 'lat: %i %s'%(msg_size, lat[-1])
return x,thr,lat
def generate_vs_nmsgs(msg_size, nmsgs_s=[2**p for p in range(4,14)], samples=5):
print msg_size
x = nmsgs_s
thr = []
lat = []
for nmsgs in nmsgs_s:
args = ('tcp://127.0.0.1:12345 %i %i'%(msg_size, nmsgs)).split()
thr.append(multi_thr(args,samples))
print 'thr: %i %s'%(nmsgs, thr[-1])
lat.append(multi_lat(args,samples))
print 'lat: %i %s'%(nmsgs, lat[-1])
return x,thr,lat
def do_plot(x,thr,lat, ref=1024, vs='nmsgs'):
import pylab
pylab.figure()
if vs == 'msg_size':
title = "%i msgs"%ref
xlabel = "msg size (B)"
else:
title = "msg size = %i B"%ref
xlabel = "nmsgs"
pylab.grid(True, which='major')
# pylab.grid(True, which='minor')
pylab.title(title)
pylab.xlabel(xlabel)
t_a,t_min,t_max = zip(*thr)
pylab.loglog(x,t_a,'b',label='throughput')
pylab.loglog(x,t_min,'b:')
pylab.loglog(x,t_max,'b:')
pylab.ylabel("Mb/s")
pylab.legend(loc='upper left')
ax2 = pylab.twinx()
l_a,l_min,l_max = zip(*lat)
pylab.loglog(x,l_a,'g',label='latency')
pylab.loglog(x,l_min,'g:')
pylab.loglog(x,l_max,'g:')
pylab.ylabel("msec")
pylab.legend(loc='upper right')
...@@ -501,7 +501,7 @@ monqueue = pxd('devices', 'monitoredqueue') ...@@ -501,7 +501,7 @@ monqueue = pxd('devices', 'monitoredqueue')
submodules = dict( submodules = dict(
core = {'constants': [libzmq], core = {'constants': [libzmq],
'error':[libzmq], 'error':[libzmq],
'poll':[libzmq, socket], 'poll':[libzmq, socket, context],
'stopwatch':[libzmq, pxd('core','stopwatch')], 'stopwatch':[libzmq, pxd('core','stopwatch')],
'context':[context, libzmq], 'context':[context, libzmq],
'message':[libzmq, buffers, message], 'message':[libzmq, buffers, message],
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -167,12 +167,13 @@ EADDRINUSE = ZMQ_EADDRINUSE ...@@ -167,12 +167,13 @@ EADDRINUSE = ZMQ_EADDRINUSE
EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL
ECONNREFUSED = ZMQ_ECONNREFUSED ECONNREFUSED = ZMQ_ECONNREFUSED
EINPROGRESS = ZMQ_EINPROGRESS EINPROGRESS = ZMQ_EINPROGRESS
ENOTSOCK = ZMQ_ENOTSOCK
# 0MQ Native # 0MQ Native
EMTHREAD = ZMQ_EMTHREAD
EFSM = ZMQ_EFSM EFSM = ZMQ_EFSM
ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO
ETERM = ZMQ_ETERM ETERM = ZMQ_ETERM
EMTHREAD = ZMQ_EMTHREAD
if ZMQ_VERSION >= 400000: if ZMQ_VERSION >= 400000:
ECANTROUTE = ZMQ_ECANTROUTE ECANTROUTE = ZMQ_ECANTROUTE
_optionals.append('ECANTROUTE') _optionals.append('ECANTROUTE')
...@@ -229,10 +230,11 @@ __all__ = [ ...@@ -229,10 +230,11 @@ __all__ = [
'EADDRNOTAVAIL', 'EADDRNOTAVAIL',
'ECONNREFUSED', 'ECONNREFUSED',
'EINPROGRESS', 'EINPROGRESS',
'EMTHREAD', 'ENOTSOCK',
'EFSM', 'EFSM',
'ENOCOMPATPROTO', 'ENOCOMPATPROTO',
'ETERM', 'ETERM',
'EMTHREAD',
'EFAULT', 'EFAULT',
'ENOMEM', 'ENOMEM',
'ENODEV', 'ENODEV',
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
from libc.stdlib cimport free, malloc, realloc from libc.stdlib cimport free, malloc, realloc
from errno import ENOTSOCK
from libzmq cimport * from libzmq cimport *
...@@ -66,12 +65,16 @@ cdef class Context: ...@@ -66,12 +65,16 @@ cdef class Context:
raise MemoryError("Could not allocate _sockets array") raise MemoryError("Could not allocate _sockets array")
def __del__(self):
"""deleting a Context should terminate it, without trying non-threadsafe destroy"""
self.term()
def __dealloc__(self): def __dealloc__(self):
"""don't touch members in dealloc, just cleanup allocations"""
cdef int rc cdef int rc
if self.handle != NULL:
self.term()
if self._sockets != NULL: if self._sockets != NULL:
free(self._sockets) free(self._sockets)
self.term()
cdef inline void _add_socket(self, void* handle): cdef inline void _add_socket(self, void* handle):
"""Add a socket handle to be closed when Context terminates. """Add a socket handle to be closed when Context terminates.
...@@ -133,22 +136,15 @@ cdef class Context: ...@@ -133,22 +136,15 @@ cdef class Context:
def term(self): def term(self):
"""ctx.term() """ctx.term()
Close or terminate the context and all its sockets. Close or terminate the context.
This can be called to close the context by hand. If this is not This can be called to close the context by hand. If this is not called,
called, the context will automatically be closed when it is the context will automatically be closed when it is garbage collected.
garbage collected.
""" """
cdef int rc cdef int rc
cdef int i=-1 cdef int i=-1
if self.handle != NULL and not self.closed: if self.handle != NULL and not self.closed:
for i in range(self.n_sockets):
# print 'closing: ', <size_t>self._sockets[i]
with nogil:
rc = zmq_close(self._sockets[i])
if rc != 0 and zmq_errno() != ENOTSOCK:
raise ZMQError()
# print i
with nogil: with nogil:
rc = zmq_term(self.handle) rc = zmq_term(self.handle)
if rc != 0: if rc != 0:
...@@ -156,6 +152,37 @@ cdef class Context: ...@@ -156,6 +152,37 @@ cdef class Context:
self.handle = NULL self.handle = NULL
self.closed = True self.closed = True
def destroy(self, linger=None):
"""ctx.destroy(linger=None)
Close all sockets associated with this context, and then terminate
the context. If linger is specified,
the LINGER sockopt of the sockets will be set prior to closing.
WARNING:
destroy involves calling zmq_close(), which is *NOT* threadsafe.
If there are active sockets in other threads, this must not be called.
"""
cdef int linger_c
cdef bint setlinger=False
if linger is not None:
linger_c = linger
setlinger=True
if self.handle != NULL and not self.closed and self.n_sockets:
while self.n_sockets:
with nogil:
if setlinger:
zmq_setsockopt(self._sockets[0], ZMQ_LINGER, &linger_c, sizeof(int))
rc = zmq_close(self._sockets[0])
if rc != 0 and zmq_errno() != ENOTSOCK:
raise ZMQError()
self.n_sockets -= 1
self._sockets[0] = self._sockets[self.n_sockets]
self.term()
def socket(self, int socket_type): def socket(self, int socket_type):
"""ctx.socket(socket_type) """ctx.socket(socket_type)
......
This diff is collapsed.
...@@ -55,6 +55,42 @@ def device(int device_type, cSocket isocket, cSocket osocket): ...@@ -55,6 +55,42 @@ def device(int device_type, cSocket isocket, cSocket osocket):
raise ZMQError() raise ZMQError()
return rc return rc
# inner loop inlined, to prevent duplication
cdef inline int _relay(void * insocket, void *outsocket, zmq_msg_t msg) nogil:
cdef int more=0
cdef int label=0
cdef int flags=0
cdef size_t flagsz
flagsz = sizeof (more)
while (True):
rc = zmq_recvmsg(insocket, &msg, 0)
if (rc < 0):
return -1
rc = zmq_getsockopt(insocket, ZMQ_RCVMORE, &more, &flagsz)
if (rc < 0):
return -1
rc = zmq_getsockopt(insocket, ZMQ_RCVLABEL, &label, &flagsz)
if (rc < 0):
return -1
flags = 0
if more:
flags = flags | ZMQ_SNDMORE
if label:
flags = flags | ZMQ_SNDLABEL
rc = zmq_sendmsg(outsocket, &msg, flags)
if (rc < 0):
return -1
if not (flags):
break
return 0
# c_device copied (and cythonized) from zmq_device in zeromq release-2.1.6 # c_device copied (and cythonized) from zmq_device in zeromq release-2.1.6
# used under LGPL # used under LGPL
cdef inline int c_device (void * insocket, void *outsocket) nogil: cdef inline int c_device (void * insocket, void *outsocket) nogil:
...@@ -67,10 +103,6 @@ cdef inline int c_device (void * insocket, void *outsocket) nogil: ...@@ -67,10 +103,6 @@ cdef inline int c_device (void * insocket, void *outsocket) nogil:
if (rc != 0): if (rc != 0):
return -1 return -1
cdef int more
cdef size_t moresz
moresz = sizeof (more)
cdef zmq_pollitem_t items [2] cdef zmq_pollitem_t items [2]
items [0].socket = insocket items [0].socket = insocket
items [0].fd = 0 items [0].fd = 0
...@@ -96,49 +128,11 @@ cdef inline int c_device (void * insocket, void *outsocket) nogil: ...@@ -96,49 +128,11 @@ cdef inline int c_device (void * insocket, void *outsocket) nogil:
# Process a request. # Process a request.
if (items [0].revents & ZMQ_POLLIN): if (items [0].revents & ZMQ_POLLIN):
while (True): rc = _relay(insocket, outsocket, msg)
rc = zmq_recvmsg(insocket, &msg, 0)
if (rc < 0):
return -1
rc = zmq_getsockopt(insocket, ZMQ_RCVMORE, &more, &moresz)
if (rc < 0):
return -1
if more:
rc = zmq_sendmsg(outsocket, &msg,ZMQ_SNDMORE)
else:
rc = zmq_sendmsg(outsocket, &msg,0)
if (rc < 0):
return -1
if (not more):
break
# Process a reply. # Process a reply.
if (items [1].revents & ZMQ_POLLIN): if (items [1].revents & ZMQ_POLLIN):
while (True): rc = _relay(outsocket, insocket, msg)
rc = zmq_recvmsg(outsocket, &msg, 0)
if (rc < 0):
return -1
rc = zmq_getsockopt(outsocket, ZMQ_RCVMORE, &more, &moresz)
if (rc < 0):
return -1
if more:
rc = zmq_sendmsg(insocket, &msg,ZMQ_SNDMORE)
else:
rc = zmq_sendmsg(insocket, &msg,0)
if (rc < 0):
return -1
if (not more):
break
return 0 return 0
......
This diff is collapsed.
...@@ -33,7 +33,7 @@ from libzmq cimport zmq_strerror, zmq_errno ...@@ -33,7 +33,7 @@ from libzmq cimport zmq_strerror, zmq_errno
from zmq.utils.strtypes import bytes from zmq.utils.strtypes import bytes
def strerror(errnum): def strerror(int errnum):
"""strerror(errnum) """strerror(errnum)
Return the error string given the error number. Return the error string given the error number.
......
...@@ -67,11 +67,12 @@ cdef extern from "zmq.h" nogil: ...@@ -67,11 +67,12 @@ cdef extern from "zmq.h" nogil:
enum: ZMQ_EADDRNOTAVAIL "EADDRNOTAVAIL" enum: ZMQ_EADDRNOTAVAIL "EADDRNOTAVAIL"
enum: ZMQ_ECONNREFUSED "ECONNREFUSED" enum: ZMQ_ECONNREFUSED "ECONNREFUSED"
enum: ZMQ_EINPROGRESS "EINPROGRESS" enum: ZMQ_EINPROGRESS "EINPROGRESS"
enum: ZMQ_EMTHREAD "EMTHREAD" enum: ZMQ_ENOTSOCK "ENOTSOCK"
enum: ZMQ_EFSM "EFSM" enum: ZMQ_EFSM "EFSM"
enum: ZMQ_ENOCOMPATPROTO "ENOCOMPATPROTO" enum: ZMQ_ENOCOMPATPROTO "ENOCOMPATPROTO"
enum: ZMQ_ETERM "ETERM" enum: ZMQ_ETERM "ETERM"
enum: ZMQ_ECANTROUTE "ECANTROUTE" enum: ZMQ_ECANTROUTE "ECANTROUTE"
enum: ZMQ_EMTHREAD "EMTHREAD"
enum: errno enum: errno
char *zmq_strerror (int errnum) char *zmq_strerror (int errnum)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -52,8 +52,6 @@ import random ...@@ -52,8 +52,6 @@ import random
import struct import struct
import codecs import codecs
from errno import ENOTSOCK
from zmq.utils import jsonapi from zmq.utils import jsonapi
try: try:
...@@ -93,7 +91,9 @@ cdef inline _check_closed(Socket s, bint raise_notsup): ...@@ -93,7 +91,9 @@ cdef inline _check_closed(Socket s, bint raise_notsup):
raise ZMQError(ENOTSUP) raise ZMQError(ENOTSUP)
else: else:
return True return True
# return False elif rc:
raise ZMQError()
return False
cdef inline Message _recv_message(void *handle, int flags=0, track=False): cdef inline Message _recv_message(void *handle, int flags=0, track=False):
"""Receive a message in a non-copying manner and return a Message.""" """Receive a message in a non-copying manner and return a Message."""
...@@ -204,9 +204,21 @@ cdef class Socket: ...@@ -204,9 +204,21 @@ cdef class Socket:
self._attrs = {} self._attrs = {}
context._add_socket(self.handle) context._add_socket(self.handle)
def __dealloc__(self): def __del__(self):
"""close *and* remove from context's list"""
self.close() self.close()
def __dealloc__(self):
"""don't touch the Context during dealloc, since it might have been cleaned up already.
This method will likely do nothing unless init has failed."""
if self.handle != NULL:
with nogil:
rc = zmq_close(self.handle)
if rc != 0 and zmq_errno() != ENOTSOCK:
# ignore ENOTSOCK (closed by Context)