static void recv_raw(int afdt_fd, void* data, uint32_t len) { afdt_error_t err = AFDT_ERROR_T_INIT; while (len > 0) { auto l = std::min<uint32_t>(len, AFDT_MSGLEN); if (afdt_recv_plain_msg(afdt_fd, (uint8_t*)data, &l, &err) < 0) { throw Exception("Failed in afdt_recv: %s", err.message && err.message[0] ? err.message : folly::errnoStr(errno).c_str()); } assert(l <= len); len -= l; data = (char*)data + l; } }
// libevent callback for a server when a client socket is readable. // Receives the request, calls the request handler, sends the response, // and calls the post handler. static void server_handle_client_read(int clientfd, short event_type, void* arg) { assert(event_type == EV_READ); int ret; struct ev_arg* ev_userdata = arg; struct afdt_error_t err = AFDT_ERROR_T_INIT; err.phase = AFDT_HANDLE_REQUEST; uint8_t req_buf[AFDT_MSGLEN]; uint8_t res_buf[AFDT_MSGLEN]; uint32_t req_len = sizeof(req_buf); ret = afdt_recv_plain_msg(clientfd, req_buf, &req_len, &err); if (ret < 0) { ev_userdata->error_handler(&err, ev_userdata->afdt_userdata); goto drop_client; } uint32_t res_len = sizeof(res_buf); int fd_to_send = ev_userdata->request_handler( req_buf, req_len, res_buf, &res_len, ev_userdata->afdt_userdata ); assert((size_t)res_len <= AFDT_MSGLEN); ret = afdt_send_fd_msg(clientfd, res_buf, res_len, fd_to_send, &err); if (ret < 0) { ev_userdata->error_handler(&err, ev_userdata->afdt_userdata); } else { ev_userdata->post_handler( req_buf, req_len, res_buf, res_len, fd_to_send, ev_userdata->afdt_userdata); } drop_client: close(clientfd); free(arg); }