def Accept(sock): while True: try: return sock.accept() except socket.error, e: if e.args[0] != errno.EAGAIN: raise event.event(HandleWakeup, handle=sock.fileno(), evtype=event.EV_READ, arg=greenlet.getcurrent()).add() ScheduleRemove()
def ReadAtMost(fd, size): while True: try: return os.read(fd, size) except OSError, e: if e.errno != errno.EAGAIN: raise event.event(HandleWakeup, handle=fd, evtype=event.EV_READ, arg=greenlet.getcurrent()).add() ScheduleRemove()
def Write(fd, data): while True: try: got = os.write(fd, data) if got == len(data): return if got: data = data[got:] # TODO(pts): Do with less copy except OSError, e: if e.errno != errno.EAGAIN: raise event.event(HandleWakeup, handle=fd, evtype=event.EV_WRITE, arg=greenlet.getcurrent()).add() ScheduleRemove()
def Handler(cs, csaddr): print >> sys.stderr, 'info: connection from %r' % (cs.getpeername(), ) SetFdBlocking(cs, False) csfd = cs.fileno() # Read HTTP request. request = '' while True: # TODO(pts): Implement (in C) and use line buffering. got = ReadAtMost(csfd, 32768) assert got request += got i = request.find('\n\r\n') if i >= 0: j = request.find('\n\n') if j >= 0 and j < i: i = j + 2 else: i += 3 break else: i = request.find('\n\n') if i >= 0: i + 2 break head = request[:i] body = request[i:] # Parse HTTP request. # Please note that an assertion here aborts the server. i = head.find('\n') assert i > 0, (head, ) if head[i - 1] == '\r': line1 = head[:i - 1] else: line1 = head[:i] items = line1.split(' ') assert 3 == len(items) assert items[2] in ('HTTP/1.0', 'HTTP/1.1') assert items[0] == 'GET' assert items[1].startswith('/') try: num = int(items[1][1:]) except ValueError: num = None # Write HTTP response. if num is None: response = ('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n' '<a href="/0">start at 0</a><p>Hello, World!\n') else: next_num = lprng.Lprng(num).next() response = ('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n' '<a href="/%d">continue with %d</a>\n' % (next_num, next_num)) Write(csfd, response) cs.close() # No need for event_del, nothing listening (?). # TODO(pts): In a finally: block for all greenlets. #assert greenlet.getcurrent() is runnable_greenlets.popleft() runnable_greenlets.popleft() greenlet.getcurrent().parent = runnable_greenlets[0]
The old blocking value (True or False). """ if hasattr(fd, 'fileno'): fd = fd.fileno() old = fcntl.fcntl(fd, fcntl.F_GETFL) if is_blocking: value = old & ~os.O_NONBLOCK else: value = old | os.O_NONBLOCK if old != value: fcntl.fcntl(fd, fcntl.F_SETFL, value) return bool(old & os.O_NONBLOCK) runnable_greenlets = deque() main_greenlet = greenlet.getcurrent() main_loop_greenlet = None runnable_greenlets.append(main_greenlet) def SendExceptionAndRun(greenlet_obj, exc_info): """Send exception to greenlet, even if it's blocked on a channel. The specified greenlet is moved to runnable_greenlets to ensure that it eventually gets scheduled. Please note that this call is linear in the size of runnable_greenlets. """ if not isinstance(exc_info, list) and not isinstance(exc_info, tuple): raise TypeError if len(exc_info) < 3:
def Handler(cs, csaddr): print >>sys.stderr, 'info: connection from %r' % ( cs.getpeername(),) SetFdBlocking(cs, False) csfd = cs.fileno() # Read HTTP request. request = '' while True: # TODO(pts): Implement (in C) and use line buffering. got = ReadAtMost(csfd, 32768) assert got request += got i = request.find('\n\r\n') if i >= 0: j = request.find('\n\n') if j >= 0 and j < i: i = j + 2 else: i += 3 break else: i = request.find('\n\n') if i >= 0: i + 2 break head = request[:i] body = request[i:] # Parse HTTP request. # Please note that an assertion here aborts the server. i = head.find('\n') assert i > 0, (head,) if head[i - 1] == '\r': line1 = head[:i - 1] else: line1 = head[:i] items = line1.split(' ') assert 3 == len(items) assert items[2] in ('HTTP/1.0', 'HTTP/1.1') assert items[0] == 'GET' assert items[1].startswith('/') try: num = int(items[1][1:]) except ValueError: num = None # Write HTTP response. if num is None: response = ('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n' '<a href="/0">start at 0</a><p>Hello, World!\n') else: next_num = lprng.Lprng(num).next() response = ('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n' '<a href="/%d">continue with %d</a>\n' % (next_num, next_num)) Write(csfd, response) cs.close() # No need for event_del, nothing listening (?). # TODO(pts): In a finally: block for all greenlets. #assert greenlet.getcurrent() is runnable_greenlets.popleft() runnable_greenlets.popleft() greenlet.getcurrent().parent = runnable_greenlets[0]
The old blocking value (True or False). """ if hasattr(fd, 'fileno'): fd = fd.fileno() old = fcntl.fcntl(fd, fcntl.F_GETFL) if is_blocking: value = old & ~os.O_NONBLOCK else: value = old | os.O_NONBLOCK if old != value: fcntl.fcntl(fd, fcntl.F_SETFL, value) return bool(old & os.O_NONBLOCK) runnable_greenlets = deque() main_greenlet = greenlet.getcurrent() main_loop_greenlet = None runnable_greenlets.append(main_greenlet) def SendExceptionAndRun(greenlet_obj, exc_info): """Send exception to greenlet, even if it's blocked on a channel. The specified greenlet is moved to runnable_greenlets to ensure that it eventually gets scheduled. Please note that this call is linear in the size of runnable_greenlets. """ if not isinstance(exc_info, list) and not isinstance(exc_info, tuple): raise TypeError if len(exc_info) < 3: exc_info = list(exc_info) + [None, None]