int EventLoop::procIoEvent() { int processed = 0; //timer struct timeval tv, *tvp = NULL; TimerList::const_iterator it = arrTimers.begin(); if(it != arrTimers.end()){ TimerEvent *te = it->second; Timestamp now = GetTime(); tvp = &tv; if(now >= te->id){ tvp->tv_sec = 0; tvp->tv_usec = 0; }else{ tvp->tv_sec = (te->id - now) / 1000000; tvp->tv_usec = (te->id - now) % 1000000; } } else { tvp = NULL; /* wait forever */ } if(nMaxWaitTime){ int sec = nMaxWaitTime / 1000; int usec = nMaxWaitTime % 1000 * 1000; if(tvp){ if(tvp->tv_sec > sec || (tvp->tv_sec == sec && tvp->tv_usec > usec)){ tvp->tv_sec = sec; tvp->tv_usec = usec; } }else{ tv.tv_sec = sec; tv.tv_usec = usec; tvp = &tv; } } //poll int numevents = pPoll->poll(tvp); for (int j = 0; j < numevents; j++) { int mask = pFireds[j].mask; int fd = pFireds[j].fd; IOEvent *io = pEvents + fd; if (io->mask & mask & EV_IO_READ) { EV_INVOKE(io->cbRead, fd, mask, io->data); } if (io->mask & mask & EV_IO_WRITE) { EV_INVOKE(io->cbWrite, fd, mask, io->data); } processed++; } return processed; }
void Connection::onConnect(int fd, int r, void *data) { int sockerr = 0; socklen_t errlen = sizeof(sockerr); //remove all event pEventLoop->removeEventListener(sSocket.getFd(), EV_IO_ALL); //remove timer if(nTimeout){ pEventLoop->stopTimer(nTimerId); } //check fd if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1){ sockerr = errno; } //error if(sockerr){ nError = sockerr; close(); return ; } initSocket(); EV_INVOKE(cbConnect, this); }
int EventLoop::procIOEvent() { int numEvent = pPoll->poll(); int processed = 0; for (int j = 0; j < numEvent; j++) { int mask = pFireds[j].mask; int fd = pFireds[j].fd; IOEvent* ev = pEvents + fd; if (ev->mask & mask & EV_IO_READ) EV_INVOKE(ev->cbRead, fd, mask, ev->data); if (ev->mask & mask & EV_IO_WRITE) EV_INVOKE(ev->cbWrite, fd, mask, ev->data); processed++; } return processed; }
void EventLoop::run() { LOG("eventloop started, event driven is %s", pPoll->name()); bRunning = true; while(bRunning) { EV_INVOKE(cbBefore, pBeforeData); procTickEvent(); procIoEvent(); procTimerEvent(); } }
void Connection::onRead(int fd, int r, void *data) { char buf[8192]; int n = sSocket.read(buf, 8192); LOG("on read, fd=%d, recv=%d", fd, n); if(n == SOCKET_ERR){ nError = sSocket.getError(); close(); }else if(n > 0){ readBuffer.append(buf, n); EV_INVOKE(cbRead, this); } }
int EventLoop::procTickEvent() { TickEvent *tick = pTickHead; int n = 0; while(tick){ TickEvent *next = tick->next; EV_INVOKE(tick->cb, tick->data); zfree(tick); tick = next; n++; } pTickHead = pTickTail = NULL; return n; }
void Connection::close() { if(bClosed){ return ; } //remove io event pEventLoop->removeEventListener(sSocket.getFd(), EV_IO_ALL); //remove timer event if(nTimerId){ pEventLoop->stopTimer(nTimerId); } bClosed = true; sSocket.close(); EV_INVOKE(cbClose, this); }
void Connection::onWrite(int fd, int r, void *data) { char *buffer = writeBuffer.data(); size_t size = writeBuffer.size(); int n = sSocket.write(buffer, size); LOG("write to fd=%d, len=%d", fd, n); if(n == SOCKET_ERR){ nError = sSocket.getError(); close(); }else if(n > 0){ int remain = writeBuffer.seek(n); if(remain <= 0){ LOG("write completed"); bWriting = false; pEventLoop->removeEventListener(sSocket.getFd(), EV_IO_WRITE); EV_INVOKE(cbWriteComplete, this); } } }
int EventLoop::procTimerEvent() { int processed = 0; Timestamp now = GetTime(); for(TimerList::iterator it = arrTimers.begin(); it != arrTimers.end();) { TimerEvent *te = it->second; if(te->id < now){ arrTimers.erase(it++); EV_INVOKE(te->cb, te->id, te->data); processed++; zfree(te); }else{ it++; } } return processed; }