Alien-uv

 view release on metacpan or  search on metacpan

libuv/src/unix/os390-syscalls.c  view on Meta::CPAN

    QUEUE_REMOVE(q);
    lst = QUEUE_DATA(q, uv__os390_epoll, member);
    uv__free(lst->items);
    lst->items = NULL;
    lst->size = 0;
  }

  uv_mutex_unlock(&global_epoll_lock);
  uv_mutex_destroy(&global_epoll_lock);
}


static void epoll_init(void) {
  QUEUE_INIT(&global_epoll_queue);
  if (uv_mutex_init(&global_epoll_lock))
    abort();

  if (pthread_atfork(&before_fork, &after_fork, &child_fork))
    abort();
}


uv__os390_epoll* epoll_create1(int flags) {
  uv__os390_epoll* lst;

  lst = uv__malloc(sizeof(*lst));
  if (lst != NULL) {
    /* initialize list */
    lst->size = 0;
    lst->items = NULL;
    init_message_queue(lst);
    maybe_resize(lst, 1);
    lst->items[lst->size - 1].fd = lst->msg_queue;
    lst->items[lst->size - 1].events = POLLIN;
    lst->items[lst->size - 1].revents = 0;
    uv_once(&once, epoll_init);
    uv_mutex_lock(&global_epoll_lock);
    QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
    uv_mutex_unlock(&global_epoll_lock);
  }

  return lst;
}


int epoll_ctl(uv__os390_epoll* lst,
              int op,
              int fd,
              struct epoll_event *event) {
  uv_mutex_lock(&global_epoll_lock);

  if (op == EPOLL_CTL_DEL) {
    if (fd >= lst->size || lst->items[fd].fd == -1) {
      uv_mutex_unlock(&global_epoll_lock);
      errno = ENOENT;
      return -1;
    }
    lst->items[fd].fd = -1;
  } else if (op == EPOLL_CTL_ADD) {

    /* Resizing to 'fd + 1' would expand the list to contain at least
     * 'fd'. But we need to guarantee that the last index on the list 
     * is reserved for the message queue. So specify 'fd + 2' instead.
     */
    maybe_resize(lst, fd + 2);
    if (lst->items[fd].fd != -1) {
      uv_mutex_unlock(&global_epoll_lock);
      errno = EEXIST;
      return -1;
    }
    lst->items[fd].fd = fd;
    lst->items[fd].events = event->events;
    lst->items[fd].revents = 0;
  } else if (op == EPOLL_CTL_MOD) {
    if (fd >= lst->size - 1 || lst->items[fd].fd == -1) {
      uv_mutex_unlock(&global_epoll_lock);
      errno = ENOENT;
      return -1;
    }
    lst->items[fd].events = event->events;
    lst->items[fd].revents = 0;
  } else
    abort();

  uv_mutex_unlock(&global_epoll_lock);
  return 0;
}


int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events,
               int maxevents, int timeout) {
  nmsgsfds_t size;
  struct pollfd* pfds;
  int pollret;
  int reventcount;
  int nevents;

  _SET_FDS_MSGS(size, 1, lst->size - 1);
  pfds = lst->items;
  pollret = poll(pfds, size, timeout);
  if (pollret <= 0)
    return pollret;

  pollret = _NFDS(pollret) + _NMSGS(pollret);

  reventcount = 0;
  nevents = 0;
  for (int i = 0; 
       i < lst->size && i < maxevents && reventcount < pollret; ++i) {
    struct epoll_event ev;
    struct pollfd* pfd;

    pfd = &pfds[i];
    if (pfd->fd == -1 || pfd->revents == 0)
      continue;

    ev.fd = pfd->fd;
    ev.events = pfd->revents;
    if (pfd->revents & POLLIN && pfd->revents & POLLOUT)
      reventcount += 2;
    else if (pfd->revents & (POLLIN | POLLOUT))



( run in 1.607 second using v1.01-cache-2.11-cpan-5b529ec07f3 )