Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
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]
Ejemplo n.º 8
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:
Ejemplo n.º 9
0
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]
Ejemplo n.º 10
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]