示例#1
0
文件: aix.c 项目: sjw7453584/Server
int uv__io_check_fd(uv_loop_t* loop, int fd) {
  struct poll_ctl pc;

  pc.events = POLLIN;
  pc.cmd = PS_MOD;  /* Equivalent to PS_ADD if the fd is not in the pollset. */
  pc.fd = fd;

  if (pollset_ctl(loop->backend_fd, &pc, 1))
    return -errno;

  pc.cmd = PS_DELETE;
  if (pollset_ctl(loop->backend_fd, &pc, 1))
    abort();

  return 0;
}
示例#2
0
zmq::pollset_t::handle_t zmq::pollset_t::add_fd (fd_t fd_, i_poll_events *events_)
{
    poll_entry_t *pe = new (std::nothrow) poll_entry_t;
    alloc_assert (pe);

    pe->fd           = fd_;
    pe->flag_pollin  = false;
    pe->flag_pollout = false;
    pe->events       = events_;

    struct poll_ctl pc;
    pc.fd     = fd_;
    pc.cmd    = PS_ADD;
    pc.events = 0;

    int rc = pollset_ctl (pollset_fd, &pc, 1);
    errno_assert (rc != -1);

    //  Increase the load metric of the thread.
    adjust_load (1);

    if (fd_ >= fd_table.size ()) {
        fd_table.resize(fd_ + 1, NULL);
    }
    fd_table [fd_] = pe;
    return pe;
}
示例#3
0
文件: aix.c 项目: abouthiroppy/node
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
  struct pollfd* events;
  uintptr_t i;
  uintptr_t nfds;
  struct poll_ctl pc;

  assert(loop->watchers != NULL);
  assert(fd >= 0);

  events = (struct pollfd*) loop->watchers[loop->nwatchers];
  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];

  if (events != NULL)
    /* Invalidate events with same file descriptor */
    for (i = 0; i < nfds; i++)
      if ((int) events[i].fd == fd)
        events[i].fd = -1;

  /* Remove the file descriptor from the poll set */
  pc.events = 0;
  pc.cmd = PS_DELETE;
  pc.fd = fd;
  if(loop->backend_fd >= 0)
    pollset_ctl(loop->backend_fd, &pc, 1);
}
示例#4
0
void zmq::pollset_t::reset_pollout (handle_t handle_)
{
    poll_entry_t *pe = (poll_entry_t*) handle_;
    if (unlikely(!pe->flag_pollout)) {
        return;
    }

    struct poll_ctl pc;
    pc.fd     = pe->fd;
    pc.events = 0;

    pc.cmd = PS_DELETE;
    int rc = pollset_ctl (pollset_fd, &pc, 1);
    errno_assert (rc != -1);
    
    if (pe->flag_pollin) {
        pc.cmd    = PS_MOD;
        pc.events = POLLIN;
        rc = pollset_ctl (pollset_fd, &pc, 1);
        errno_assert (rc != -1);
    }
    pe->flag_pollout = false;
}
示例#5
0
void zmq::pollset_t::set_pollout (handle_t handle_)
{
    poll_entry_t *pe = (poll_entry_t*) handle_;
    if (likely (!pe->flag_pollout)) {
        struct poll_ctl pc;
        pc.fd     = pe->fd;
        pc.cmd    = PS_MOD;
        pc.events = POLLOUT;

        const int rc = pollset_ctl (pollset_fd, &pc, 1);
        errno_assert (rc != -1);

        pe->flag_pollout = true;        
    }
}
示例#6
0
void zmq::pollset_t::rm_fd (handle_t handle_)
{
    poll_entry_t *pe = (poll_entry_t*) handle_;

    struct poll_ctl pc;
    pc.fd = pe->fd;
    pc.cmd = PS_DELETE;
    pc.events = 0;
    pollset_ctl (pollset_fd, &pc, 1);

    fd_table [pe->fd] = NULL;

    pe->fd = retired_fd;
    retired.push_back (pe);

    //  Decrease the load metric of the thread.
    adjust_load (-1);
}
示例#7
0
int Rpollset()
{
#ifdef  AIX
    int servfd = listen_net(g_port);
    if (servfd < 0)
    {
        printf("listen_net failed:%s \n", strerror(errno));
        return -1;
    }

    struct poll_ctl  pollset[CLIENT_NUM];

    for(int i = 0; i< CLIENT_NUM; i++)
    {
        pollset[i].fd = my_accept(servfd);
        if (pollset[i].fd < 0)
        {
            printf("my_accept failed %s\n", strerror(errno));
            return -1;
        }
        int buff = 1024*1024;
        socklen_t len = sizeof(int);
        if(setsockopt(pollset[i].fd , SOL_SOCKET,SO_RCVBUF , &buff , len) == -1)
        {
            printf("setsockopt SO_RCVBUF failed:%s\n", strerror(errno));
        }
        if(setsockopt(pollset[i].fd , SOL_SOCKET,SO_SNDBUF , &buff , len) == -1)
        {
            printf("setsockopt SO_SNDBUF failed:%s\n", strerror(errno));
        }
    }

    pollset_t ps = pollset_create(-1);
    if(ps < 0)
    {
        printf("pollset_create failed %s\n",strerror(errno));
        return -1;
    }

    for(int i = 0; i< CLIENT_NUM; i++)
    {
        pollset[i].events = POLLIN;
        pollset[i].cmd = PS_ADD;
        printf("my_accept clifd[%d] %d\n", i , pollset[i].fd);
    }

    nRet = pollset_ctl(ps, pollset, CLIENT_NUM);
    if(nRet < 0)
    {
        printf("pollset_ctl failed %s\n",strerror(errno));
        return -1;
    }

    char  buff[MAX_FD][1024];
    int   readlen[MAX_FD];
    memset(buff, 0, MAX_FD*1024);
    memset(readlen, 0, sizeof(readlen));

    struct pollfd fds[CLIENT_NUM];
    memset(fds, 0, sizeof(fds));
    int conn = CLIENT_NUM;
    int nRet = 0;
    gettimeofday(&time_c, NULL);
    while (true)
    {
        if (_HandleSignal() < 0)
            break;

        if (conn == 0)
        {
            printf("no fd poll\n");
            break;
        }
        if (g_count2 >= loop_times && loop_times != 0)
        {
            printf("finish\n");
            break;
        }
        gettimeofday(&time_a, NULL);
        nRet = pollset_poll(ps, fds, CLIENT_NUM, -1);
        gettimeofday(&time_b, NULL);
        if (nRet < 0)
        {
            printf("poll failed %s\n", strerror(errno));
            break;
        }

        unsigned long long use_time0 = (time_b.tv_sec - time_a.tv_sec) * 1000000 + (time_b.tv_usec - time_a.tv_usec);
        total_time0 += use_time0;
        g_count0++;

        for(int i = 0; i< CLIENT_NUM; i++)
        {
            if(fds[i].fd > 0 && (fds[i].revents & (POLLIN | POLLERR)))
            {
                gettimeofday(&time_e, NULL);
                nRet = read(fds[i].fd, buff[fds[i].fd]+readlen[fds[i].fd], g_len-readlen[fds[i].fd]);
                gettimeofday(&time_f, NULL);
                if (nRet == 0)
                {
                    printf("%d fd %d close\n", i, fds[i].fd);
                    struct poll_ctl  delset;
                    delset.cmd = PS_DELETE;
                    delset.fd = fds[i].fd;
                    nRet = pollset_ctl(ps, &delset, 1);
                    if(nRet < 0)
                    {
                        printf("pollset_ctl failed %s\n",strerror(errno));
                        return -1;
                    }
                    fds[i].fd = -1;
                    conn -- ;
                    break;
                }
                if (nRet < 0)
                {
                    printf("%d fd %d err %s \n", i, fds[i].fd,strerror(errno));
                    fds[i].fd = -1;
                    conn -- ;
                    break;
                }

                unsigned long long use_time1 = (time_f.tv_sec - time_e.tv_sec) * 1000000 + (time_f.tv_usec - time_e.tv_usec);
                total_time1 += use_time1;
                g_count1++;

                if (nRet != g_len-readlen[fds[i].fd])//没读完
                {
                    readlen[fds[i].fd] += nRet;
                }
                else if (nRet == g_len-readlen[fds[i].fd])//读完
                {
                    if(g_verify == 1 && buff[fds[i].fd][0] != 'a')
                    {
                        printf("format error %s\n", buff[fds[i].fd]);
                        return -1;
                    }
                    readlen[fds[i].fd] = 0;
                    g_count2++;
                    memcpy(rbuff, buff[fds[i].fd], sizeof(buff[fds[i].fd]));
                    memset(buff[fds[i].fd], 0, sizeof(buff[fds[i].fd]));
                }

            }
        }

    }
    gettimeofday(&time_d, NULL);


    unsigned long long use_time2 = (time_d.tv_sec - time_c.tv_sec) * 1000000 + (time_d.tv_usec - time_c.tv_usec);
    total_time2 += use_time2;

    nRet = pollset_destroy(ps);
    if(nRet < 0)
    {
        printf("pollset_destroy failed %s\n",strerror(errno));
        return -1;
    }
#endif
    return 0;
}
示例#8
0
void uv__io_poll(uv_loop_t* loop, int timeout) {
  struct pollfd events[1024];
  struct pollfd pqry;
  struct pollfd* pe;
  struct poll_ctl pc;
  QUEUE* q;
  uv__io_t* w;
  uint64_t base;
  uint64_t diff;
  int nevents;
  int count;
  int nfds;
  int i;
  int rc;
  int add_failed;

  if (loop->nfds == 0) {
    assert(QUEUE_EMPTY(&loop->watcher_queue));
    return;
  }

  while (!QUEUE_EMPTY(&loop->watcher_queue)) {
    q = QUEUE_HEAD(&loop->watcher_queue);
    QUEUE_REMOVE(q);
    QUEUE_INIT(q);

    w = QUEUE_DATA(q, uv__io_t, watcher_queue);
    assert(w->pevents != 0);
    assert(w->fd >= 0);
    assert(w->fd < (int) loop->nwatchers);

    pc.events = w->pevents;
    pc.fd = w->fd;

    add_failed = 0;
    if (w->events == 0) {
      pc.cmd = PS_ADD;
      if (pollset_ctl(loop->backend_fd, &pc, 1)) {
        if (errno != EINVAL) {
          assert(0 && "Failed to add file descriptor (pc.fd) to pollset");
          abort();
        }
        /* Check if the fd is already in the pollset */
        pqry.fd = pc.fd;
        rc = pollset_query(loop->backend_fd, &pqry);
        switch (rc) {
        case -1: 
          assert(0 && "Failed to query pollset for file descriptor");
          abort();
        case 0:
          assert(0 && "Pollset does not contain file descriptor");
          abort();
        }
        /* If we got here then the pollset already contained the file descriptor even though
         * we didn't think it should. This probably shouldn't happen, but we can continue. */
        add_failed = 1;
      }
    }
    if (w->events != 0 || add_failed) {
      /* Modify, potentially removing events -- need to delete then add.
       * Could maybe mod if we knew for sure no events are removed, but
       * content of w->events is handled above as not reliable (falls back)
       * so may require a pollset_query() which would have to be pretty cheap
       * compared to a PS_DELETE to be worth optimizing. Alternatively, could
       * lazily remove events, squelching them in the mean time. */
      pc.cmd = PS_DELETE;
      if (pollset_ctl(loop->backend_fd, &pc, 1)) {
        assert(0 && "Failed to delete file descriptor (pc.fd) from pollset");
        abort();
      }
      pc.cmd = PS_ADD;
      if (pollset_ctl(loop->backend_fd, &pc, 1)) {
        assert(0 && "Failed to add file descriptor (pc.fd) to pollset");
        abort();
      }
    }

    w->events = w->pevents;
  }

  assert(timeout >= -1);
  base = loop->time;
  count = 48; /* Benchmarks suggest this gives the best throughput. */

  for (;;) {
    nfds = pollset_poll(loop->backend_fd,
                        events,
                        ARRAY_SIZE(events),
                        timeout);

    /* Update loop->time unconditionally. It's tempting to skip the update when
     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
     * operating system didn't reschedule our process while in the syscall.
     */
    SAVE_ERRNO(uv__update_time(loop));

    if (nfds == 0) {
      assert(timeout != -1);
      return;
    }

    if (nfds == -1) {
      if (errno != EINTR) {
        abort();
      }

      if (timeout == -1)
        continue;

      if (timeout == 0)
        return;

      /* Interrupted by a signal. Update timeout and poll again. */
      goto update_timeout;
    }

    nevents = 0;

    assert(loop->watchers != NULL);
    loop->watchers[loop->nwatchers] = (void*) events;
    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;

    for (i = 0; i < nfds; i++) {
      pe = events + i;
      pc.cmd = PS_DELETE;
      pc.fd = pe->fd;

      /* Skip invalidated events, see uv__platform_invalidate_fd */
      if (pc.fd == -1)
        continue;

      assert(pc.fd >= 0);
      assert((unsigned) pc.fd < loop->nwatchers);

      w = loop->watchers[pc.fd];

      if (w == NULL) {
        /* File descriptor that we've stopped watching, disarm it.
         *
         * Ignore all errors because we may be racing with another thread
         * when the file descriptor is closed.
         */
        pollset_ctl(loop->backend_fd, &pc, 1);
        continue;
      }

      w->cb(loop, w, pe->revents);
      nevents++;
    }

    loop->watchers[loop->nwatchers] = NULL;
    loop->watchers[loop->nwatchers + 1] = NULL;

    if (nevents != 0) {
      if (nfds == ARRAY_SIZE(events) && --count != 0) {
        /* Poll for more events but don't block this time. */
        timeout = 0;
        continue;
      }
      return;
    }

    if (timeout == 0)
      return;

    if (timeout == -1)
      continue;

update_timeout:
    assert(timeout > 0);

    diff = loop->time - base;
    if (diff >= (uint64_t) timeout)
      return;

    timeout -= diff;
  }
}