void handle_worker_response(Worker_handle worker_handle, const Response_msg& resp) { // Master node has received a response from one of its workers. // Here we directly return this response to the client. DLOG(INFO) << ">>>Master received a response from a worker: [" << resp.get_tag() << ":" << resp.get_response() << "]" << std::endl; Client_handle client = mstate.tagClientMap[resp.get_tag()]; send_client_response(client, resp); DLOG(INFO) << "<<Master send response back to client: " << client << std::endl; mstate.num_pending_client_requests --; DLOG(INFO) << "pending_client_requests: " << mstate.num_pending_client_requests << std::endl; //store to cache int tag = resp.get_tag(); std::string req_string = mstate.tagReqStringMap[tag]; cache_manager.cacheMap[req_string] = resp.get_response(); //find the worker for(unsigned int i = 0; i< mstate.my_workers.size(); i++) { if(mstate.my_workers[i].worker_handle == worker_handle) { // update mstate mstate.handle_work_done(resp, i); break; } } // re-dispatching vip queue for (unsigned int i = 0; i < mstate.requests_queue_vip.size(); i++) { Request_info req = mstate.requests_queue_vip.front(); DLOG(INFO) << "deque(vip):" << req.client_req.get_request_string()<< std::endl; mstate.requests_queue_vip.pop(); handle_client_request(req.client_handle, req.client_req); } // re-dispatching queue for (unsigned int i = 0; i < mstate.requests_queue.size(); i++) { Request_info req = mstate.requests_queue.front(); DLOG(INFO) << "deque:" << req.client_req.get_request_string()<< std::endl; mstate.requests_queue.pop(); handle_client_request(req.client_handle, req.client_req); } return; }
int main(int argc, char** argv) { int chdev = -1; try { if (argc != 2) { THROW("incorrect number of arguments"); } // open the character device CHECK((chdev = open(argv[1], O_RDWR))); // handles client requests try { while (handle_client_request(chdev)); } catch (std::exception& e) { close(chdev); std::cerr << e.what() << std::endl; exit(1); } // close the client CHECK(close((chdev))); exit(0); } catch (std::exception& e) { close(chdev); std::cerr << e.what() << std::endl; exit(1); } return 0; }
void handle_event(const struct epoll_event *event) { struct signalfd_siginfo signalinfo; if (event->data.fd == sig_fd) { ssize_t n; if ((n = read(event->data.fd, &signalinfo, sizeof(signalinfo))) < 0) { syslog(LOG_ERR, "Error reading from signal fd: %s\n", strerror(errno)); return; } if (n < sizeof(signalinfo)) { syslog(LOG_ERR, "Partial read(2) on signal fd detected (%zu/%zu)\n", n, sizeof(signalinfo)); return; } if (signalinfo.ssi_signo == SIGHUP) { sighup_rehash(); return; } else if (signalinfo.ssi_signo == SIGTERM) { syslog(LOG_INFO, "Got SIGTERM, exiting...\n"); leave(); } else if (signalinfo.ssi_signo == SIGINT) { syslog(LOG_INFO, "Got SIGINT, exiting...\n"); leave(); } else { syslog(LOG_INFO, "Unexpected signal received: %s\n", strsignal(signalinfo.ssi_signo)); } } if (event->data.fd == sockfd) { int clientfd; if ((clientfd = accept(sockfd, NULL, NULL)) < 0) { syslog(LOG_ERR, "Error accepting new client: %s\n", strerror(errno)); return; } int optval = 1; if (setsockopt(clientfd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) { syslog(LOG_ERR, "Error setting SO_PASSCRED on new client: %s\n", strerror(errno)); close(clientfd); return; } struct epoll_event event; event.events = EPOLLIN | EPOLLET; event.data.fd = clientfd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, clientfd, &event) < 0) { syslog(LOG_ERR, "Error adding new client to epoll set: %s\n", strerror(errno)); close(clientfd); } return; } handle_client_request(event->data.fd); }
static void handle_client_data(int fd) { int r; if((r = read(fd, client_data[fd].buf+client_data[fd].pos, 1024-client_data[fd].pos)) > 0) { client_data[fd].pos += r; if(client_data[fd].pos >= 4 && !strncmp(client_data[fd].buf+client_data[fd].pos-4, "\r\n\r\n", 4)) { client_data[fd].buf[client_data[fd].pos] = '\0'; client_data[fd].state = CLIENT_INACTIVE; handle_client_request(fd, client_data[fd].buf); return; } } else { client_data[fd].state = CLIENT_INACTIVE; close(fd); } }
/* thread: the request handler */ void handle_request(void *args){ HandlerArgs *handlerArgs = (HandlerArgs*)args; char *recv_text = recv_once(handlerArgs->sockfd); int isServerRequest = is_server_request(recv_text); if(isServerRequest == TRUE){ handle_server_request(handlerArgs->sockfd, recv_text, handlerArgs->own_service_table, handlerArgs->service_list, handlerArgs->own_server_name); } else if(isServerRequest == FALSE){ handle_client_request(handlerArgs->sockfd, recv_text, handlerArgs->own_service_table, handlerArgs->service_list, handlerArgs->own_server_name); } else{ printf("no infomation recived\n"); printf("connection closed by client\n"); } if(recv_text != NULL) free(recv_text); free(args); pthread_exit(NULL); }
int main (int argc, char *argv[]) { int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; if (argc != 2) { fprintf (stderr, "Usage: %s [port]\n", argv[0]); exit (EXIT_FAILURE); } sfd = create_and_bind (argv[1]); if (sfd == -1) abort (); s = make_socket_non_blocking (sfd); if (s == -1) abort (); s = listen (sfd, SOMAXCONN); if (s == -1) { perror ("listen"); abort (); } efd = epoll_create1 (0); if (efd == -1) { perror ("epoll_create"); abort (); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } /* Buffer where events are returned */ events = calloc (MAXEVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait (efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } else if (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept (sfd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror ("accept"); break; } } s = getnameinfo (&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (s == 0) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking (infd); if (s == -1) abort (); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } } continue; } else { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ int done = 0; while (1) { ssize_t count; char buf[512]; count = read (events[i].data.fd, buf, sizeof buf); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror ("read"); done = 1; } break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } /* Write the buffer to standard output */ handle_client_request(buf, count); } if (done) { printf ("Closed connection on descriptor %d\n", events[i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close (events[i].data.fd); } } } } free (events); close (sfd); return EXIT_SUCCESS; }
void handle_client(int sockfd){ handle_client_request(sockfd); handle_client_response(sockfd); }
void handle_server_events(server_t *server) { // respond to events memset(&server->ke, 0, sizeof(server->ke)); if (kevent(server->kq, NULL, 0, &server->ke, 1, NULL) <= 0) { usleep(5000); return; } if (server->ke.ident == (uintptr_t)server->sock) { // client connection int cl_sock; struct sockaddr_in c; socklen_t len; if ((cl_sock = accept(server->sock, (struct sockaddr *)&c, &len)) == -1) err(EX_UNAVAILABLE, "accept"); // init client client_conn_t *conn = calloc(1, sizeof(client_conn_t)); conn->sock = cl_sock; memcpy(&conn->addr, &c.sin_addr, sizeof(c.sin_addr)); conn->client = init_client(); server->clients[server->client_count++] = conn; // listen to the client socket EV_SET(&server->ke, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); if (kevent(server->kq, &server->ke, 1, NULL, 0, NULL) == -1) err(EX_UNAVAILABLE, "kevent add user"); fprintf(stderr, "connection from %s\n", inet_ntoa(c.sin_addr)); } else if (server->ke.ident == 0) { // game update timer fired update_server(server); } else { // client data client_conn_t *conn = find_client(server, server->ke.ident); // read the data char buf[1024]; memset(&buf, 0, sizeof(buf)); int n = read(conn->sock, buf, sizeof(buf)); // not ready yet if (n == -1) return; // EOF - disconnect user if (n == 0) { EV_SET(&server->ke, conn->sock, EVFILT_READ, EV_DELETE, 0, 0, NULL); if (kevent(server->kq, &server->ke, 1, 0, 0, NULL) == -1) err(EX_UNAVAILABLE, "disconnect user"); fprintf(stderr, "%s logged out\n", conn->client->username); close(conn->sock); if (conn->client) if (conn->client->entity) conn->client->entity->dead = true; free(conn); return; } // handle the data handle_client_request(server, conn, buf, n); } }