#include "jobqueue.h" #include "maincontext.h" #include "mainloop.h" /* A main context will generally correspond to one client in the server. * * Tasks added to it, either as fd tasks, or as idle/timeout tasks * will run serially, always. * * Parallelism can be done through the - as yet - non-existant * get_executor(). Or perhaps, create_job_queue()? * * Also, given a main context, who really needs a "mainloop"? How about * just passing in an epoll and an executor at creation time? * * Sounds like a better idea. Hmm, the problem is who calls epoll_wait()? * * Also should probably have a main_context_get_data() and then pass the * context to the callbacks, rather than the data directly. This way * the callbacks have acess to the context as well. Though I guess the * user data will generally contain a pointer to the context. So data * itself is probably more convenient. Or is it? If you have data, then * you have to do my_stuff->context to get at the context, if it is an * argument, then you can just use it. Ie., there is no useless "data" * parameter. * * We will most likely need per-fd data for things like Connections. */ typedef struct ContextFdInfo ContextFdInfo; struct MainContext { MainLoop * loop; gpointer data; JobQueue * job_queue; }; struct ContextFdInfo { MainContext * context; MainFdTask prepare; MainFdTask read; MainFdTask write; gpointer data; }; MainContext * main_context_new (MainLoop *loop, gpointer data) { MainContext *context = g_new0 (MainContext, 1); context->loop = loop; context->data = data; context->job_queue = job_queue_new (main_loop_get_executor (loop)); return context; } void main_context_free (MainContext *context) { /* FIXME: this will complain if we run it when there are still * active jobs. But we kinda have to delete the job out of a * task that runs in it. So what do we do? Maybe just make it * legal to delete an active job queue. I don't really see the * harm in that, except that the execution function in jobqueue.c * might get a little bit more complex */ job_queue_free (context->job_queue); g_free (context); } static void on_fd_activity (int fd, EPollEventType mask, gpointer data) { } /* Filedescriptors */ void main_context_add_fd (MainContext *context, int fd, gpointer data) { ContextFdInfo *info = g_new0 (ContextFdInfo, 1); info->context = context; info->data = data; info->prepare = NULL; info->read = NULL; info->write = NULL; main_loop_add_fd (context->loop, fd, context->job_queue, on_fd_activity, info); } void main_context_remove_fd (MainContext *context, int fd) { } static void update_poll_mask (MainContext *context, ContextFdInfo *info, int fd) { } /* Called before the fd is polled */ void main_context_set_prepare_callback (MainContext *context, int fd, MainFdTask func) { } /* Called when the fd is writable */ void main_context_set_write_callback (MainContext *context, int fd, MainFdTask func) { } /* Called when there is data to be read, if the fd is closed/hungup, or * if there is an error */ void main_context_set_read_callback (MainContext *context, int fd, MainFdTask func) { } /* Idle/timeout tasks */ #if 0 typedef gboolean (* MainTaskFunc) (gpointer data); MainTask * main_context_add_idle (MainContext *context, MainTaskFunc func, gpointer data) { } MainTask * main_context_add_timeout (MainContext *context, int millisecs, MainTaskFunc func, gpointer data) { } void main_task_remove (MainTask *task) { } #endif