#include "evt_core.h" void free_fd(void* v) { int* fd = (int*)v; close(*fd); free(v); } void free_char(void* c) { free(c); } void free_cat(void* vcat) { struct evt_core_cat* cat = (struct evt_core_cat*) vcat; cat->free_app_ctx(cat->app_ctx); free(cat->name); free(cat); } void evt_core_init(struct evt_core_ctx* ctx) { ctx->epollfd = epoll_create1(0); if (ctx->epollfd == -1) { perror("Failed to create epoll file descriptor epoll_create1"); exit(EXIT_FAILURE); } ctx->catlist = g_hash_table_new_full(g_str_hash, g_str_equal,free_char,free_cat); ctx->socklist = g_hash_table_new_full(g_int_hash, g_int_equal,free_fd, NULL); } void evt_core_add_cat(struct evt_core_ctx* ctx, struct evt_core_cat* cat) { struct evt_core_cat* dyn = NULL; dyn = malloc(sizeof(struct evt_core_cat)); if (dyn == NULL) { fprintf(stderr, "Failed to alloc memory\n"); exit(EXIT_FAILURE); } dyn->app_ctx = cat->app_ctx; dyn->free_app_ctx = cat->free_app_ctx; dyn->cb = cat->cb; dyn->name = strdup(cat->name); dyn->flags = cat->flags; if (dyn->name == NULL) { perror("Unable to allocate memory for category name via strdup"); exit(EXIT_FAILURE); } char* key = NULL; key = strdup(cat->name); if (key == NULL) { perror("Unable to allocate memory for key via strdup"); exit(EXIT_FAILURE); } g_hash_table_insert (ctx->catlist, key, dyn); } void evt_core_add_fd(struct evt_core_ctx* ctx, char* name, int fd) { int* key = NULL; key = malloc(sizeof(int)); if (key == NULL) { perror("Unable to allocate memory for key via malloc"); exit(EXIT_FAILURE); } memcpy(key, &fd, sizeof(int)); struct evt_core_cat* cat = g_hash_table_lookup(ctx->catlist, name); if (cat == NULL) { fprintf(stderr, "Category %s should be defined before inserting a file descriptor in it.\n", name); exit(EXIT_FAILURE); } g_hash_table_insert(ctx->socklist, key, cat); add_fd_to_epoll(ctx->epollfd, fd); } void evt_core_free(struct evt_core_ctx* ctx) { g_hash_table_destroy(ctx->socklist); g_hash_table_destroy(ctx->catlist); } void evt_core_loop(struct evt_core_ctx* ctx) { struct epoll_event current_event, events[EVT_CORE_MAX_EVENTS]; struct evt_core_cat* cat; printf("--- Start main loop\n"); int num_fd, n = 0; while(1) { num_fd = epoll_wait(ctx->epollfd, events, EVT_CORE_MAX_EVENTS, -1); if (num_fd == -1) { perror("Failed to epoll_wait"); exit(EXIT_FAILURE); } for (n = 0 ; n < num_fd; n++) { if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (!(events[n].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[n].data.fd); continue; } cat = g_hash_table_lookup(ctx->socklist, &(events[n].data.fd)); if (cat == NULL) { fprintf(stderr, "Ignoring file descriptor %d as it is not registered. This is a bug.\n", events[n].data.fd); continue; } cat->cb(ctx, cat, events[n].data.fd); } } evt_core_free(ctx); }