~ubuntu-branches/ubuntu/precise/pyzmq/precise

« back to all changes in this revision

Viewing changes to zmq/core/socket.pyx

  • Committer: Package Import Robot
  • Author(s): Debian Python Modules Team
  • Date: 2011-09-23 00:16:39 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: package-import@ubuntu.com-20110923001639-girjqodpb7uv17yu
Tags: 2.1.9-1
* New upstream version
  - should build on kFreeBSD without patches (Closes: #637777).
* Build-depend on zeromq 2.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""0MQ Socket class."""
2
2
 
3
3
#
4
 
#    Copyright (c) 2010 Brian E. Granger
 
4
#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
5
5
#
6
6
#    This file is part of pyzmq.
7
7
#
27
27
cdef extern from "pyversion_compat.h":
28
28
    pass
29
29
 
30
 
from libc.stdlib cimport free, malloc
31
30
from cpython cimport PyBytes_FromStringAndSize
32
31
from cpython cimport PyBytes_AsString, PyBytes_Size
33
32
from cpython cimport Py_DECREF, Py_INCREF
34
33
 
35
34
from buffers cimport asbuffer_r, viewfromobject_r
36
35
 
37
 
from czmq cimport *
 
36
from libzmq cimport *
38
37
from message cimport Message, copy_zmq_msg_bytes
39
38
 
 
39
from context cimport Context
 
40
 
40
41
cdef extern from "Python.h":
41
42
    ctypedef int Py_ssize_t
42
43
 
51
52
import struct
52
53
import codecs
53
54
 
 
55
from errno import ENOTSOCK
 
56
 
54
57
from zmq.utils import jsonapi
55
58
 
56
59
try:
72
75
# inline some small socket submethods:
73
76
# true methods frequently cannot be inlined, acc. Cython docs
74
77
 
75
 
cdef inline _check_closed(Socket s):
76
 
    if s.closed:
77
 
        raise ZMQError(ENOTSUP)
 
78
cdef inline _check_closed(Socket s, bint raise_notsup):
 
79
    cdef int rc
 
80
    cdef int errno
 
81
    cdef int stype
 
82
    cdef size_t sz=sizeof(int)
 
83
    if s._closed:
 
84
        if raise_notsup:
 
85
            raise ZMQError(ENOTSUP)
 
86
        else:
 
87
            return True
 
88
    else:
 
89
        rc = zmq_getsockopt(s.handle, ZMQ_TYPE, <void *>&stype, &sz)
 
90
        if rc and zmq_errno() == ENOTSOCK:
 
91
            s._closed = True
 
92
            if raise_notsup:
 
93
                raise ZMQError(ENOTSUP)
 
94
            else:
 
95
                return True
 
96
    # return False
78
97
 
79
98
cdef inline Message _recv_message(void *handle, int flags=0, track=False):
80
99
    """Receive a message in a non-copying manner and return a Message."""
155
174
 
156
175
    These objects will generally be constructed via the socket() method of a Context object.
157
176
    
 
177
    Note: 0MQ Sockets are *not* threadsafe. **DO NOT** share them across threads.
 
178
    
158
179
    Parameters
159
180
    ----------
160
181
    context : Context
161
182
        The 0MQ Context this Socket belongs to.
162
183
    socket_type : int
163
184
        The socket type, which can be any of the 0MQ socket types: 
164
 
        REQ, REP, PUB, SUB, PAIR, XREQ, XREP, PULL, PUSH, XPUB, XSUB.
 
185
        REQ, REP, PUB, SUB, PAIR, XREQ, DEALER, XREP, ROUTER, PULL, PUSH, XPUB, XSUB.
165
186
    
166
187
    See Also
167
188
    --------
168
189
    .Context.socket : method for creating a socket bound to a Context.
169
190
    """
170
191
 
171
 
    def __cinit__(self, object context, int socket_type):
 
192
    def __cinit__(self, Context context, int socket_type, *args, **kwrags):
172
193
        cdef Py_ssize_t c_handle
173
194
        c_handle = context._handle
174
195
 
179
200
            self.handle = zmq_socket(<void *>c_handle, socket_type)
180
201
        if self.handle == NULL:
181
202
            raise ZMQError()
182
 
        self.closed = False
 
203
        self._closed = False
 
204
        self._attrs = {}
 
205
        context._add_socket(self.handle)
183
206
 
184
207
    def __dealloc__(self):
185
208
        self.close()
 
209
    
 
210
    def __init__(self, context, socket_type):
 
211
        pass
186
212
 
 
213
    @property
 
214
    def closed(self):
 
215
        return _check_closed(self, False)
 
216
    
187
217
    def close(self):
188
218
        """s.close()
189
219
 
194
224
        garbage collected.
195
225
        """
196
226
        cdef int rc
197
 
        if self.handle != NULL and not self.closed:
 
227
        
 
228
        if self.handle != NULL and not self._closed:
198
229
            with nogil:
199
230
                rc = zmq_close(self.handle)
200
 
            if rc != 0:
 
231
            if rc != 0 and zmq_errno() != ENOTSOCK:
 
232
                # ignore ENOTSOCK (closed by Context)
201
233
                raise ZMQError()
 
234
            self.context._remove_socket(self.handle)
202
235
            self.handle = NULL
203
 
            self.closed = True
 
236
            self._closed = True
204
237
 
205
238
    def setsockopt(self, int option, optval):
206
239
        """s.setsockopt(option, optval)
207
240
 
208
241
        Set socket options.
209
242
 
210
 
        See the 0MQ documentation for details on specific options.
 
243
        See the 0MQ API documentation for details on specific options.
211
244
 
212
245
        Parameters
213
246
        ----------
214
 
        option : str
215
 
            The name of the option to set. Can be any of: SUBSCRIBE, 
216
 
            UNSUBSCRIBE, IDENTITY, HWM, SWAP, AFFINITY, RATE, 
217
 
            RECOVERY_IVL, MCAST_LOOP, SNDBUF, RCVBUF.
218
 
        optval : int or str
 
247
        option : int
 
248
            The option to set.  Available values will depend on your
 
249
            version of libzmq.  Examples include:
 
250
                zmq.SUBSCRIBE, UNSUBSCRIBE, IDENTITY, HWM, LINGER, FD
 
251
        optval : int or bytes
219
252
            The value of the option to set.
220
253
        """
221
254
        cdef int64_t optval_int64_c
224
257
        cdef char* optval_c
225
258
        cdef Py_ssize_t sz
226
259
 
227
 
        _check_closed(self)
 
260
        _check_closed(self, True)
228
261
        if isinstance(optval, unicode):
229
262
            raise TypeError("unicode not allowed, use setsockopt_unicode")
230
263
 
231
264
        if option in constants.bytes_sockopts:
232
265
            if not isinstance(optval, bytes):
233
 
                raise TypeError('expected str, got: %r' % optval)
 
266
                raise TypeError('expected bytes, got: %r' % optval)
234
267
            optval_c = PyBytes_AsString(optval)
235
268
            sz = PyBytes_Size(optval)
236
269
            with nogil:
267
300
 
268
301
        Get the value of a socket option.
269
302
 
270
 
        See the 0MQ documentation for details on specific options.
 
303
        See the 0MQ API documentation for details on specific options.
271
304
 
272
305
        Parameters
273
306
        ----------
274
 
        option : str
275
 
            The name of the option to set. Can be any of: 
276
 
            IDENTITY, HWM, SWAP, AFFINITY, RATE, 
277
 
            RECOVERY_IVL, MCAST_LOOP, SNDBUF, RCVBUF, RCVMORE.
 
307
        option : int
 
308
            The option to set.  Available values will depend on your
 
309
            version of libzmq.  Examples include:
 
310
                zmq.SUBSCRIBE, UNSUBSCRIBE, IDENTITY, HWM, LINGER, FD
278
311
 
279
312
        Returns
280
313
        -------
281
 
        optval : int, str
282
 
            The value of the option as a string or int.
 
314
        optval : int or bytes
 
315
            The value of the option as a bytestring or int.
283
316
        """
284
317
        cdef int64_t optval_int64_c
285
318
        cdef int optval_int_c
 
319
        cdef fd_t optval_fd_c
286
320
        cdef char identity_str_c [255]
287
321
        cdef size_t sz
288
322
        cdef int rc
289
323
 
290
 
        _check_closed(self)
 
324
        _check_closed(self, True)
291
325
 
292
326
        if option in constants.bytes_sockopts:
293
327
            sz = 255
310
344
            if rc != 0:
311
345
                raise ZMQError()
312
346
            result = optval_int_c
 
347
        elif option == ZMQ_FD:
 
348
            sz = sizeof(fd_t)
 
349
            with nogil:
 
350
                rc = zmq_getsockopt(self.handle, option, <void *>&optval_fd_c, &sz)
 
351
            if rc != 0:
 
352
                raise ZMQError()
 
353
            result = optval_fd_c
313
354
        else:
314
355
            raise ZMQError(EINVAL)
315
356
 
356
397
        optval : unicode
357
398
            The value of the option as a unicode string.
358
399
        """
359
 
        if option not in [IDENTITY]:
 
400
        
 
401
        if option not in [ZMQ_IDENTITY]:
360
402
            raise TypeError("option %i will not return a string to be decoded"%option)
361
403
        return self.getsockopt(option).decode(encoding)
362
404
    
 
405
    def __setattr__(self, key, value):
 
406
        """set sockopts by attr"""
 
407
        key = key
 
408
        try:
 
409
            opt = getattr(constants, key.upper())
 
410
        except AttributeError:
 
411
            # allow subclasses to have extended attributes
 
412
            if self.__class__.__module__ != 'zmq.core.socket':
 
413
                self._attrs[key] = value
 
414
            else:
 
415
                raise AttributeError("Socket has no such option: %s"%key.upper())
 
416
        else:
 
417
            self.setsockopt(opt, value)
 
418
    
 
419
    def __getattr__(self, key):
 
420
        """set sockopts by attr"""
 
421
        if key in self._attrs:
 
422
            # `key` is subclass extended attribute
 
423
            return self._attrs[key]
 
424
        key = key.upper()
 
425
        try:
 
426
            opt = getattr(constants, key)
 
427
        except AttributeError:
 
428
            raise AttributeError("Socket has no such option: %s"%key)
 
429
        else:
 
430
            return self.getsockopt(opt)
 
431
    
363
432
    def bind(self, addr):
364
433
        """s.bind(addr)
365
434
 
379
448
        """
380
449
        cdef int rc
381
450
 
382
 
        _check_closed(self)
 
451
        _check_closed(self, True)
383
452
        if isinstance(addr, unicode):
384
453
            addr = addr.encode('utf-8')
385
454
        if not isinstance(addr, bytes):
440
509
        """
441
510
        cdef int rc
442
511
 
443
 
        _check_closed(self)
 
512
        _check_closed(self, True)
444
513
        if isinstance(addr, unicode):
445
514
            addr = addr.encode('utf-8')
446
515
        if not isinstance(addr, bytes):
491
560
            If the send does not succeed for any reason.
492
561
        
493
562
        """
494
 
        _check_closed(self)
 
563
        _check_closed(self, True)
495
564
        
496
565
        if isinstance(data, unicode):
497
566
            raise TypeError("unicode not allowed, use send_unicode")
542
611
        ZMQError
543
612
            for any of the reasons zmq_recvmsg might fail.
544
613
        """
545
 
        _check_closed(self)
 
614
        _check_closed(self, True)
546
615
        
547
616
        if copy:
548
617
            return _recv_copy(self.handle, flags)