NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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()