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