2019-02-11 17:56:52 +00:00
|
|
|
#include "evt_core.h"
|
|
|
|
|
2019-02-11 21:40:00 +00:00
|
|
|
void free_fd(void* v) {
|
|
|
|
int* fd = (int*)v;
|
|
|
|
close(*fd);
|
2019-02-11 17:56:52 +00:00
|
|
|
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);
|
2019-02-11 22:40:37 +00:00
|
|
|
g_array_free(cat->socklist, TRUE);
|
2019-02-11 18:14:07 +00:00
|
|
|
free(cat->name);
|
|
|
|
free(cat);
|
2019-02-11 17:56:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2019-02-11 21:40:00 +00:00
|
|
|
ctx->socklist = g_hash_table_new_full(g_int_hash, g_int_equal,free_fd, NULL);
|
2019-02-11 17:56:52 +00:00
|
|
|
}
|
|
|
|
|
2019-02-11 18:14:07 +00:00
|
|
|
void evt_core_add_cat(struct evt_core_ctx* ctx, struct evt_core_cat* cat) {
|
2019-02-11 22:40:37 +00:00
|
|
|
if (cat->socklist != NULL) {
|
|
|
|
fprintf(stderr, "cat->socklist must be null. What have you done?\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
cat->socklist = g_array_new (FALSE, FALSE, sizeof(int));
|
|
|
|
|
2019-02-11 17:56:52 +00:00
|
|
|
struct evt_core_cat* dyn = NULL;
|
|
|
|
dyn = malloc(sizeof(struct evt_core_cat));
|
|
|
|
if (dyn == NULL) {
|
2019-02-11 18:14:07 +00:00
|
|
|
fprintf(stderr, "Failed to alloc memory\n");
|
2019-02-11 17:56:52 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-02-11 18:14:07 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-02-11 21:40:00 +00:00
|
|
|
void evt_core_add_fd(struct evt_core_ctx* ctx, char* name, int fd) {
|
2019-02-11 18:14:07 +00:00
|
|
|
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);
|
|
|
|
}
|
2019-02-11 17:56:52 +00:00
|
|
|
|
2019-02-11 22:40:37 +00:00
|
|
|
g_array_append_val (cat->socklist, fd);
|
2019-02-11 18:14:07 +00:00
|
|
|
g_hash_table_insert(ctx->socklist, key, cat);
|
2019-02-11 21:40:00 +00:00
|
|
|
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);
|
2019-02-11 17:56:52 +00:00
|
|
|
}
|