/* Generic entrypoint for this SERVER. Takes in a socket on SOCKFD, which * should already be connected to an incoming request. Processes the request * and sends back a response message. This should call out to the appropriate * internal handler. */ void kvserver_handle(kvserver_t *server, int sockfd, void *extra) { kvmessage_t *reqmsg, *respmsg; respmsg = calloc(1, sizeof(kvmessage_t)); reqmsg = kvmessage_parse(sockfd); void (*server_handler)(kvserver_t *server, kvmessage_t *reqmsg, kvmessage_t *respmsg); server_handler = server->use_tpc ? kvserver_handle_tpc : kvserver_handle_no_tpc; if (reqmsg == NULL) { respmsg->type = RESP; respmsg->message = ERRMSG_INVALID_REQUEST; } else { server_handler(server, reqmsg, respmsg); } kvmessage_send(respmsg, sockfd); if (reqmsg != NULL) kvmessage_free(reqmsg); }
static void server_loop(void) { for (;/* EVER */;) { struct sockaddr_in clientINETAdress; socklen_t clientLen = sizeof(clientINETAdress); /* TODO accept connection from serverFD into clientFD */ fprintf(stdout, "connected clientFD %d from IPadress %s\n", clientFD, inet_ntoa(clientINETAdress.sin_addr)); /* Create new child to deal with this connection */ pid_t cpid = fork(); if (cpid == 0) { // child serverFD = -1; // avoid cleaning this up server_handler(); exit(0); } else { // parent clientFD = -1; // reset so it doesn't get closed twice } } }
void run_event_loop() { int num_events; while (1) { num_events = kevent(event_loop.kqueue_fd, NULL, 0, event_loop.events, MAX_EVENTS_PER_POLL, NULL); for (int ei = 0; ei < num_events; ei++) { struct kevent *ke = event_loop.events + ei; if (ke->ident == (uint64_t)server.fd) { server.fired_event = ke; server_handler(); } else { client_t* client = (client_t*) ke->udata; client->fired_event = ke; client_handler(client); } } } }