1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
from queue import Queue import select
class Task(object): taskid = 0
def __init__(self,target): Task.taskid += 1
self.tid = Task.taskid self.target = target self.sendval = None
def run(self): return self.target.send(self.sendval)
class Scheduler(object): def __init__(self): self.ready = Queue() self.taskmap = {} self.exit_waiting = {} self.read_waiting = {} self.write_waiting = {}
def new(self, target): newtask = Task(target) self.taskmap[newtask.tid] = newtask self.schedule(newtask) return newtask.tid
def exit(self, task): print('Task %d terminated' % task.tid) del self.taskmap[task.tid] for task in self.exit_waiting.pop(task.tid,[]): self.schedule(task)
def waitforexit(self, task, waittid): if waittid in self.taskmap: self.exit_waiting.setdefault(waittid, []).append(task) return True else: return False
def waitforread(self,task,fd): self.read_waiting[fd] = task
def waitforwrite(self,task,fd): self.write_waiting[fd] = task
def iopoll(self, timeout): if self.read_waiting or self.write_waiting: r, w, e = select.select(self.read_waiting, self.write_waiting,[],timeout) for fd in r: self.schedule(self.read_waiting.pop(fd)) for fd in w: self.schedule(self.write_waiting.pop(fd))
def iotask(self): while True: if self.ready.empty(): self.iopoll(None) else: self.iopoll(0) yield
def schedule(self, task): self.ready.put(task)
def mainloop(self): self.new(self.iotask()) while self.taskmap: task = self.ready.get() try: result = task.run() if isinstance(result, SystemCall): result.task = task result.sched = self result.handle() continue
except StopIteration: self.exit(task) continue
self.schedule(task)
class SystemCall(object): task: Task sched: Scheduler
def handle(self): pass
class GetTid(SystemCall): def handle(self): self.task.sendval = self.task.tid self.sched.schedule(self.task)
class NewTask(SystemCall): def __init__(self,target): self.target = target
def handle(self): tid = self.sched.new(self.target) self.task.sendval = tid self.sched.schedule(self.task)
class KillTask(SystemCall): def __init__(self,tid): self.tid = tid
def handle(self): task = self.sched.taskmap.get(self.tid,None) if task: task.target.close() self.task.sendval = True else: self.task.sendval = False self.sched.schedule(self.task)
class WaitTask(SystemCall): def __init__(self, tid): self.tid = tid
def handle(self): result = self.sched.waitforexit(self.task, self.tid) self.task.sendval = result if not result: self.sched.schedule(self.task)
class ReadWait(SystemCall): def __init__(self,f): self.f = f
def handle(self): fd = self.f.fileno() self.sched.waitforread(self.task,fd)
class WriteWait(SystemCall): def __init__(self,f): self.f = f
def handle(self): fd = self.f.fileno() self.sched.waitforwrite(self.task,fd)
|