class Node(object): STATE_INIT = 0 STATE_STARTING = 1 STATE_RUNNING = 2 STATE_STOPPED = 3 STATE_PARTITIONED = 4 STATE_FAILED = 5 state_str = {STATE_INIT: "Initial", STATE_STARTING: "Starting", STATE_RUNNING: "Running", STATE_STOPPED: "Stopped", STATE_FAILED: "Failed"} def __init__(self, node_id): self.node_id = node_id self.state = Node.STATE_INIT self.cv_lock = Lock() self.cv = Condition(self.cv_lock) def wait_for_state(self, state): self.cv.acquire() while self.state not in (state, Node.STATE_FAILED): self.cv.wait() self.cv.release() if self.state != state: raise ChistributedException("Node entered failed state while waiting for state %s" % Node.state_str[state]) def set_state(self, state): self.cv.acquire() self.state = state self.cv.notify_all() self.cv.release()
class KeepAlive(Thread): """ Used by Client to keep session opened. OPCUA defines timeout both for sessions and secure channel """ def __init__(self, client, timeout): Thread.__init__(self) self.logger = logging.getLogger(__name__) if timeout == 0: # means no timeout bu we do not trust such servers timeout = 360000 self.timeout = timeout self.client = client self._dostop = False self._cond = Condition() def run(self): self.logger.debug("starting keepalive thread with period of %s milliseconds", self.timeout) server_state = self.client.get_node(ua.FourByteNodeId(ua.ObjectIds.Server_ServerStatus_State)) while not self._dostop: with self._cond: self._cond.wait(self.timeout/1000) if self._dostop: break self.logger.debug("renewing channel") self.client.open_secure_channel(renew=True) val = server_state.get_value() self.logger.debug("server state is: %s ", val) self.logger.debug("keepalive thread has stopped") def stop(self): self.logger.debug("stoping keepalive thread") with self._cond: self._cond.notify_all() self._dostop = True
class ThreadLoop(Thread): def __init__(self): Thread.__init__(self) self.logger = logging.getLogger(__name__) self.loop = None self._cond = Condition() def start(self): with self._cond: Thread.start(self) self._cond.wait() def run(self): self.logger.debug("Starting subscription thread") self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) with self._cond: self._cond.notify_all() self.loop.run_forever() self.logger.debug("subscription thread ended") def stop(self): """ stop subscription loop, thus the subscription thread """ self.loop.call_soon_threadsafe(self.loop.stop) def call_soon(self, callback): self.loop.call_soon_threadsafe(callback) def call_later(self, delay, callback): p = functools.partial(self.loop.call_later, delay, callback) self.loop.call_soon_threadsafe(p)
class Event(object): def __init__(self,): self.__cond = Condition(Lock()) self.__flag = False def isSet(self): return self.__flag is_set = isSet def set(self): self.__cond.acquire() try: self.__flag = True self.__cond.notify_all() finally: self.__cond.release() def clear(self): self.__cond.acquire() try: self.__flag = False finally: self.__cond.release() def wait(self, timeout=None): self.__cond.acquire() try: if not self.__flag: self.__cond.wait(timeout) return self.__flag finally: self.__cond.release()
class MockSock: def __init__(self): self.sent = six.binary_type() self.send_q = deque() self.recv_q = deque() self.closed = False self.lock = Lock() self.cond = Condition(self.lock) self.timeout = 0.5 def gettimeout(self): return self.timeout def close(self): self.lock.acquire() self.closed = True self.lock.release() def queue_send(self, num_bytes): self.lock.acquire() try: self.send_q.append(num_bytes) self.cond.notify_all() finally: self.lock.release() def send(self, message): self.lock.acquire() try: while not len(self.send_q): self.cond.wait() num_bytes = self.send_q.popleft() if num_bytes < len(message): self.send_q.appendleft(len(message) - num_bytes) sent = min(num_bytes, len(message)) self.sent += message[:sent] return sent finally: self.lock.release() def queue_recv(self, message): self.lock.acquire() try: self.recv_q.append(message) self.cond.notify_all() finally: self.lock.release() def recv(self, max_len): self.lock.acquire() try: while not len(self.recv_q): self.cond.wait() message = self.recv_q.popleft() recd = min(max_len, len(message)) if (recd < len(message)): self.recv_q.appendleft(message[recd:]) return message[:recd] finally: self.lock.release()
class Barrier: def __init__(self, num_threads): self.num_threads = num_threads self.count = num_threads self.iter = 0 self.cond = Condition() def wait(self): self.cond.acquire() i = self.iter self.count -= 1 if self.count == 0: self.iter += 1 self.count = self.num_threads self.cond.notify_all() self.cond.release() return True # Release lock and block this thread until notified/woken. # Allow for spurious wake-ups. while 1: self.cond.wait(None) if i != self.iter: break self.cond.release() return False
class LockedDirectories(object): """ Class that keeps a list of locked directories """ def __init__(self): self.dirs = set() self.cv = Condition() def run_in(self, dir_): """ Start running in the directory and lock it """ self.cv.acquire() while dir_ in self.dirs: self.cv.wait() self.dirs.add(dir_) self.cv.release() def done(self, dir_): """ Finished with the directory, unlock it """ self.cv.acquire() self.dirs.remove(dir_) self.cv.notify_all() self.cv.release()
class Presponse(PktHandler): def __init__(self): self.ping_response_wait = Condition() ''' To wait for a ping response, do the following:{ start = time.time() with Presponse.ping_response_wait: Presponse.ping_response_wait.wait(5) # Standard timeout in PING latency is 5. end = time.time() } (end - start) is the ping latency. ''' def handle(self, packet_map): with self.ping_response_wait: self.ping_response_wait.notify_all() return None def getproperties(self): return { 'DisplayName':'Ping-Response Notifier', 'CodeName':'PRESPONSE_NOTIFY', 'PacketType':'PRESPONSE', 'Version':0.01 }
class TestBackend(Backend): def __init__(self, queue): self.lock = Condition() queue._set_backend(self) # Statistics self.notifies = 0 def start(self): pass def stop(self): pass def start_feedback(self): pass def queue_lock(self): return self.lock def queue_notify(self): self.notifies += 1 self.lock.notify_all() def sleep(self): pass
class SendBuffer(object): def __init__(self, max_size): self.size = 0 self.frontbuffer = '' self.full = Condition() self.backbuffer = StringIO() self.max_size = max_size def __len__(self): return len(self.frontbuffer) + self.size def write(self, data): dlen = len(data) with self.full: while self.size + dlen > self.max_size and dlen < self.max_size: # if a single write is bigger than the buffer, swallow hard. # No amount of waitng will make it fit. self.full.wait() self.backbuffer.write(data) self.size += dlen def to_sock(self, sock): if not self.frontbuffer: with self.full: buf, self.backbuffer = self.backbuffer, StringIO() self.size = 0 self.full.notify_all() self.frontbuffer = buf.getvalue() written = sock.send(self.frontbuffer) self.frontbuffer = self.frontbuffer[written:]
class BinaryServer(Thread): """ Socket server forwarding request to internal server """ def __init__(self, internal_server, hostname, port): Thread.__init__(self) self.socket_server = None self.hostname = hostname self.port = port self.iserver = internal_server self._cond = Condition() def start(self): with self._cond: Thread.start(self) self._cond.wait() def run(self): logger.warning("Listening on %s:%s", self.hostname, self.port) socketserver.TCPServer.allow_reuse_address = True # get rid of address already in used warning self.socket_server = ThreadingTCPServer((self.hostname, self.port), UAHandler) # self.socket_server.daemon_threads = True # this will force a shutdown of all threads, maybe too hard self.socket_server.internal_server = self.iserver # allow handler to acces server properties with self._cond: self._cond.notify_all() self.socket_server.serve_forever() def stop(self): logger.warning("server shutdown request") self.socket_server.shutdown()
class MySubHandler(opcua.SubscriptionHandler): """ More advanced subscription client using conditions, so we can wait for events in tests """ def setup(self): self.cond = Condition() self.node = None self.handle = None self.attribute = None self.value = None self.ev = None return self.cond def data_change(self, handle, node, val, attr): self.handle = handle self.node = node self.value = val self.attribute = attr with self.cond: self.cond.notify_all() def event(self, handle, event): self.ev = event with self.cond: self.cond.notify_all()
class Timer(EventProducer): #{{{ """ Timer implementation; richer than threading.Timer: allows to periodically fire one callback for some time, finally it fires second callback. Timer instance is tightly bound to invoker object which is used to execute callbacks. """ def __init__(self, invoker, total=None, interval=None, callback=__pass__, end_callback=__pass__, user_data=None): """Run for `total` seconds, every `interval` call `callback`, finally call `end_callback`. If `interval` is not set, only `end_callback` is called once. If `total` is None, call until canceled. """ EventProducer.__init__(self, invoker) self.interval = interval if interval is not None else float('inf') self.total = total if total is not None else float('inf') if user_data: self.callback = partial(callback, user_data=user_data) else: self.callback = callback self.end_callback = end_callback self.user_data = user_data self.cancelled = False self.last_time = time() self.timer_invoker = Invoker() self.timer_invoker.name = 'timer invoker' self.end_cnd = Condition() def start(self): def __callback__(): if not self.cancelled: self.callback(self.time_left) self.timer_invoker.invoke(tick) def tick(): to_sleep = max(0, min(self.time_left, self.interval)) with self.end_cnd: self.end_cnd.wait(to_sleep) act_time = time() self.time_left = self.total - (act_time - self.begin_time) if not self.cancelled: if self.time_left > 0: self.invoker.invoke(__callback__) else: self.invoker.invoke(self.end_callback) self.timer_invoker.cancel() self.begin_time = time() self.time_left = self.total self.timer_invoker.start() self.timer_invoker.invoke(tick) return "timer_start_return" def cancel(self): self.cancelled = True self.timer_invoker.cancel() with self.end_cnd: self.end_cnd.notify_all()
class Future(object): class CallbackRecord(object): def __init__(self, callback, trigger_on_cancel): self.callback = callback self.trigger_on_cancel = trigger_on_cancel def __init__(self): self.__result = None self.finished = False self.cancelled = False self.__callbacks = [] self.__lock = Condition() self.logger = logging.getLogger(__name__) def fulfill(self, result=None): with self.__lock: self.__result = result self.__do_finish() def __do_finish(self): self.finished = True self.__fire_callbacks() self.__lock.notify_all() def cancel(self): with self.__lock: self.cancelled = True self.__do_finish() def __fire_callbacks(self): for callback_record in self.__callbacks: self.__fire_callback(callback_record) def __do_fire(self, callback): #pylint: disable=bare-except try: callback(self.__result) except: self.logger.exception("Exception occurred running future callback") def __fire_callback(self, callback_record): if callback_record.trigger_on_cancel or not self.cancelled: common_pool.submit(self.__do_fire(callback_record.callback)) def join(self): with self.__lock: while not self.finished: self.__lock.wait() def add_callback(self, callback, trigger_on_cancel=True): callback_record = Future.CallbackRecord(callback, trigger_on_cancel) with self.__lock: if self.finished: self.__fire_callback(callback_record) else: self.__callbacks.append(callback_record)
class CameraWorker: def __init__(self): self.frame_cd = Condition() self.frame = False self.keep_working = True self.worker = Thread(target=self.work) self.worker.start() def work(self): camera = picamera.PiCamera() camera.hflip = config_get("raspberry_horizontal_flip") camera.vflip = config_get("raspberry_vertical_flip") camera.resolution = ( config_get("raspberry_resolution_x"), config_get("raspberry_resolution_y") ) camera.start_preview() time.sleep(2) stream = io.BytesIO() released = True try: for notUsed in camera.capture_continuous(stream, format='jpeg', resize=None, quality=config_get("raspberry_base_quality")): self.frame_cd.acquire() released = False self.frame = stream.getvalue() self.frame_cd.notify_all() self.frame_cd.release() released = True stream.seek(0) stream.truncate() if not self.keep_working: break finally: camera.close() if not released: self.frame_cd.release() def close(self): self.keep_working = False self.worker.join() def get_picture(self): self.frame_cd.acquire() self.frame_cd.wait(5) frame_cpy = self.frame self.frame_cd.release() return frame_cpy def stream(self): try: self.frame_cd.acquire() while self.keep_working: self.frame_cd.wait(5) yield self.frame finally: self.frame_cd.release()
class TimeoutObserver(BLEDriverObserver): def __init__(self): self.cond = Condition(Lock()) def on_gap_evt_timeout(self, ble_driver, conn_handle, src): with self.cond: self.cond.notify_all() def wait_for_timeout(self): with self.cond: self.cond.wait()
class BroadcastQueue(object): """ NOTE: This has been superseded by stm/broadcastqueue.py. Look there for future improvements. A queue-like object that allows multiple "endpoints", each of which provides separate read access to the queue. Whenever an item is added to the queue, it becomes available at every endpoint separately. This class provides several advantages over simply tracking a list of ordinary Python Queue instances and inserting items into all of them at once: Each endpoint uses a constant amount of space. With an ordinary list of queues, 1000 items added to 100 queues would result in 100,000 pointers being created, 1000 in each of the 100 queues. Due to the way BroadcastQueue is implemented, it would only use 1,100 pointers: one for each endpoint and one for each item. When an endpoint loses all references, any items that have not yet been consumed by that endpoint are automatically dereferenced. There's no need to remove the endpoint from any sort of list, like you would have to do with a list of ordinary Queue instances. Better yet, endpoints don't use reference cycles or weak references, so the dereferencing happens instantaneously. An interesting side effect of the automatic dereferencing is that inserting into a BroadcastQueue with no endpoints (or only endpoints that have since been garbage collected) silently ignores the value to be inserted. """ def __init__(self): self.condition = Condition() self._link = _Link() def put(self, value): """ Inserts an item into this queue. """ with self.condition: item = _Item(value, _Link()) self._link.item = item self._link = item.link self.condition.notify_all() def new_endpoint(self): """ Creates a new endpoint for reading from this queue. The endpoint initially starts out empty; new items will be available from it once Queue.put is called. """ return _Endpoint(self, self._link)
class EventQueue(object): """Queue to store events posted to a StateMachine.""" def __init__(self, dflt_prio=None): self._queue = [] self._counter = 0 self._lock = lock = Lock() self._evt_avail = Condition(lock) self._settled = Condition(lock) self._consumers = 0 self.dflt_prio = dflt_prio def put(self, evt_data, prio=None): """Adds the Event to the queue.""" if prio is None: prio = self.dflt_prio with self._lock: if not self._queue: # Notify any thread waiting for a new event # as soon as the lock is released self._evt_avail.notify() # _counter is used to ensure that Events that share # the same priority are queued by order of arrival. heappush(self._queue, (prio, self._counter, evt_data)) self._counter += 1 def get(self, timeout=None): """Returns the next (prio, evt_data) from the queue.""" with self._lock: if not self._queue: # Queue is empty, the StateMachine is settled self._counter = 0 self._consumers += 1 self._settled.notify_all() self._evt_avail.wait(timeout) self._consumers -= 1 if not self._queue: # Timed out waiting for a new event raise queue.Empty prio, _, evt_data = heappop(self._queue) return prio, evt_data def settle(self, timeout=None): """Returns once the queue is empty and a consumer is waiting for the next event, or when timeout has expired. returns True if the queue is empty.""" with self._lock: if self._queue or self._consumers == 0: self._settled.wait(timeout) return not bool(self._queue) and self._consumers > 0
class Poller(object): def __init__(self): # Note: this is really close to the python queue, but we really have to # mess with its internals to get the same semantics as WPILib, so we are # rolling our own :( self.poll_queue = deque() self.poll_cond = Condition() self.terminating = False self.cancelling = False def terminate(self): with self.poll_cond: self.terminating = True self.poll_cond.notify_all()
class StreamingOutputBGR(object): def __init__(self, resolution): self.frame = None self.condition = Condition() self.resolution = resolution self.count = 0 def write(self, buf): with self.condition: frame = np.frombuffer(buf, dtype=np.uint8) self.frame = frame.reshape(self.resolution[1], self.resolution[0], 4) self.frame = np.delete(self.frame, 3, 2) self.condition.notify_all() return len(buf)
class UdpReceiver(Thread): """Thread which can receive UDP messages on a port, so we can make sure syslog/snmp is working.""" def __init__(self, port): Thread.__init__(self) self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.addr = ("127.0.0.1", port) self.socket.bind(self.addr) self.packets = [] self.packets_cv = Condition() def run(self): self.running = True while self.running: data, _ = self.socket.recvfrom(4096) with self.packets_cv: self.packets.append(data) self.packets_cv.notify_all() def pop(self, timeout_seconds=10): """Blocking call that returns the next UDP packet received or raises an exception on timeout.""" start_time = time() with self.packets_cv: while len(self.packets) == 0: total_wait = time() - start_time if total_wait < timeout_seconds: self.packets_cv.wait(timeout_seconds) else: raise StandardError("Timed out waiting for packet.") return self.packets.pop(0) def stop(self): self.running = False self.socket.sendto("quit", self.addr) # Send jibberish so recv wakes. def close(self): self.socket.close() def __enter__(self): self.start() return self def __exit__(self, type, value, traceback): self.stop() self.join() self.close()
class Invoker: """ once started, invoker works as a one-thread executor, executing functions that are passed to it using invoke """ def __init__(self): self.cnd = Condition() self.commands = deque() self.end = False def start(self): t = Thread(target = self.__start__) t.daemon = True t.start() return t def __start__(self): try: while not self.end: with self.cnd: while (not self.commands) and (not self.end): self.cnd.wait() if not self.end: fn,args,kwargs=self.commands.pop() if not self.end: logger.debug('invoking %s with arguments %s %s (%d commands left)'%(str(fn), str(args), str(kwargs), len(self.commands))) fn(*args, **kwargs) logger.debug('after invocation') except Exception as e: logger.exception(e) sys.exit() def __exit__(self): with self.cnd: self.end=True self.cnd.notify_all() def invoke(self, fn, *args, **kwargs): """ invoke function fn with given arguments """ with self.cnd: self.commands.appendleft((fn, args, kwargs)) self.cnd.notify_all() def cancel(self): self.__exit__()
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class ExclusiveContext(object): def __init__(self): self.active = False self.lock = Lock() self.condition = Condition(self.lock) def __enter__(self): self.condition.acquire() self.active = True def __exit__(self, exc_type, exc_val, exc_tb): self.active = False self.condition.notify_all() self.condition.release()
class Barrier: def __init__(self, num_threads): self.num_threads = num_threads self.num_remaining = num_threads self.cond = Condition() def wait(self): self.cond.acquire() self.num_remaining -= 1 if self.num_remaining > 0: # Release lock and block this thread until notified. self.cond.wait(None) else: self.num_remaining = self.num_threads self.cond.notify_all() self.cond.release()
class ReusableBarrierCond(): def __init__(self, num_threads): self.num_threads = num_threads self.count_threads = self.num_threads self.cond = Condition() # blocheaza/deblocheaza thread-urile # protejeaza modificarea contorului def wait(self): self.cond.acquire() # intra in regiunea critica self.count_threads -= 1; if self.count_threads == 0: self.cond.notify_all() # deblocheaza toate thread-urile self.count_threads = self.num_threads else: self.cond.wait(); # blocheaza thread-ul eliberand in acelasi timp lock-ul self.cond.release(); # iese din regiunea critica
class TokenBasedAuthenticationHandler(): """ Authenticate via a Token drawn from a configured login url """ def __init__(self, username, password, login_url, ssl_config=SslConfig()): self.login_http_client = HttpClient(login_url, BasicAuthenticationHandler(username, password), ssl_config=ssl_config) self.token = None self.is_renewing = False self.renewing = Condition() def request_headers(self): if self.is_renewing: # avoid lock at the cost of sometimes missing, sending mutiple requests and getting more than one 40x with self.renewing: # wait for one thread to renew the lock while self.is_renewing: self.renewing.wait() if not self.token: self.login({}) return { self.request_header_name : self.token if self.token else "no token received" } def handle_forbidden(self, request_headers, status_code): self.login(request_headers) # retry whether there is a new token or not.... return True def login(self, request_headers): # only one of the threads will get the jwt token with self.renewing: # check if another thread as allready set the cookie to a different value if self.token == request_headers.get(self.request_header_name, None): try: self.is_renewing = True self.token = self.__renew_token__() finally: self.is_renewing = False self.renewing.notify_all() def __renew_token__(self): # looks as if we have to aquire a (new) JWT Token.... logger.debug("Requesting new Token from %s...", self.login_http_client.base_url) response = self.login_http_client.open() token = response.getheader(self.response_header_name) if token: logger.info("Received new Token") logger.debug("New Token: '%s...'", token[:42]) # log only start in order to avoid leak return token else: logger.error("Failed to renew Token, did not receive an %s header" % self.response_header_name) return self.token # try with old token, will try another login if token is invalid....
class KeepAlive(Thread): """ Used by Client to keep the session open. OPCUA defines timeout both for sessions and secure channel """ def __init__(self, client, timeout): """ :param session_timeout: Timeout to re-new the session in milliseconds. """ Thread.__init__(self) self.logger = logging.getLogger(__name__) self.client = client self._dostop = False self._cond = Condition() self.timeout = timeout # some server support no timeout, but we do not trust them if self.timeout == 0: self.timeout = 3600000 # 1 hour def run(self): self.logger.debug("starting keepalive thread with period of %s milliseconds", self.timeout) server_state = self.client.get_node(ua.FourByteNodeId(ua.ObjectIds.Server_ServerStatus_State)) while not self._dostop: with self._cond: self._cond.wait(self.timeout / 1000) if self._dostop: break self.logger.debug("renewing channel") try: self.client.open_secure_channel(renew=True) except concurrent.futures.TimeoutError: self.logger.debug("keepalive failed: timeout on open_secure_channel()") break val = server_state.get_value() self.logger.debug("server state is: %s ", val) self.logger.debug("keepalive thread has stopped") def stop(self): self.logger.debug("stoping keepalive thread") self._dostop = True with self._cond: self._cond.notify_all()
class ConditionWrapper(): def __init__(self, listener=None): self.__listeners = [] if(listener): self.add(listener) self.__condition = Condition() self.__waiting_event = object() self.__notify_event = object() self.__notify_all_event = object() def add(self, listener): self.__listeners.append(listener) def wait(self): print "wait" for listener in self.__listeners: listener.append(self.__waiting_event) self.__condition.wait() def notify_all(self): for listener in self.__listeners: listener.append(self.__notify_all_event) self.__condition.notify_all() def notify(self): for listener in self.__listeners: listener.append(self.__notify_event) self.__condition.notify() def __enter__(self): return self.__condition.__enter__() def __exit__(self, *args): return self.__condition.__exit__(*args) @property def waiting_event(self): return self.__waiting_event @property def notify_all_event(self): return self.__notify_all_event @property def notify_event(self): return self.__notify_event
class Ladron(Thread): def __init__(self, no_tengo_objetivo=None): Thread.__init__(self) self.__no_tengo_objetivo = no_tengo_objetivo or Condition() self.__hay_policias = Condition() self.__objetivo = None self.estoy_en_la_carcel = False def intentar_robo(self): if not self.objetivo.policias: self.objetivo.llega_ladron(self) print 'robando banco 2' time.sleep(0.2) print 'banco robado' def policias_en_movimiento(self, new_value, old_value, objetivo): print 'policias_en_movimiento' if not self.objetivo.policias: with self.__hay_policias: self.__hay_policias.notify_all() def run(self): Thread.run(self) with self.__no_tengo_objetivo: if not self.objetivo: self.__no_tengo_objetivo.wait() print 'observando' self.observe(self.objetivo, ['policias'], self.policias_en_movimiento) while(not self.estoy_en_la_carcel): with self.__hay_policias: self.__hay_policias.wait() self.intentar_robo() def a_la_carcel(self): self.estoy_en_la_carcel = True @property def objetivo(self): return self.__objetivo @objetivo.setter def objetivo(self, objetivo): with self.__no_tengo_objetivo: self.__objetivo = objetivo self.__no_tengo_objetivo.notify_all()
class _ContextFuture(object): def __init__(self, address, wait_for_tree=False): self.address = address self._result = None self._result_is_set = False self._condition = Condition() self._wait_for_tree = wait_for_tree self._tree_has_set = False def done(self): return self._result_is_set def result(self): with self._condition: self._condition.wait_for(lambda: self._result_is_set) return self._result def set_result(self, result, from_tree=False): """Set the addresses's value. If the _ContextFuture needs to be resolved from a read from the MerkleTree first, wait to set the value until _tree_has_set is True. Args: result (bytes): The value at an address. from_tree (bool): Whether the value is coming from the MerkleTree, or if it is set from prior state. Returns: None """ with self._condition: if self._wait_for_tree and not from_tree: self._condition.wait_for(lambda: self._tree_has_set) self._result = result self._result_is_set = True if self._wait_for_tree and from_tree: self._tree_has_set = True self._condition.notify_all()
class _BackgroundReader(Thread): daemon = True def __init__(self): super(_BackgroundReader, self).__init__() self.cond = Condition() self.read_fd, self.write_fd = os.pipe() self.buffer = io.BytesIO() self.finished = False def run(self): # noinspection PyBroadException try: while True: buf = os.read(self.read_fd, 1024 * 1024) if not buf: break self.buffer.write(buf) except Exception: sys.excepthook(*sys.exc_info()) interrupt_main() finally: with self.cond: self.finished = True os.close(self.read_fd) self.cond.notify_all() def wait(self): """ Call this when you know that everything has been written to self.write_fd. This waits until the thread has read everything from self.read_fd. """ with self.cond: os.close(self.write_fd) while True: if self.finished: return self.cond.wait()
class WaitableValue: def __init__(self, default=None): self._value = default self._condition = Condition(Lock()) def exchange_if(self, expected, new): """Compare and exchange. Returns the stored value, stores the new one if the stored value equals the expected""" with self._condition: if self._value == expected: old, self._value = self._value, new self._condition.notify_all() return old else: return self._value def set(self, value): """Update the stored value. Wake up threads waiting for a value""" with self._condition: self._value = value self._condition.notify_all() def get(self): """Return the current value""" with self._condition: return self._value def wait(self, timeout=None): """Wait for a value to be set()""" with self._condition: if self._condition.wait(timeout): return self._value else: raise TimeoutError def map(self, callback): """Perform an operation on the current value""" with self._condition: return callback(self._value)
class KeepAlive(Thread): """ Used by Client to keep session opened. OPCUA defines timeout both for sessions and secure channel """ def __init__(self, client, timeout): Thread.__init__(self) self.logger = logging.getLogger(__name__) if timeout == 0: # means no timeout bu we do not trust such servers timeout = 360000 self.timeout = timeout self.daemon = True self.client = client self._dostop = False self._cond = Condition() def run(self): self.logger.debug( "starting keepalive thread with period of %s milliseconds", self.timeout) server_state = self.client.get_node( ua.FourByteNodeId(ua.ObjectIds.Server_ServerStatus_State)) while not self._dostop: with self._cond: self._cond.wait(self.timeout / 1000) if self._dostop: break self.logger.debug("renewing channel") self.client.open_secure_channel(renew=True) val = server_state.get_value() self.logger.debug("server state is: %s ", val) self.logger.debug("keepalive thread has stopped") def stop(self): self.logger.debug("stoping keepalive thread") self._dostop = True with self._cond: self._cond.notify_all()
class Semaphore(object): def __init__(self, value=1): if value < 0: raise ValueError('semaphore initial value must be >= 0') self.__cond = Condition(Lock()) self.__value = value def acquire(self, blocking=1): rc = False with self.__cond: while self.__value == 0: if not blocking: break self.__cond.wait() else: self.__value = self.__value - 1 rc = True return rc __enter__ = acquire def release(self): with self.__cond: self.__value = self.__value + 1 self.__cond.notify() def release_multi(self, value): with self.__cond: self.__value = value self.__cond.notify_all() def __exit__(self, t, v, tb): self.release()
class StreamingOutput: """ File-like-proxy für die Aufnahme des Kamerabildes in einen Buffer und signalisierung wartender Threads auf Vorhandensein eines neuen Bildes. """ def __init__(self): #: Enthält den jeweils aktuellen Frame der Kamera nach Benachrichtung der :attr:`condition`. #: Darf nur im Kontext der :attr:`condition` abgefragt werden! self.frame = None #: Binärer Zwischenbuffer, der die einzelnen Frames der Kamera in :meth:`write` entgegen- #: nimmt. Wenn ein vollständiges Bild empfangen wurde, wird der Frame in :attr:`frame`` #: zwischengespeichert und die :attr:`conditon` benachrichtigt. self.buffer = io.BytesIO() #: Condition zu Synchronisierung des Zugriffs auf den :attr:`frame`. self.condition = Condition() def write(self, buf: bytes) -> int: """ Diese Methode nimmt die Binärdaten aus ``buf`` entgegen und speichert diese in einem Buffer zwischen. Sobald ein neues Bild beginnt, wird der Inhalt des Buffers in das Attribut :attr:`frame` übertragen und die Condition :attr:`condition` benachrichtigt, so dass alle wartenden Threads nach Erhalt der Benachrichtung das Bild aus :attr:`frame` abrufen können. Der Zugriff auf :attr:`frame` muss immer im Kontext der :attr:`condition` stattfinden! :returns: Die Anzahl der in den Buffer übertragenen Bytes. """ if buf[:2] == b'\xff\xd8': self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class DrawingThread(Thread): def __init__(self, game, theme=None, target_fps=60): super().__init__() self.game = game self.last_cycle_count = -1 self.target_fps = 60 self.exit_condition = Condition() self.screen = None if theme is None: self.theme = DefaultTheme() else: self.theme = theme def init_screen(self, screen_width, screen_height): screen_size = (screen_width, screen_height) screen_flags = DOUBLEBUF color_depth = pg.display.mode_ok(screen_size, screen_flags, 32) self.screen = pg.display.set_mode(screen_size, screen_flags, color_depth) def run(self): with self.exit_condition: while not self.exit_condition.wait(1 / self.target_fps): if self.catch_up(): self.theme.draw_board(self.screen, self.game.board) pg.display.flip() def is_dirty(self): return self.last_cycle_count != self.game.cycles def catch_up(self): result = self.is_dirty() self.last_cycle_count = self.game.cycles return result def quit(self): with self.exit_condition: self.exit_condition.notify_all()
class ThreadLoop(Thread): def __init__(self): Thread.__init__(self) self.loop = None self._cond = Condition() def start(self): with self._cond: Thread.start(self) self._cond.wait() def run(self): self.loop = asyncio.new_event_loop() logger.debug("Threadloop: %s", self.loop) self.loop.call_soon_threadsafe(self._notify_start) self.loop.run_forever() def _notify_start(self): with self._cond: self._cond.notify_all() def stop(self): self.loop.call_soon_threadsafe(self.loop.stop) self.join() self.loop.close() def post(self, coro): if not self.loop or not self.loop.is_running(): raise ThreadLoopNotRunning(f"could not post {coro}") futur = asyncio.run_coroutine_threadsafe(coro, loop=self.loop) return futur.result() def __enter__(self): self.start() return self def __exit__(self, exc_t, exc_v, trace): self.stop()
class LatestEEObs: def __init__(self): self._cv = Condition() self._latest_eep = None self._eep_sub = rospy.Subscriber('/robot/limb/right/endpoint_state', EndpointState, self._state_listener) def _state_listener(self, state_msg): pose = state_msg.pose with self._cv: self._latest_eep = np.array([ pose.position.x, pose.position.y, pose.position.z, pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z ]) self._cv.notify_all() def get_eep(self): with self._cv: self._cv.wait() ee = self._latest_eep return ee
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() def write(self, buf): if buf: # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() if self.frame: frame_cv = np.frombuffer(self.frame, np.uint8).reshape( (480, 640, 3)) cv2.putText(frame_cv, str(datetime.now()), (0, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 1, cv2.LINE_AA) (flag, self.frame) = cv2.imencode('.jpg', frame_cv) self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class StreamingOutput(object): def __init__(self, FaceApp): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() self.app = FaceApp def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available # Truncate returns current stream position self.buffer.truncate() with self.condition: # get value at current frame position self.frame = self.buffer.getvalue() self.frame = detectFace(self.frame) self.condition.notify_all() # Offset the frame to start of the stream self.buffer.seek(0) return self.buffer.write(buf)
class StreamingOutput(object): def __init__(self, camera): self.camera = camera self.frame = None self.buffer = io.BytesIO() self.condition = Condition() # self._longshutter = True def write(self, buf): # if self._longshutter: # self.camera.shutter_speed = 1000 # else: # self.camera.shutter_speed = 20 # self._longshutter = not self._longshutter if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class ThreadLoop(Thread): def __init__(self): Thread.__init__(self) self.loop = None self._cond = Condition() def start(self): with self._cond: Thread.start(self) self._cond.wait() def run(self): self.loop = asyncio.new_event_loop() with self._cond: self._cond.notify_all() self.loop.run_forever() def stop(self): self.loop.call_soon_threadsafe(self.loop.stop) def post(self, coro): futur = asyncio.run_coroutine_threadsafe(coro, loop=self.loop) return futur.result()
class LockWrapper: def __init__(self): self.__condition = Condition(lock=Lock()) def wait(self): self.__condition.wait() def notify(self): self.__condition.notify() def notify_all(self): self.__condition.notify_all() def acquire(self): acquired = False while not acquired: # saves from interruption by POSIX signal acquired = self.__condition.acquire() def release(self): try: self.__condition.release() except RuntimeError: pass # already released
class ThreadSafeCallback: def __init__(self): self.queue = [] self.condition = Condition() def add_func(self, func, t): with self.condition: heapq.heappush(self.queue, (time.time() + t, func)) self.condition.notify_all() def start_queue(self): while True: self.condition.acquire() while not self.queue: self.condition.wait() while self.queue and time.time() < self.queue[0][0]: self.condition.wait(self.queue[0][0] - time.time()) _, f = heapq.heappop(self.queue) f() self.condition.release()
class PeriodicTimer: def __init__(self, interval): self.interval = interval self._cv = Condition() self._flag = 0 def run(self): while True: time.sleep(self.interval) with self._cv: self._flag ^= 1 self._cv.notify_all() def start(self): t = Thread(target=self.run) t.daemon = True t.start() def wait_for_tick(self): with self._cv: last_flag = self._flag while last_flag == self._flag: self._cv.wait()
class Buffer(IdentityObject): def __init__(self, id): self.id = id self.loop = False self.deque = deque() self.condition = Condition() def start(self): self.clear() self.loop = True def stop(self): self.loop = False self.push("stop") def push(self, value): with self.condition: self.deque.append(value) self.condition.notify_all() def pop(self): while self.loop: with self.condition: if self.size() > 0: return self.deque.popleft() else: self.condition.wait() return None def size(self): with self.condition: value = len(self.deque) return value def clear(self): with self.condition: self.deque.clear()
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() def write(self, buf): global start_time, webserver, cap, out, rec_start_time, REC_TIME, begin_hour_started #if time.time() - start_time > 90: #webserver.shutdown() if time.time() - rec_start_time > REC_TIME or ( datetime.now().minute == 0 and datetime.now().second == 0 and not begin_hour_started): begin_hour_started = True handle_recording() if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all clients that's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) ret_val = self.buffer.write(buf) clone = copy.deepcopy(buf) try: image_as_file = io.BytesIO(clone) image_as_pil = Image.open(image_as_file).convert('RGB') image_as_cv = np.array(image_as_pil) image_as_cv = image_as_cv[:, :, ::-1].copy() #cv2.imwrite("test_cv.jpg", image_as_cv) #image_as_pil.save("test.jpg") out.write(image_as_cv) except Exception as e: print(e) return ret_val
class ZeroEvenOdd: def __init__(self, n): self.lock = Lock() self.n = n self.i = 0 self.zero_cv = Condition(self.lock) self._cv = Condition(self.lock) def zero(self, printNumber: 'Callable[[int], None]') -> None: while self.i < self.n: with self.lock: printNumber(0) #print('0') if self.i == 0: self.i = 1 self.zero_cv.notify_all() print('wait..') self._cv.wait() def even(self, printNumber: 'Callable[[int], None]') -> None: while self.i <= self.n: with self.lock: while self.i == 0 or self.i % 2: self.zero_cv.wait() printNumber(self.i) #print(self.i) self.i += 1 self._cv.notify() def odd(self, printNumber: 'Callable[[int], None]') -> None: while self.i <= self.n: with self.lock: while self.i == 0 or not self.i % 2: self.zero_cv.wait() printNumber(self.i) #print(self.i) self.i += 1 self._cv.notify()
class FizzBuzz: def __init__(self, n: int): self.n = n self._condition = Condition() self._counter = 1 # printFizz() outputs "fizz" def fizz(self, printFizz: 'Callable[[], None]') -> None: for i in range((self.n // 3) - (self.n // 15)): with self._condition: self._condition.wait_for( lambda: self._counter % 3 == 0 and self._counter % 15 != 0) printFizz() self._counter += 1 self._condition.notify_all() # printBuzz() outputs "buzz" def buzz(self, printBuzz: 'Callable[[], None]') -> None: for i in range((self.n // 5) - (self.n // 15)): with self._condition: self._condition.wait_for( lambda: self._counter % 5 == 0 and self._counter % 15 != 0) printBuzz() self._counter += 1 self._condition.notify_all() # printFizzBuzz() outputs "fizzbuzz" def fizzbuzz(self, printFizzBuzz: 'Callable[[], None]') -> None: for i in range(self.n // 15): with self._condition: self._condition.wait_for(lambda: self._counter % 15 == 0) printFizzBuzz() self._counter += 1 self._condition.notify_all() # printNumber(x) outputs "x", where x is an integer. def number(self, printNumber: 'Callable[[int], None]') -> None: n = self.n free_numbers = n - (n // 3) - (n // 5) + (n // 15) used = 0 with self._condition: for i in range(free_numbers): self._condition.wait_for( lambda: self._counter % 3 != 0 and self._counter % 5 != 0) printNumber(self._counter) self._counter += 1 self._condition.notify_all()
class File(): def __init__(self): self.file = [] self.cond = Condition() def ajoute(self): with self.cond: nb_alea = randint(0, 100) resultat = "" if (len(self.file) == 20): self.cond.wait() else: self.file.append(nb_alea) self.cond.notify_all() resultat = "Ajout de l'entier " + str(nb_alea) + " ..." return resultat return resultat def supprime(self): with self.cond: resultat = "" if (len(self.file) == 0): self.cond.wait() else: del self.file[0] self.cond.notify_all() resultat = "Retrait de " + str(self.file[0]) + " effectue ! " return resultat def fileToString(self): file_string = "<" for i in range(0, len(self.file)): file_string += str(self.file[i]) + "," file_string += "<" return file_string
class LatestEEObs: def __init__(self): self._cv = Condition() self._latest_eep = None self._eep_sub = rospy.Subscriber('/move_group/pose', geometry_msgs.msg.Pose, self._state_listener) def _state_listener(self, state_msg): # print('state_msg: ',state_msg) pose = state_msg with self._cv: self._latest_eep = np.array([ pose.position.x, pose.position.y, pose.position.z, pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z ]) self._cv.notify_all() def get_eep(self): with self._cv: self._cv.wait() ee = self._latest_eep return ee
class Frame(object): def __init__(self): self.frame = None self.length = 0 self.condition = Condition() def write_frame(self, frame): with self.condition: self.frame = frame self.condition.notify_all() return True def get_frame(self): return self.frame def wait_for_new_frame(self): with this.condition: this.condition.wait() return this.frame def save_frame_as_jpeg(self, path): f = open(path, "wb") f.write(self.frame) f.close()
class FooBar: def __init__(self, n): self.n = n self.condition = Condition() self.foo_counter = 0 self.bar_counter = 0 def foo(self, printFoo): for i in range(self.n): with self.condition: self.condition.wait_for( lambda: self.foo_counter == self.bar_counter) printFoo() self.foo_counter += 1 self.condition.notify_all() def bar(self, printBar): for i in range(self.n): with self.condition: self.condition.wait_for( lambda: self.foo_counter > self.bar_counter) printBar() self.bar_counter += 1 self.condition.notify_all()
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) global safeImage if safeImage: with io.open( '/home/pi/Babycam/AngularClient/dist/BabyCam/media/' + str(round(time.time() * 1000)) + '.jpg', 'wb') as file: file.write(buf) print('image saved') safeImage = False return self.buffer.write(buf)
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() self.engine = None self.obj_engine = None def set_engine(self, engine): self.engine = engine def set_obj_engine(self, obj_engine): self.obj_engine = obj_engine def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class PeriodicTimer: def __init__(self, interval): self._interval = interval self._flag = 0 self._cv = Condition() def start(self): t = Thread(target=self.run) t.daemon = True t.start() print(f'{t.getName()} is starting') def run(self): # set timer while True: time.sleep(self._interval) with self._cv: self._flag ^= 1 # 0/1 self._cv.notify_all() def wait_for_tick(self): with self._cv: last_flag = self._flag while last_flag == self._flag: self._cv.wait()
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() print("Initializing Stream Output") def write(self, buf): global count if count == 0: streaming_led.off() else: streaming_led.on() if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class Porta: def __init__(self, dim): self.dim = dim self.lock = RLock() self.fullInputCondition = Condition(self.lock) self.emptyOutputCondition = Condition(self.lock) self.input = BlockingQueue(dim) self.output = BlockingQueue(dim) def put(self, f): with self.lock: while len(self.input) == self.dim: self.fullInputCondition.wait() self.emptyOutputCondition.notify_all() self.input.put(f) def get(self): with self.lock: while len(self.output) == 0: self.emptyOutputCondition.wait() self.fullInputCondition.notify_all() self.input.get()
class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() self.last = datetime.now() def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue()[:] self.condition.notify_all() self.buffer.seek(0) if ENABLE_STATS: t1 = datetime.now() JPEG_FRAME_TIME.observe((t1 - self.last).total_seconds()) self.last = t1 return self.buffer.write(buf)