1 import os, threading, time, logging
3 log = logging.getLogger("ashd.serve")
5 seqlk = threading.Lock()
17 class reqthread(threading.Thread):
18 def __init__(self, name=None):
20 name = "Request handler %i" % reqseq()
21 super(reqthread, self).__init__(name=name)
30 log.error("exception occurred when handling request", exc_info=True)
32 class closed(IOError):
34 super(closed, self).__init__("The client has closed the connection.")
36 class wsgithread(reqthread):
37 def __init__(self, **kwargs):
38 super(wsgithread, self).__init__(**kwargs)
45 def writehead(self, status, headers):
47 def writedata(self, data):
50 def write(self, data):
59 raise Exception("Cannot send response body before starting response.")
61 self.writehead(self.status, self.headers)
63 def startreq(self, status, headers, exc_info=None):
65 if exc_info: # Nice calling convetion ^^
68 raise exc_info[0], exc_info[1], exc_info[2]
70 exc_info = None # CPython GC bug?
72 raise Exception("Can only start responding once.")
74 self.headers = headers
79 respiter = self.handlewsgi()
86 if hasattr(respiter, "close"):
91 class calllimiter(object):
92 def __init__(self, limit):
94 self.lock = threading.Condition()
97 def waited(self, time):
99 raise RuntimeError("Waited too long")
105 while self.inflight >= self.limit:
107 self.waited(time.time() - start)
113 def __exit__(self, *excinfo):
122 def call(self, target):
129 class abortlimiter(calllimiter):
130 def waited(self, time):