Ejemplo n.º 1
0
int picoev_update_events_internal(picoev_loop* _loop, int fd, int events)
{
  picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop;
  picoev_fd* target = picoev.fds + fd;
  
  assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd));
  
  /* initialize if adding the fd */
  if ((events & PICOEV_ADD) != 0) {
    target->_backend = -1;
  }
  /* return if nothing to do */
  if (events == PICOEV_DEL
      ? target->_backend == -1
      : (events & PICOEV_READWRITE) == target->events) {
    return 0;
  }
  /* add to changed list if not yet being done */
  if (target->_backend == -1) {
    target->_backend = BACKEND_BUILD(loop->changed_fds, target->events);
    loop->changed_fds = fd;
  }
  /* update events */
  target->events = events & PICOEV_READWRITE;
  /* apply immediately if is a DELETE */
  if ((events & PICOEV_DEL) != 0) {
    apply_pending_changes(loop, 1);
  }
  
  return 0;
}
Ejemplo n.º 2
0
int picoev_poll_once_internal(picoev_loop* _loop, int max_wait)
{
  picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop;
  struct timespec ts;
  int cl_off = 0, nevents, i;
  
  /* apply pending changes, with last changes stored to loop->changelist */
  cl_off = apply_pending_changes(loop, 0);
  
  ts.tv_sec = max_wait;
  ts.tv_nsec = 0;
  nevents = kevent(loop->kq, loop->changelist, cl_off, loop->events,
		   sizeof(loop->events) / sizeof(loop->events[0]), &ts);
  if (nevents == -1) {
    /* the errors we can only rescue */
    assert(errno == EACCES || errno == EFAULT || errno == EINTR);
    return -1;
  }
  for (i = 0; i < nevents; ++i) {
    struct kevent* event = loop->events + i;
    picoev_fd* target = picoev.fds + event->ident;
    assert((event->flags & EV_ERROR) == 0); /* changelist errors are fatal */
    if (loop->loop.loop_id == target->loop_id
	&& (event->flags & (EVFILT_READ | EVFILT_WRITE)) != 0) {
      int revents = ((event->flags & EVFILT_READ) != 0 ? PICOEV_READ : 0)
	| ((event->flags & EVFILT_WRITE) != 0 ? PICOEV_WRITE : 0);
      (*target->callback)(&loop->loop, event->ident, revents,
			  target->cb_arg);
    }
  }
  
  return 0;
}
Ejemplo n.º 3
0
int picoev_poll_once_internal(picoev_loop* _loop, int max_wait)
{
  picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop;
  struct timespec ts;
  int cl_off = 0, nevents, i;
  
  /* apply pending changes, with last changes stored to loop->changelist */
  cl_off = apply_pending_changes(loop, 0);
  
  ts.tv_sec = max_wait;
  ts.tv_nsec = 0;

  Py_BEGIN_ALLOW_THREADS
  nevents = kevent(loop->kq, loop->changelist, cl_off, loop->events,
		   sizeof(loop->events) / sizeof(loop->events[0]), &ts);
  Py_END_ALLOW_THREADS
  cache_time_update();

  if (nevents == -1) {
    /* the errors we can only rescue */
    assert(errno == EACCES || errno == EFAULT || errno == EINTR);
    return -1;
  }
  for (i = 0; i < nevents; ++i) {
    struct kevent* event = loop->events + i;
    picoev_fd* target = picoev.fds + event->ident;
    assert((event->flags & EV_ERROR) == 0); /* changelist errors are fatal */
    if (loop->loop.loop_id == target->loop_id
	&& (event->filter & (EVFILT_READ | EVFILT_WRITE)) != 0) {
      int revents;
      switch (event->filter) {
      case EVFILT_READ:
	revents = PICOEV_READ;
	break;
      case EVFILT_WRITE:
	revents = PICOEV_WRITE;
	break;
      default:
	assert(0);
	revents = 0; // suppress compiler warning
	break;
      }
      (*target->callback)(&loop->loop, event->ident, revents, target->cb_arg);
    }
  }
  
  return 0;
}