/* * 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 __WriteCallback(ev::io &watcher) { if (writebuf.empty()) { char szSeq[20]; snprintf(szSeq, 20, "%d", total); writebuf = testdata + szSeq; } int nWritten = write(watcher.fd, writebuf.c_str()+writelen, writebuf.size()-writelen); if (nWritten <= 0) { if (errno != EAGAIN) { __Stats(); } return; } writebytes += nWritten; writelen += nWritten; if (writelen >= (int)writebuf.size()) { watcher.set(ev::READ); } }
EchoServer(int port) { printf("Mendengarkan pada port %d\n", port); struct sockaddr_in addr; s = socket(PF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0) { perror("bind"); } fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK); listen(s, 5); io.set<EchoServer, &EchoServer::io_accept>(this); io.start(s, ev::READ); sio.set<&EchoServer::signal_cb>(); sio.start(SIGINT); }
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 }
/* Callback umum */ void callback(ev::io &watcher, int revents) { if (EV_ERROR & revents) { perror("got invalid event"); return; } if (revents & EV_READ) read_cb(watcher); if (revents & EV_WRITE) write_cb(watcher); if (write_queue.empty()) { io.set(ev::READ); } else { io.set(ev::READ|ev::WRITE); } }
server (int fd) { read_ev.set <server, &server::read_cb> (this); log_cb.set <server, &server::log_msg> (this); getfd_cb.set<server, &server::getfd> (this); this->fd = fd; fcntl (fd, F_SETFD, FD_CLOEXEC); fcntl (fd, F_SETFL, 0); read_ev.start (fd, ev::READ); }
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; } } }
/* 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); }
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 setupNode(ev::io& node) { int reuseaddr_on = 1; int node_fd = socket(AF_INET, SOCK_STREAM, 0); if (node_fd < 0) err(1, "listen failed"); if (setsockopt(node_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on)) == -1) err(1, "setsockopt failed"); sockaddr_in node_addr; memset(&node_addr, 0, sizeof(node_addr)); node_addr.sin_family = AF_INET; node_addr.sin_addr.s_addr = INADDR_ANY; node_addr.sin_port = htons(COMM_NODE_PORT); if (bind(node_fd, reinterpret_cast<sockaddr*>(&node_addr), sizeof(node_addr)) < 0) err(1, "bind failed"); if (listen(node_fd, 5) < 0) err(1, "listen failed"); if (setnonblock(node_fd) < 0) err(1, "failed to set server socket to non-blocking"); node.set<nodeAccept>(); node.start(node_fd, ev::READ); }
void setupHTTP(ev::io& http) { int reuseaddr_on = 1; int http_fd = socket(AF_INET, SOCK_STREAM, 0); if (http_fd < 0) err(1, "listen failed"); if (setsockopt(http_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on)) == -1) err(1, "setsockopt failed"); sockaddr_in http_addr; memset(&http_addr, 0, sizeof(http_addr)); http_addr.sin_family = AF_INET; http_addr.sin_addr.s_addr = INADDR_ANY; http_addr.sin_port = htons(COMM_HTTP_PORT); if (bind(http_fd, reinterpret_cast<sockaddr*>(&http_addr), sizeof(http_addr)) < 0) err(1, "bind failed"); if (listen(http_fd, 5) < 0) err(1, "listen failed"); if (setnonblock(http_fd) < 0) err(1, "failed to set server socket to non-blocking"); http.set<httpAccept>(); http.start(http_fd, ev::READ); }
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; }
EchoInstance(int s) : sfd(s) { fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK); printf("Client terkoneksi\n"); io.set<EchoInstance, &EchoInstance::callback>(this); io.start(s, ev::READ); }
/* Hancurkan dan tutup */ virtual ~EchoInstance() { /* Tutup dan bebaskan watcher saat socket ditutup */ io.stop(); close(sfd); }