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 (); } }
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; }
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; } }