echo_io * make_echo_watcher(EV_P_ int wfd) { if (set_nonblocking(wfd) == -1) return 0; echo_io *watcher = malloc(sizeof(echo_io)); if (watcher) { msg_buf_init(&watcher->buf, server_ringbuf_capacity); watcher->half_closed = false; ev_io *io = &watcher->io; ev_io_init(io, echo_cb, wfd, EV_READ); ev_timer *timer = &watcher->timeout.timer; ev_init(timer, timeout_cb); watcher->timeout.last_activity = ev_now(EV_A); watcher->timeout.eio = watcher; timeout_cb(EV_A_ timer, EV_TIMER); } return watcher; }
void pubnub_sync_wait(struct pubnub *p, void *ctx_data) { struct pubnub_sync *sync = (struct pubnub_sync *)ctx_data; while (!sync->stop) { DBGMSG("=polling= for %d (timeout %p)\n", sync->n, sync->timeout_cb); long timeout; if (sync->timeout_cb) { struct timespec now; GET_CLOCK_NOW timeout = (sync->timeout_at.tv_sec - now.tv_sec) * 1000; timeout += (sync->timeout_at.tv_nsec - now.tv_nsec) / 1000000; DBGMSG("timeout in %ld ms\n", timeout); if (timeout < 0) { /* If we missed the timeout moment, just * spin poll() quickly until we are clear * to call the timeout handler. */ timeout = 0; } } else { timeout = -1; } #ifdef _MSC_VER int n = (sync->n ? WSAPoll(sync->fdset, sync->n, timeout) : 0); #else int n = poll(sync->fdset, sync->n, timeout); #endif if (n < 0) { /* poll() errors are ignored, it's not clear what * we should do. Most likely, we have just received * a signal and will spin around and restart poll(). */ #ifdef _MSC_VER DBGMSG("WSAPoll error: %d\n", WSAGetLastError()); #else DBGMSG("poll(): %s\n", strerror(errno)); #endif continue; } if (n == 0) { /* Time out, call the handler and reset * timeout. */ DBGMSG("Timeout, callback and reset\n"); /* First, we reset sync->timeout_cb, then we * call the timeout handler - likely, that will * cause it to set timeout_cb again, so resetting * timeout_cb only after the call is bad idea. */ void (*timeout_cb)(struct pubnub *p, void *cb_data) = sync->timeout_cb; sync->timeout_cb = NULL; if (timeout_cb) { timeout_cb(p, sync->timeout_cb_data); } continue; } for (int i = 0; i < sync->n; i++) { short revents = sync->fdset[i].revents; if (!revents) continue; DBGMSG("event: fd %d ev %d rev %d\n", sync->fdset[i].fd, sync->fdset[i].events, sync->fdset[i].revents); int mode = (revents & POLLIN ? 1 : 0) | (revents & POLLOUT ? 2 : 0) | (revents & POLLERR ? 4 : 0); sync->cbset[i].cb(p, sync->fdset[i].fd, mode, sync->cbset[i].cb_data); } } sync->stop = false; }