Ejemplo n.º 1
0
 async def _bind_tcp_sockets_with_consistent_port_number(self, make_socket):
     # Find a random port number that is free on all self.interfaces,
     # and get a bound TCP socket with that port number on each
     # interface. The argument `make_socket` is expected to be a coroutine
     # with the signature `make_socket(interface, port)` that does whatever
     # library-specific incantation is necessary to return a bound socket or
     # raise an IOError.
     tcp_sockets = {}  # maps interface to bound socket
     stashed_ex = None
     for port in ca.random_ports(100, try_first=self.ca_server_port):
         try:
             for interface in self.interfaces:
                 s = await make_socket(interface, port)
                 tcp_sockets[interface] = s
         except IOError as ex:
             stashed_ex = ex
             for s in tcp_sockets.values():
                 s.close()
             tcp_sockets.clear()
         else:
             break
     else:
         raise CaprotoRuntimeError(
             'No available ports and/or bind failed') from stashed_ex
     return port, tcp_sockets
Ejemplo n.º 2
0
    def __init__(self,
                 pvname,
                 callback=None,
                 form='time',
                 verbose=False,
                 auto_monitor=None,
                 count=None,
                 connection_callback=None,
                 connection_timeout=None,
                 access_callback=None,
                 *,
                 context=None):

        if context is None:
            context = self._default_context
        if context is None:
            raise CaprotoRuntimeError("must have a valid context")
        self._context = context
        self.pvname = pvname.strip()
        self.form = form.lower()
        self.verbose = verbose
        self.auto_monitor = auto_monitor
        self.ftype = None
        self._connected = False
        self._connect_event = threading.Event()
        self._state_lock = threading.RLock()
        self.connection_timeout = connection_timeout
        self.default_count = count
        self._auto_monitor_sub = None

        if self.connection_timeout is None:
            self.connection_timeout = 1

        self._args = {}.fromkeys(self._fields)
        self._args['pvname'] = self.pvname
        self._args['count'] = count
        self._args['nelm'] = -1
        self._args['type'] = None
        self._args['typefull'] = None
        self._args['access'] = None
        self.connection_callbacks = []
        self._cb_count = iter(itertools.count())

        if connection_callback is not None:
            self.connection_callbacks = [connection_callback]

        self.access_callbacks = []
        if access_callback is not None:
            self.access_callbacks.append(access_callback)

        self.callbacks = {}
        self._conn_started = False

        if isinstance(callback, (tuple, list)):
            for i, thiscb in enumerate(callback):
                if hasattr(thiscb, '__call__'):
                    self.callbacks[i] = (thiscb, {})

        elif hasattr(callback, '__call__'):
            self.callbacks[0] = (callback, {})

        self._caproto_pv, = self._context.get_pvs(
            self.pvname,
            connection_state_callback=self._connection_state_changed,
            access_rights_callback=self._access_rights_changed,
        )

        if self._caproto_pv.connected:
            # connection state callback was already called but we didn't see it
            self._connection_state_changed(self._caproto_pv, 'connected')