1b2732e9dSimarom# coding: utf-8
2b2732e9dSimarom"""zmq Context class"""
3b2732e9dSimarom
4b2732e9dSimarom# Copyright (C) PyZMQ Developers
5b2732e9dSimarom# Distributed under the terms of the Modified BSD License.
6b2732e9dSimarom
7b2732e9dSimaromimport weakref
8b2732e9dSimarom
9b2732e9dSimaromfrom ._cffi import C, ffi
10b2732e9dSimarom
11b2732e9dSimaromfrom .socket import *
12b2732e9dSimaromfrom .constants import *
13b2732e9dSimarom
14b2732e9dSimaromfrom zmq.error import ZMQError, _check_rc
15b2732e9dSimarom
16b2732e9dSimaromclass Context(object):
17b2732e9dSimarom    _zmq_ctx = None
18b2732e9dSimarom    _iothreads = None
19b2732e9dSimarom    _closed = None
20b2732e9dSimarom    _sockets = None
21b2732e9dSimarom    _shadow = False
22b2732e9dSimarom
23b2732e9dSimarom    def __init__(self, io_threads=1, shadow=None):
24b2732e9dSimarom
25b2732e9dSimarom        if shadow:
26b2732e9dSimarom            self._zmq_ctx = ffi.cast("void *", shadow)
27b2732e9dSimarom            self._shadow = True
28b2732e9dSimarom        else:
29b2732e9dSimarom            self._shadow = False
30b2732e9dSimarom            if not io_threads >= 0:
31b2732e9dSimarom                raise ZMQError(EINVAL)
32b2732e9dSimarom
33b2732e9dSimarom            self._zmq_ctx = C.zmq_ctx_new()
34b2732e9dSimarom        if self._zmq_ctx == ffi.NULL:
35b2732e9dSimarom            raise ZMQError(C.zmq_errno())
36b2732e9dSimarom        if not shadow:
37b2732e9dSimarom            C.zmq_ctx_set(self._zmq_ctx, IO_THREADS, io_threads)
38b2732e9dSimarom        self._closed = False
39b2732e9dSimarom        self._sockets = set()
40b2732e9dSimarom
41b2732e9dSimarom    @property
42b2732e9dSimarom    def underlying(self):
43b2732e9dSimarom        """The address of the underlying libzmq context"""
44b2732e9dSimarom        return int(ffi.cast('size_t', self._zmq_ctx))
45b2732e9dSimarom
46b2732e9dSimarom    @property
47b2732e9dSimarom    def closed(self):
48b2732e9dSimarom        return self._closed
49b2732e9dSimarom
50b2732e9dSimarom    def _add_socket(self, socket):
51b2732e9dSimarom        ref = weakref.ref(socket)
52b2732e9dSimarom        self._sockets.add(ref)
53b2732e9dSimarom        return ref
54b2732e9dSimarom
55b2732e9dSimarom    def _rm_socket(self, ref):
56b2732e9dSimarom        if ref in self._sockets:
57b2732e9dSimarom            self._sockets.remove(ref)
58b2732e9dSimarom
59b2732e9dSimarom    def set(self, option, value):
60b2732e9dSimarom        """set a context option
61b2732e9dSimarom
62b2732e9dSimarom        see zmq_ctx_set
63b2732e9dSimarom        """
64b2732e9dSimarom        rc = C.zmq_ctx_set(self._zmq_ctx, option, value)
65b2732e9dSimarom        _check_rc(rc)
66b2732e9dSimarom
67b2732e9dSimarom    def get(self, option):
68b2732e9dSimarom        """get context option
69b2732e9dSimarom
70b2732e9dSimarom        see zmq_ctx_get
71b2732e9dSimarom        """
72b2732e9dSimarom        rc = C.zmq_ctx_get(self._zmq_ctx, option)
73b2732e9dSimarom        _check_rc(rc)
74b2732e9dSimarom        return rc
75b2732e9dSimarom
76b2732e9dSimarom    def term(self):
77b2732e9dSimarom        if self.closed:
78b2732e9dSimarom            return
79b2732e9dSimarom
80b2732e9dSimarom        C.zmq_ctx_destroy(self._zmq_ctx)
81b2732e9dSimarom
82b2732e9dSimarom        self._zmq_ctx = None
83b2732e9dSimarom        self._closed = True
84b2732e9dSimarom
85b2732e9dSimarom    def destroy(self, linger=None):
86b2732e9dSimarom        if self.closed:
87b2732e9dSimarom            return
88b2732e9dSimarom
89b2732e9dSimarom        sockets = self._sockets
90b2732e9dSimarom        self._sockets = set()
91b2732e9dSimarom        for s in sockets:
92b2732e9dSimarom            s = s()
93b2732e9dSimarom            if s and not s.closed:
94b2732e9dSimarom                if linger:
95b2732e9dSimarom                    s.setsockopt(LINGER, linger)
96b2732e9dSimarom                s.close()
97b2732e9dSimarom
98b2732e9dSimarom        self.term()
99b2732e9dSimarom
100b2732e9dSimarom__all__ = ['Context']
101