Пример #1
0
void zmq::pollset_t::loop ()
{
    struct pollfd polldata_array[max_io_events];

    while (!stopping) {

        //  Execute any due timers.
        int timeout = (int) execute_timers ();

        //  Wait for events.
        int n = pollset_poll(pollset_fd, polldata_array, max_io_events, 
            timeout ? timeout : -1);
        if (n == -1) {
            errno_assert (errno == EINTR);
            continue;
        }

        for (int i = 0; i < n; i ++) {
            poll_entry_t *pe = fd_table [polldata_array [i].fd];
            if (!pe)
                continue;

            if (pe->fd == retired_fd)
                continue;
            if (polldata_array [i].revents & (POLLERR | POLLHUP))
                pe->events->in_event ();
            if (pe->fd == retired_fd)
               continue;
            if (polldata_array [i].revents & POLLOUT)
                pe->events->out_event ();
            if (pe->fd == retired_fd)
                continue;
            if (polldata_array [i].revents & POLLIN)
                pe->events->in_event ();
        }

        //  Destroy retired event sources.
        for (retired_t::iterator it = retired.begin (); it != retired.end ();
              ++it)
            LIBZMQ_DELETE(*it);
        retired.clear ();
    }
}
Пример #2
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;
}
Пример #3
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;
  }
}