#include #include #include #include #include #include #include #include #include #include #include #include #define SOCKET_PATH "/tmp/socket" #define MAX_CLIENTS 10 #define CMD_ECHO 1 #define CMD_TIMER 2 struct request { int priority; int command; int value; }; typedef struct client_request { int client_fd; int event_fd; struct request req; struct client_request *next; } client_request_t; client_request_t *queue_head = NULL; pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; void log_msg(const char *msg) { printf("[SERVER] %s\n", msg); } void enqueue(client_request_t *node) { pthread_mutex_lock(&queue_mutex); if (!queue_head || node->req.priority > queue_head->req.priority) { node->next = queue_head; queue_head = node; } else { client_request_t *cur = queue_head; while (cur->next && cur->next->req.priority >= node->req.priority) cur = cur->next; node->next = cur->next; cur->next = node; } pthread_mutex_unlock(&queue_mutex); } client_request_t* dequeue() { pthread_mutex_lock(&queue_mutex); client_request_t *node = queue_head; if (queue_head) queue_head = queue_head->next; pthread_mutex_unlock(&queue_mutex); return node; } void* worker_thread(void *arg) { while (1) { client_request_t *node = dequeue(); if (!node) { usleep(100000); continue; } struct request *req = &(node->req); char buffer[128]; sprintf(buffer, "Processing (p: %d, c: %d, v: %d)", req->priority, req->command, req->value); log_msg(buffer); int response = 0; if (req->command == CMD_ECHO) { response = req->value; write(node->client_fd, &response, sizeof(response)); } else if (req->command == CMD_TIMER) { sleep(req->value); uint64_t val = 1; write(node->event_fd, &val, sizeof(val)); response = 0; write(node->client_fd, &response, sizeof(response)); } free(node); } return NULL; } int recv_fd(int socket) { struct msghdr msg = {0}; char buf[CMSG_SPACE(sizeof(int))]; memset(buf, 0, sizeof(buf)); struct iovec io = { .iov_base = "F", .iov_len = 1 }; msg.msg_iov = &io; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); recvmsg(socket, &msg, 0); struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); int fd; memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); return fd; } int main() { int server_fd = socket(AF_UNIX, SOCK_STREAM, 0); struct sockaddr_un addr; unlink(SOCKET_PATH); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, SOCKET_PATH); bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)); listen(server_fd, MAX_CLIENTS); log_msg("Server started"); pthread_t worker; pthread_create(&worker, NULL, worker_thread, NULL); while (1) { int client_fd = accept(server_fd, NULL, NULL); log_msg("Client connected"); int event_fd = recv_fd(client_fd); struct request req = {0, 0, 0}; read(client_fd, &req, sizeof(struct request)); client_request_t *node = malloc(sizeof(client_request_t)); node->client_fd = client_fd; node->event_fd = event_fd; node->req = req; node->next = NULL; enqueue(node); } close(server_fd); unlink(SOCKET_PATH); return 0; }