def exceptionTest(self, cls): # check the nesting level and the ref counts def func(obj): 1 / 0 def helper(): # we need a close control over references to None here try: cls(func) except ZeroDivisionError: emsg = sys.exc_info()[1].args[0] return emsg self.fail("does not raise the expected exception") emsg = '' helper() # warm up gc.collect() with stackless.atomic(): rc_none = sys.getrefcount(None) rc_cls = sys.getrefcount(cls) # we need a close control over references to None here emsg = helper() rc_none2 = sys.getrefcount(None) rc_cls2 = sys.getrefcount(cls) self.assertEqual(rc_cls, rc_cls2) self.assertEqual(rc_none, rc_none2) self.assertIn("division by zero", emsg)
def lock(self): '''acquire the lock''' with stackless.atomic(): if self.capacity: self.capacity -= 1 else: self.queue.receive()
def nestingLevelTest(self, cls): # check the nesting level and the ref counts def func(obj=None): if obj is None: self.assertGreater(stackless.current.nesting_level, 0) return None self.assertIs(obj.__class__, cls) obj.nesting_level = stackless.current.nesting_level return None cls(func ).__class__ # the first access of __class__ releases 1 ref to None with stackless.atomic(): # None-refcount needs protection, it the test suite is multithreaded gc.collect() rc_none = rc_none2 = sys.getrefcount(None) rc_cls = rc_cls2 = sys.getrefcount(cls) c = cls(func) rc_none2 = sys.getrefcount(None) rc_cls2 = sys.getrefcount(cls) self.assertEqual(rc_none, rc_none2) self.assertEqual(rc_cls + 1, rc_cls2) # one ref for c self.assertEqual(sys.getrefcount(c) - sys.getrefcount(object()), 1) self.assertIs(c.__class__, cls) current_nesting_level = stackless.current.nesting_level if hasattr(c, "nesting_level"): if stackless.enable_softswitch(None): self.assertEqual(c.nesting_level, current_nesting_level) else: self.assertGreater(c.nesting_level, current_nesting_level) c = None gc.collect() self.assertEqual(sys.getrefcount(cls), rc_cls)
def uniqueId(): """Returns a unique number ID. This function is thread safe""" global idIndex tmp = stackless.atomic() z = idIndex idIndex = z + 1 return z
def unlock(self): '''release the lock''' with stackless.atomic(): if self.queue.balance < 0: self.queue.send(None) else: self.capacity += 1
def unbind_restorable_tasklets(tid=None): current = stackless.current first = current.cstate unbound = set() found = True while found: with stackless.atomic(): found = False cstate = first.next while cstate is not first: tlet_running = cstate.task cstate = cstate.next if tlet_running is None: continue if tlet_running.alive and tlet_running.restorable and not tlet_running.is_main and not tlet_running.is_current: if tid is not None and tid != tlet_running.thread_id: continue assert tlet_running is not current if tlet_running.blocked: tlet_running.bind_thread() tlet_running.kill(pending=True) # unblock the tasklet tlet_running.remove() tlet_running.bind(None) found = True unbound.add(id(tlet_running)) time.sleep(0) print("unbound:", ["%08x" % i for i in unbound])
def returnTypeTest(self, cls): # check the nesting level and the ref counts def func(obj): return "not None" def helper(): # we need a close control over references to None here try: cls(func) except TypeError: emsg = sys.exc_info()[1].args[0] return emsg self.fail("does not raise the expected exception") helper() # warm up. gc.collect() with stackless.atomic(): rc_none = sys.getrefcount(None) rc_cls = sys.getrefcount(cls) # we need a close control over references to None here emsg = helper() rc_none2 = sys.getrefcount(None) rc_cls2 = sys.getrefcount(cls) self.assertEqual(rc_cls, rc_cls2) self.assertEqual(rc_none, rc_none2) self.assertIn("__init__() should return None", emsg)
def testAtomicNopCtxt(self): old = stackless.getcurrent().atomic stackless.getcurrent().set_atomic(True) try: with stackless.atomic(): self.assertTrue(stackless.getcurrent().atomic) finally: stackless.getcurrent().set_atomic(old)
def runner_func(recursive, start): if recursive: stackless.tasklet(runner_func)(recursive-1, start) with stackless.atomic(): stackless.run(2, soft=soft, totaltimeout=True, ignore_nesting=True) a = self.awoken self.awoken += 1 if recursive == start: # we are the first watchdog self.assertEqual(a, 0) #the first to wake up self.done += 1 # we were interrupted t1.kill() t2.kill()
def runner_func(recursive, start): if recursive: stackless.tasklet(runner_func)(recursive - 1, start) with stackless.atomic(): stackless.run(2, soft=soft, totaltimeout=True, ignore_nesting=True) a = self.awoken self.awoken += 1 if recursive == start: # we are the first watchdog self.assertEqual(a, 0) #the first to wake up self.done += 1 # we were interrupted t1.kill() t2.kill()
def testRunOrder(self): def a(): self.events.append(0) def b(): self.events.append(1) def c(): self.events.append(2) (t1, t2, t3), thread = GetRemoteTasklets((a, b, c)) try: with stackless.atomic(): t2.insert() t3.insert() t1.run() #t1 should run first finally: thread.join(2) self.assertEqual(self.events, list(range(3)))
def acquire(self): """ Tries to acquire the semaphore and if it can't, it blocks until it can. """ global semaphoreID global semaphores global semaphoreLockStats global semaphoreLockCheck tmp = stackless.atomic() lockStats = semaphoreLockStats[self.name] if self.count == 0: if self.thread is stackless.getcurrent(): raise RuntimeError("Deadlock", "Thread trying to reaquire this semaphore") before = time() try: self.numwaiting = self.numwaiting + 1 while True: timeout = self.waiting.receive() if timeout is None: break elif timeout == _SEM_GET_WAITING: self.callback.send((traceback.format_list(traceback.extract_stack(None,40)[:-1]),before,)) elif timeout == _SEM_PROBLEM: print "Semaphore problem" traceback.print_exc() else: print "CSemaphore : Unknown command" finally: self.numwaiting = self.numwaiting + 1 now = time() diff = now - before lockStats.waitCount = lockStats.waitCount + 1 lockStats.sumWait = lockStats.sumWait + diff if diff > lockStats.maxWait: lockStats.maxWait = diff lockStats.acquireCount = lockStats.acquireCount + 1 else: self.count = self.count - 1 lockStats.receiveMax = lockStats.receiveMax + 1 now = time() self.lockedWhen = now if semaphoreLockCheck: self.frame = sys._getframe() self.thread = stackless.getcurrent()
def get_tasklets_with_cstate(): """Return a list of all tasklets with a C-stack. """ tlets = [] current = stackless.current if current.nesting_level > 0: tlets.append(current) with stackless.atomic(): cscurrent = current.cstate cs = cscurrent.next while cs is not cscurrent: t = cs.task if (t is not None and t.cstate is cs and t.alive and t.nesting_level > 0): assert t not in tlets tlets.append(t) cs = cs.next return tlets
def testSimpleLeakage(self): leakage = [] with stackless.atomic(): gc.collect(2) before = frozenset(id(o) for o in gc.get_objects()) for i in f(): pass gc.collect(2) after = gc.get_objects() for x in after: if x is not before and id(x) not in before: leakage.append(x) if len(leakage): self.failUnless(len(leakage) == 0, "Leaked %s" % repr(leakage))
def release(self): """Releases the previously aquired semaphore""" global semaphoreID global semaphores global semaphoreLockStats global semaphoreLockCheck tmp = stackless.atomic() lockStats = semaphoreLockStats[self.semaphoreName] diff = time() - self.lockedWhen self.lockedWhen = None lockStats.sumLockTime = lockStats.sumLockTime + diff if diff > lockStats.maxLockTime: lockStats.maxLockTime = diff if semaphoreLockCheck: self.frame = None self.thread = None if self.waiting.queue: self.waiting.send(None) else: self.count = self.count + 1
def testSimpleLeakage(self): leakage = [] with stackless.atomic(): gc.collect(2) before = frozenset(id(o) for o in gc.get_objects()) for i in f(): pass gc.collect(2) after = gc.get_objects() for x in after: if x is not before and id(x) not in before: leakage.append(x) try: __in_psyco__ # @UndefinedVariable relevant = False except NameError: relevant = True if relevant and len(leakage): self.assertTrue(len(leakage) == 0, "Leaked %s" % repr(leakage))
def acquire(self): tmp = stackless.atomic() if self.count == 0: self.waiting.receive() else: self.count = self.count - 1
def release(self): tmp = stackless.atomic() if self.waiting.queue: self.waiting.send(None) else: self.count = self.count + 1
def signal_all(self, value=None): """send(value) for every waiting tasklet""" with atomic(): for i in xrange(-self.balance): assert self.balance < 0 self.send(value)
def signal(self, value=None): """send(value) if someone is waiting""" with atomic(): if self.balance < 0: self.send(value)
def get(self): tmp = stackless.atomic() if self.contents: return self.contents.pop(0) return self.channel.receive()
def unget(self, x): tmp = stackless.atomic() self.contents.insert(0, x)
def irandom(n): """Returns a thread safe random number generator in the range 0...n""" tmp = stackless.atomic() n = random.randrange(0, n) return n
def put(self, x): tmp = stackless.atomic() self.contents.append(x) while self.channel.queue and self.contents: self.channel.send(self.contents.pop(0))
def add(self): tmp = stackless.atomic() thread = stackless.getcurrent() self.ch.receive()