Exemple #1
0
 def enter(self):
     with Lock(self):
         assert not self.opened.is_set(), 'loop has been opened'
         self.opened.set()
     while True:
         pop = None
         timeout = None
         with Lock(self):
             if self.targets:
                 timeout = self.targets[0]['until'] - time.monotonic()
                 if timeout <= 0:
                     pop = self.targets.pop(0)
             elif self.closer.is_set():
                 self.closed.set()
                 break
             if pop is None:
                 self.wait.clear()
         if pop is not None:
             try:
                 pop['target'](*pop['args'], **pop['kwargs'])
             except BaseException as e:
                 try:
                     callable(pop['log']) and pop['log'](e)
                 except BaseException:
                     pass
         else:
             self.wait.wait(timeout=timeout)
Exemple #2
0
 def wrapper(self, *args, **kwargs):
     with Lock(self):
         assert getvar(self, '__withas__', d=0) == i and setvar(
             self, '__withas__', i + 1)
     try:
         return function(self, *args, **kwargs)
     except BaseException:
         with Lock(self):
             assert setvar(self, '__withas__', -1)
         raise
Exemple #3
0
 def _recv(self):
     with Lock(self):
         self.blocking = True
     try:
         return self.recver.recv()
     except TimeoutError:
         pass
     except EOFError:
         raise
     except BaseException as e:
         logger.exception(e)
     finally:
         with Lock(self):
             if not self.blocking:
                 raise EOFError
             self.blocking = False
Exemple #4
0
 def mark(self):
     assert threading.current_thread() is not self, 'may lead to deadlock'
     with Lock(self):
         if self.queue:
             mark = threading.Event()
             self.queue[-1].append(mark)
             return mark
Exemple #5
0
 def plant(self, *twigs, seize=False):
     ret = []
     if self.t < 0:
         for twig in twigs:
             b, r, = twig()
             if not b:
                 break
             ret.append(r)
         ret += [
             Tree.SEIZE,
         ] * (len(twigs) - len(ret))
     elif self.t == 0:
         for twig in twigs:
             b, r, = twig()
             ret.append(r if b else Tree.SEIZE)
     else:
         with Lock(self):
             targets = [{
                 'twig': twig,
                 'event': threading.Event(),
             } for twig in twigs]
             self.targets.extend(targets)
             for i in range(min(len(targets), self.t - self.running)):
                 threading.Thread(target=self._run).start()
                 self.running += 1
         for target in targets:
             target['event'].wait()
             b, r, = target['ret']
             ret.append(r if b else Tree.SEIZE)
     if not seize:
         for i in range(len(ret) - 1, -1, -1):
             if ret[i] is Tree.SEIZE:
                 ret.pop(i)
     return ret
Exemple #6
0
 def done(self):
     tid = threading.get_ident()
     with Lock(self):
         assert tid not in self.recv_black_l, 'mailbox already in use'
         if tid in self.marks:
             self.marks.pop(tid)
             self._gc()
Exemple #7
0
 def _wake(self):
     if self.closer.is_set():
         with Lock(self):
             if self.blocking:
                 if self.handle_t.empty():
                     self.blocking = False
                     self._shutdown()
         self.wait.set()
Exemple #8
0
 def _run(self):
     while True:
         with Lock(self):
             if self.targets:
                 target = self.targets.pop(0)
             else:
                 self.running -= 1
                 break
         target['ret'] = target['twig']()
         target['event'].set()
Exemple #9
0
 def want(self):
     tid = threading.get_ident()
     with Lock(self):
         assert tid not in self.recv_black_l, 'mailbox already in use'
         if tid not in self.marks:
             self.marks[tid] = len(self.queue) - 1
         else:
             if self.marks[tid] < len(self.queue) - 1:
                 self.marks[tid] += 1
                 self._gc()
Exemple #10
0
 def _gc(self):
     with Lock(self):
         if not self.marks:
             gc = len(self.queue) - 1
         else:
             gc = min(self.marks.values())
         if gc > 0:
             for _ in range(gc):
                 self.queue.pop(0)
             for k in self.marks:
                 self.marks[k] -= gc
Exemple #11
0
 def update(self, key, timeout=None):
     with Lock(self):
         if key in self._data:
             return self._data[key]
         else:
             if key not in self._wait:
                 self._wait[key] = threading.Event()
             wait = self._wait[key]
     if not wait.wait(timeout=timeout):
         raise TimeoutError
     return wait.value
Exemple #12
0
 def recv(self, timeout=None):
     tid = threading.get_ident()
     with Lock(self):
         assert tid not in self.recv_black_l, 'mailbox already in use'
         assert tid in self.marks, 'lack of calling want'
         event = self.queue[self.marks[tid]]
     if not event.wait(timeout=timeout):
         raise TimeoutError
     if event.data is None:
         raise EOFError
     return event.data
Exemple #13
0
 def run(self):
     while True:
         self.wait.wait()
         with Lock(self):
             data = self.queue[0].pop(0)
         eof = data is None
         self._handle(data)
         del data
         with Lock(self):
             for mark in self.queue.pop(0):
                 mark.set()
             mark = None
             if eof:
                 break
             if not self.queue:
                 self.wait.clear()
                 wake = True
             else:
                 wake = False
         if wake:
             self.waker()
     self.closed.set()
Exemple #14
0
 def run(self):
     closed = False
     while not closed:
         self.wait.wait()
         with Lock(self):
             if self.closed is not None:
                 closed = True
             queue = self.queue.copy()
             self.queue.clear()
             self.wait.clear()
         while queue:
             self._send(queue.pop(0))
     self.closed.set()
Exemple #15
0
 def _send(self, data, *cc):
     cc = list(cc)
     with Lock(self):
         while cc:
             cc.pop(0)(data)
         if data is not None:
             if self.marks:
                 self.queue[-1].data = data
                 self.queue[-1].set()
                 self.queue.append(threading.Event())
         else:
             self.queue[-1].data = None
             self.queue[-1].set()
Exemple #16
0
 def loads(self):
     primary = self._data.primary
     if primary is not None:
         with Database(**self._data._database) as cursor:
             cursor.execute(
                 'select data from ' + self._data._table +
                 ' where id=%s', (primary, ))
             row = cursor.fetchone()
             return json.loads((row['data'] if row else '')
                               or '{}').get(self._name, {})
     else:
         with Lock(self._data):
             return json.loads(self._data._data
                               or '{}').get(self._name, {})
Exemple #17
0
 def saves(self, updates):
     primary = self._data.primary
     if primary is not None:
         with Database(**self._data._database) as cursor:
             cursor.execute(
                 'select data from ' + self._data._table +
                 ' where id=%s for update', (primary, ))
             row = cursor.fetchone()
             obj = json.loads((row['data'] if row else '') or '{}')
             if updates is None:
                 if self._name in obj:
                     obj.pop(self._name)
             else:
                 obj[self._name] = value_not_none(
                     safe_sum(obj.get(self._name, {}), updates))
                 if not obj[self._name]:
                     obj.pop(self._name)
             assert isjson(obj)
             cursor.execute(
                 'update ' + self._data._table +
                 ' set data=%s where id=%s', (
                     json.dumps(obj) if obj else '',
                     primary,
                 ))
     else:
         with Lock(self._data):
             obj = json.loads(self._data._data or '{}')
             if updates is None:
                 if self._name in obj:
                     obj.pop(self._name)
             else:
                 obj[self._name] = value_not_none(
                     safe_sum(obj.get(self._name, {}), updates))
                 if not obj[self._name]:
                     obj.pop(self._name)
             assert isjson(obj)
             self._data._data = json.dumps(obj) if obj else ''
Exemple #18
0
 def empty(self):
     with Lock(self):
         return not self.queue
Exemple #19
0
 def __enter__(self):
     tid = threading.get_ident()
     with Lock(self):
         self.recv_black_l.append(tid)
Exemple #20
0
 def request(self, session, arguments):
     with Lock(session):
         with Throw(session) as r:
             if not r:
                 type(self).load(session)
Exemple #21
0
 def __exit__(self, t, v, tb):
     tid = threading.get_ident()
     with Lock(self):
         self.recv_black_l.remove(tid)
Exemple #22
0
 def handle(self, data):
     with Lock(self):
         self.queue.append([data, ])
     self.wait.set()
Exemple #23
0
 def close(self):
     with Lock(self):
         if self.closed is None:
             self.closed = threading.Event()
     self.wait.set()
     self.closed.wait()
Exemple #24
0
 def send(self, data):
     with Lock(self):
         assert self.closed is None, 'send has been closed'
         self.queue.append(data)
     self.wait.set()
Exemple #25
0
 def exit(self):
     with Lock(self):
         self.closer.set()
         if not self.opened.is_set() and not self.targets:
             self.closed.set()
     self.wait.set()