#include "mainloop.h" #include "epoll.h" typedef struct FdInfo FdInfo; typedef struct FdCallbackInfo FdCallbackInfo; struct FdInfo { JobQueue * queue; MainFdFunc func; gpointer data; }; struct MainLoop { Executor *executor; EPoll *epoll; }; struct FdCallbackInfo { EPoll *epoll; int fd; EPollEventType mask; MainFdFunc func; gpointer data; }; static void run_fd_callback (gpointer data) { FdCallbackInfo *info = data; info->func (info->fd, info->mask, info->data); epoll_reenable_fd (info->epoll, info->fd); g_free (info); } static void poll_job (gpointer data) { MainLoop *loop = data; EPollEvent *events; int i, n_events; events = epoll_wait (loop->epoll, &n_events, -1); for (i = 0; i < n_events; ++i) { EPollEvent *event = &(events[i]); FdInfo *info = epoll_get_fd_data (loop->epoll, event->fd); FdCallbackInfo *callback_info = g_new0 (FdCallbackInfo, 1); callback_info->epoll = loop->epoll; callback_info->fd = event->fd; callback_info->mask = event->events; callback_info->func = info->func; callback_info->data = info->data; job_queue_add (info->queue, run_fd_callback, callback_info); } g_free (events); executor_add_job (loop->executor, poll_job, loop); } MainLoop * main_loop_new (Executor *executor) { MainLoop *loop; g_return_val_if_fail (executor != NULL, NULL); loop = g_new0 (MainLoop, 1); loop->executor = executor; loop->epoll = epoll_new (); executor_add_job (executor, poll_job, loop); return loop; } void main_loop_add_fd (MainLoop *loop, int fd, JobQueue *queue, MainFdFunc func, gpointer data) { FdInfo *info; g_return_if_fail (loop != NULL); g_return_if_fail (!epoll_has_fd (loop->epoll, fd)); info = g_new0 (FdInfo, 1); info->queue = queue; info->func = func; info->data = data; epoll_add_fd (loop->epoll, fd, 0, info); } #if 0 void main_loop_set_fd_poll_mask (MainLoop *loop, int fd, EPollEventType poll_mask) { g_return_if_fail (loop != NULL); g_return_if_fail (epoll_has_fd (loop->epoll, fd)); epoll_fd_set_mask (loop->epoll, fd, poll_mask); } #endif void main_loop_remove_fd (MainLoop *loop, int fd) { FdInfo *info; g_return_if_fail (loop != NULL); g_return_if_fail (epoll_has_fd (loop->epoll, fd)); info = epoll_get_fd_data (loop->epoll, fd); g_free (info); epoll_remove_fd (loop->epoll, fd); } Executor * main_loop_get_executor (MainLoop *loop) { g_return_val_if_fail (loop != NULL, NULL); return loop->executor; }