stacklessimpl.py (3476B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\uthread2_plugins\stacklessimpl.py 2 import stackless 3 import sys 4 import time 5 import weakref 6 import uthread 7 from stacklesslib import locks, main 8 try: 9 from stacklesslib.util import qchannel 10 except ImportError: 11 from stacklesslib.util import QueueChannel as qchannel 12 13 from . import BaseUthreadImpl, Tasklet, stackless_sleep, BaseSemaphore, BaseChannel, pop_stackless_tracing_enabled 14 15 def is_main(): 16 return stackless.getcurrent() == stackless.getmain() 17 18 19 _tasklets = weakref.WeakKeyDictionary() 20 21 class StacklessTasklet(Tasklet): 22 23 def __init__(self, func, *args, **kwargs): 24 pop_stackless_tracing_enabled(kwargs) 25 26 def inner(): 27 _tasklets[stackless.getcurrent()] = self 28 func(*args, **kwargs) 29 30 self.tasklet = stackless.tasklet(inner)() 31 32 def is_alive(self): 33 return self.tasklet.alive 34 35 def kill(self): 36 self.tasklet.kill() 37 38 def get(self): 39 while self.tasklet.alive: 40 stackless_sleep.sleep(0.005) 41 42 43 class StacklessSemaphore(BaseSemaphore): 44 45 def __init__(self): 46 self.__semaphore = uthread.Semaphore() 47 48 def __enter__(self): 49 self.__semaphore.__enter__() 50 51 def __exit__(self, exc, val, tb): 52 self.__semaphore.__exit__(exc, val, tb) 53 54 def acquire(self): 55 self.__semaphore.acquire() 56 57 def release(self): 58 self.__semaphore.release() 59 60 61 class StacklessEvent(locks.Event): 62 63 def wait(self, timeout = None): 64 if not is_main(): 65 res = locks.Event.wait(self, timeout) 66 return res 67 if self.is_set(): 68 return True 69 if timeout is None: 70 timeout = sys.maxint 71 endtime = time.time() + timeout 72 while not self.is_set() and time.time() < endtime: 73 stackless_sleep.sleep(0.005) 74 75 return self.is_set() 76 77 78 class Channel(BaseChannel): 79 80 def __init__(self, preference): 81 self.channel = stackless.channel() 82 self.channel.preference = preference 83 84 def send(self, data): 85 self.channel.send(data) 86 87 def receive(self): 88 return self.channel.receive() 89 90 91 class _StacklessUthread(BaseUthreadImpl): 92 93 def sleep(self, seconds): 94 stackless_sleep.sleep(seconds) 95 96 def start_tasklet(self, func, *args, **kwargs): 97 return StacklessTasklet(func, *args, **kwargs) 98 99 def yield_(self): 100 main.mainloop.wakeup_tasklets(None) 101 if stackless.getcurrent() == stackless.getmain(): 102 stackless.run() 103 104 def get_current(self): 105 return _tasklets.get(stackless.getcurrent(), None) 106 107 def wait(self, tasklets, timeout): 108 deadline = time.time() + timeout 109 while time.time() < deadline: 110 alive = [ tasklet.is_alive() for tasklet in tasklets ] 111 if not all(alive): 112 return 113 self.sleep(0.005) 114 115 for tasklet in tasklets: 116 try: 117 tasklet.kill() 118 except Exception as e: 119 pass 120 121 def Event(self): 122 return StacklessEvent() 123 124 def Semaphore(self): 125 return StacklessSemaphore() 126 127 def BlockingChannel(self): 128 return Channel(-1) 129 130 def PumpChannel(self): 131 return Channel(1) 132 133 def QueueChannel(self): 134 return QueueChannel() 135 136 137 class QueueChannel(qchannel): 138 139 def __len__(self): 140 return len(self.data_queue) 141 142 143 StacklessImpl = _StacklessUthread()