/* * If your compiler can inline your callback (i.e. it is visible to it at the place of the set call and * your compiler is good :), then the method will be fully inlined into the thunking function, making it * as fast as a direct C callback. * * revents was bitset * * if (revents & EV_READ ) fd->revents |= fd->events & POLLIN; * if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT; */ void CNetBackend::accept_cb(ev::io &w, int32 revents) { if ( EV_ERROR & revents ) //error { GERROR() << "accept_cb error:" << strerror(errno) << "\n"; w.stop(); return; } struct sockaddr_in socket_address; int32 length = sizeof( socket_address ); //w.fd is m_plistenning_socket->get_listen_socket_fd() int32 fd = accept( w.fd,(sockaddr *)&socket_address,(socklen_t *)&length ); if ( fd < 0 ) { if ( EWOULDBLOCK == errno || EAGAIN == errno ) //无连接libev怎么会调用accept_cb { GERROR() << "accept_cb EWOULDBLOCK or EAGAIN found\n"; return; } GERROR() << "accept new connection fail:" << strerror( errno ) << "\n"; return; } add_socket( fd,socket_address ); }
void DataSink::_DeleteAndCleanupWatcher(ev::io &watcher) { watcher.stop(); // Make watcher inactive close(watcher.fd); // Close associated socket int numWatchersRemoved = _watcherMap.erase(&watcher); CHECK(numWatchersRemoved == 1); delete &watcher; // Release memory }
void readCallback(ev::io& w, int) { char buf[m_receiveBufferSize]; auto res = m_bfSocket->read(buf, m_receiveBufferSize); m_receivedBytes += res; ASSERT_EQ(buf[0], 0x47); ASSERT_EQ(res, m_messageSize); if(m_doneSending) w.stop(); }
void Connection::read(ev::io &w, int revents) { char buffer[BUFFER_SIZE]; ssize_t r = recv(w.fd, buffer, BUFFER_SIZE, MSG_NOSIGNAL); if (r < 0) { // error char err_buf[100]; log_file << "Error reading socket: " << strerror_r(errno, err_buf, 100) << std::endl; w.stop(); delete this; return; } else if (r == 0) { // connection closed w.stop(); delete this; return; } else { parse(buffer, r, w); if (closeConnection) { w.stop(); shutdown(w.fd, SHUT_RDWR); close(w.fd); delete this; } } }
void do_read(ev::io& w, int revents) { /*now attempt the read*/ /*first use a select() to check: the event loop might falsely trigger */ if((revents & ev::READ) && check_select(ev::READ)) { /*now attempt a read*/ ioa.data.reset( new std::vector<unsigned char>(READ_SIZE)); ssize_t rv = read(fd, io.data->begin(), READ_SIZE); if(rv < 0) { /*potential errors*/ switch(errno) { /*ignore these*/ case EAGAIN: case EINTR: return; break; case EBADF: todo.err(ioa, "not valid, or not " "open for reading"); break; case EFAULT: todo.err(ioa, "internal error, buffer " "misallocated"); break; case EINVAL: todo.err(ioa, "unsuitable for " "reading"); break; case EIO: todo.err(ioa, "low-level i/o error"); break; default: todo.err(ioa, "unknown error type"); break; } } else if(rv == 0) { todo.eof(ioa); } else { ioa.data->resize(rv); todo.respond(ioa); } w.stop(); } }
void AppServer::read_cb(ev::io &watcher, int revents) { if(EV_ERROR & revents) { perror("Error event in accept\n"); return; } char buffer[BUFFER_SIZE]; int readlen; readlen = recv(watcher.fd, buffer, BUFFER_SIZE, 0); if(readlen < 0) { perror("read error!\n"); return; } if(readlen == 0) { TESTINFO("client disconnected.\n"); XMessage msg; msg.user_id = watcher.fd; msg.msg_type = XMSG_DISCONN; MessageHandler.push(msg); watcher.stop(); return; } else// { buffer[readlen] = '\0'; TESTINFO("Received: %s", buffer); MessageHandler.parse_and_push(buffer, watcher.fd); } return; }
/* Socket dapat ditulis */ void write_cb(ev::io &watcher) { if (write_queue.empty()) { io.set(ev::READ); return; } Buffer* buffer = write_queue.front(); ssize_t written = write(watcher.fd, buffer->dpos(), buffer->nbytes()); if (written < 0) { perror("read error"); return; } buffer->pos += written; if (buffer->nbytes() == 0) { write_queue.pop_front(); delete buffer; } /* Tutup dan bebaskan watcher saat selesai mengirim response (stateless) */ io.stop(); close(sfd); }
/* Hancurkan dan tutup */ virtual ~EchoInstance() { /* Tutup dan bebaskan watcher saat socket ditutup */ io.stop(); close(sfd); }