From f3b3c2f12c2e7e3996d682a415b6ae7cfa7a7a7e Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Tue, 13 Sep 2005 04:50:23 +0000 Subject: [PATCH] It's a whole mess. Shit. Trying anyway. --- include/appserver.h | 3 + include/array.h | 7 +- include/event.h | 13 +-- src/appserver.c | 36 +++++++-- src/array.c | 21 +++++ src/event.c | 192 +++++++++++++++++++++++++++++++------------- 6 files changed, 200 insertions(+), 72 deletions(-) diff --git a/include/appserver.h b/include/appserver.h index cf36e06..df88110 100644 --- a/include/appserver.h +++ b/include/appserver.h @@ -23,4 +23,7 @@ AppServer * appserver_new(const char * app, int options); AppServer * appserver_new_event(const char * app, int options, Event * event); void appserver_delete(AppServer * appserver); +/* useful */ +int appserver_loop(AppServer * appserver); + #endif /* !_APPSERVER_H */ diff --git a/include/array.h b/include/array.h index bb536f8..44cd290 100644 --- a/include/array.h +++ b/include/array.h @@ -7,8 +7,8 @@ # define ARRAY(type, name) \ - typedef Array name ## Array; \ - Array * name ## ArrayNew(void) { return array_new(sizeof(type)); } + typedef Array type ## Array; \ + Array * name ## array_new(void) { return array_new(sizeof(type)); } /* types */ @@ -25,5 +25,8 @@ void array_delete(Array * array); int array_append(Array * array, void * data); void array_apply(Array * array, ArrayApplyFunc func, void * userdata); unsigned int array_count(Array * array); +int array_get(Array * array, unsigned int pos, void ** data); +int array_remove_pos(Array * array, unsigned int pos); +int array_set(Array * array, unsigned int pos, void * data); #endif /* !_ARRAY_H */ diff --git a/include/event.h b/include/event.h index 07a93cb..a339f2c 100644 --- a/include/event.h +++ b/include/event.h @@ -13,8 +13,8 @@ /* types */ typedef struct _Event Event; -typedef void (*EventFunc)(int fd, void * data); -typedef void (*EventTimeoutFunc)(void * data); +typedef int (*EventIOFunc)(int fd, void * data); +typedef int (*EventTimeoutFunc)(void * data); /* functions */ @@ -23,8 +23,11 @@ void event_delete(Event * event); /* useful */ int event_loop(Event * event); -int event_register_fd_read(Event * event, int fd, EventFunc * func); -int event_register_timeout(Event * event, EventTimeoutFunc * func, - struct timeval timeout, void * userdata); +int event_register_io_read(Event * event, int fd, EventIOFunc func, + void * userdata); +int event_register_io_write(Event * event, int fd, EventIOFunc func, + void * userdata); +int event_register_timeout(Event * event, struct timeval timeout, + EventTimeoutFunc * func, void * userdata); #endif /* !_EVENT_H */ diff --git a/src/appserver.c b/src/appserver.c index 3af05ac..9231e94 100644 --- a/src/appserver.c +++ b/src/appserver.c @@ -8,8 +8,8 @@ #include #include -#include -#include +#include "array.h" +#include "string.h" #include "appserver.h" @@ -65,7 +65,7 @@ struct _AppServer /* functions */ -static void _appserver_accept(int fd, AppServer * appserver) +static int _appserver_accept(int fd, AppServer * appserver) { struct sockaddr_in sa; int sa_size = sizeof(struct sockaddr_in); @@ -74,11 +74,15 @@ static void _appserver_accept(int fd, AppServer * appserver) /* FIXME append client to the clients list with the appropriate state */ if((fd2 = accept(fd, (struct sockaddr *)&sa, &sa_size)) == -1) - return perror("accept"); /* FIXME report error */ + { + perror("accept"); /* FIXME report error */ + return 0; + } if((asc = appserverclient_new(fd2, sa.sin_addr.s_addr, sa.sin_port)) == NULL) - return; + return 0; array_append(appserver->clients, asc); + return 0; } @@ -127,13 +131,21 @@ AppServer * appserver_new_event(const char * app, int options, Event * event) } static int _new_interface(AppServer * appserver, const char * app) -{ /* FIXME interfaces are hardcoded */ +{ if(string_compare(app, "Session") == 0) { appserver->port = 4242; /* FIXME */ return 0; } + else if(string_compare(app, "Network") == 0) + { + /* FIXME */ + } + else if(string_compare(app, "Probe") == 0) + { + /* FIXME */ + } return 1; } @@ -146,7 +158,8 @@ static int _new_server(AppServer * appserver, int options) return 1; /* FIXME report error */ sa.sin_family = AF_INET; sa.sin_port = htons(appserver->port); - sa.sin_addr.s_addr = options & ASO_LOCAL ? INADDR_LOOPBACK : INADDR_ANY; + sa.sin_addr.s_addr = htonl(options & ASO_LOCAL ? INADDR_LOOPBACK + : INADDR_ANY); if(bind(fd, (struct sockaddr *)&sa, sizeof(sa)) != 0 || listen(fd, 5) != 0) { @@ -155,7 +168,7 @@ static int _new_server(AppServer * appserver, int options) perror("close"); /* FIXME report error appropriately */ return 1; } - event_register_fd_read(appserver->event, fd, _appserver_accept); + event_register_io_read(appserver->event, fd, _appserver_accept, NULL); return 0; } @@ -166,3 +179,10 @@ void appserver_delete(AppServer * appserver) event_delete(appserver->event); free(appserver); } + + +/* useful */ +int appserver_loop(AppServer * appserver) +{ + return event_loop(appserver->event); +} diff --git a/src/array.c b/src/array.c index cec9042..d9d58db 100644 --- a/src/array.c +++ b/src/array.c @@ -65,3 +65,24 @@ unsigned int array_count(Array * array) { return array->count; } + + +int array_get(Array * array, unsigned int pos, void ** data) +{ + if(pos >= array->count) + return 1; + memcpy(*data, &array->data[pos * array->size], array->size); + return 0; +} + + +int array_remove_pos(Array * array, unsigned int pos) +{ + if(pos >= array->count) + return 1; + array->count--; /* FIXME resize array? */ + memmove(&array->data[pos * array->size], + &array->data[(pos + 1) * array->size], + (array->count - pos) * array->size); + return 0; +} diff --git a/src/event.c b/src/event.c index 83471a2..d46c4c2 100644 --- a/src/event.c +++ b/src/event.c @@ -3,110 +3,103 @@ #include +#include +#include #include -#include #include #include #include + #include "array.h" #include "event.h" +#define max(a, b) ((a) >= (b)) ? (a) : (b) + /* Event */ +/* private */ +/* types */ typedef struct _EventTimeout { - EventTimeoutFunc * func; - void * data; - struct timeval now; struct timeval timeout; + EventTimeoutFunc func; + void * data; } EventTimeout; -ARRAY(EventTimeout, EventTimeout); +ARRAY(EventTimeout, eventtimeout); + +typedef struct _EventIO +{ + int fd; + EventIOFunc func; + void * data; +} EventIO; +ARRAY(EventIO, eventio); struct _Event { fd_set rfds; fd_set wfds; EventTimeoutArray * timeouts; - struct timeval now; - struct timeval * timeout; + struct timeval timeout; + EventIOArray * reads; + EventIOArray * writes; + int fdmax; }; -#ifdef DEBUG -static void _debug_timeval(struct timeval * tv, char * message) -{ - fprintf(stderr, "%s%s%lu%s%lu%s", message, ": ", tv->tv_sec, "s, ", - tv->tv_usec, "us\n"); -} -#endif - - +/* public */ +/* functions */ +/* event_new */ Event * event_new(void) { Event * event; if((event = malloc(sizeof(Event))) == NULL) return NULL; - if(gettimeofday(&event->now, NULL) != 0 - || (event->timeouts = EventTimeoutArrayNew()) == NULL) + if((event->timeouts = eventtimeoutarray_new()) == NULL) { - perror("event"); free(event); return NULL; } -#ifdef DEBUG - _debug_timeval(&event->now, "event_new()"); -#endif + event->timeout.tv_sec = LONG_MAX; + event->timeout.tv_usec = LONG_MAX; + event->reads = eventioarray_new(); /* FIXME */ + event->writes = eventioarray_new(); /* FIXME */ FD_ZERO(&event->rfds); FD_ZERO(&event->wfds); - event->timeout = NULL; return event; } +/* event_delete */ void event_delete(Event * event) { + array_delete(event->timeouts); + array_delete(event->reads); + array_delete(event->writes); free(event); } -/* internal */ -static void _event_timeout_set(Event * event) -{ - static struct timeval tv; - - if(array_count(event->timeouts) == 0) - { - event->timeout = NULL; - return; - } - if(gettimeofday(&tv, NULL) != 0) - perror("gettimeofday"); - /* FIXME set event->timeout */ -} - -static int _event_timeout_hit(Event * event) -{ - if(event->timeout == NULL) - return 0; - /* FIXME look at every timeout func and run it if necessary */ - return 0; -} - - /* useful */ +static void _loop_timeouts(Event * event); +static void _loop_reads(Event * event); +static void _loop_writes(Event * event); int event_loop(Event * event) { + struct timeval * timeout = event->timeout.tv_sec == LONG_MAX + && event->timeout.tv_usec == LONG_MAX ? NULL : &event->timeout; int ret; - for(_event_timeout_set(event); - (ret = select(0, &event->rfds, &event->wfds, NULL, - event->timeout)) != -1; - _event_timeout_set(event)) + for(; (ret = select(event->fdmax+1, &event->rfds, &event->wfds, NULL, + timeout)) != -1; + timeout = event->timeout.tv_sec == LONG_MAX + && event->timeout.tv_usec == LONG_MAX + ? NULL : &event->timeout) { - if(_event_timeout_hit(event)) - continue; - /* FIXME */ + _loop_timeouts(event); + _loop_reads(event); + _loop_writes(event); } if(ret != -1) return 0; @@ -114,16 +107,101 @@ int event_loop(Event * event) return 1; } +static void _loop_timeouts(Event * event) +{ + struct timeval now; + unsigned int i = 0; -int event_timeout(Event * event, EventTimeoutFunc * func, - struct timeval timeout, void * data) + if(gettimeofday(&now, NULL) != 0) + return perror("gettimeofday"); + while(i < array_count(event->timeouts)) + { + /* FIXME */ + i++; + } +} + +static void _loop_reads(Event * event) +{ + unsigned int i = 0; + EventIO * eio; + + while(i < array_count(event->reads)) + { + array_get(event->reads, i, &eio); + if(FD_ISSET(eio->fd, &event->rfds) + && eio->func(eio->fd, eio->data) != 0) + { + array_remove_pos(event->reads, i); + continue; + } + i++; + } +} + +static void _loop_writes(Event * event) +{ + unsigned int i = 0; + EventIO * eio; + + while(i < array_count(event->writes)) + { + array_get(event->writes, i, &eio); + if(FD_ISSET(eio->fd, &event->wfds) + && eio->func(eio->fd, eio->data) != 0) + { + array_remove_pos(event->writes, i); + continue; + } + i++; + } +} + + +/* event_register_io_read */ +int event_register_io_read(Event * event, int fd, EventIOFunc func, + void * userdata) +{ + EventIO * eventio; + + if((eventio = malloc(sizeof(EventIO))) == NULL) + return 1; + eventio->fd = fd; + eventio->func = func; + eventio->data = userdata; + array_append(event->reads, eventio); + event->fdmax = max(event->fdmax, fd); + return 0; +} + + +/* event_register_io_write */ +int event_register_io_write(Event * event, int fd, EventIOFunc func, + void * userdata) +{ + EventIO * eventio; + + if((eventio = malloc(sizeof(EventIO))) == NULL) + return 1; + eventio->fd = fd; + eventio->func = func; + eventio->data = userdata; + array_append(event->writes, eventio); + event->fdmax = max(event->fdmax, fd); + return 0; +} + + +/* event_register_timeout */ +int event_register_timeout(Event * event, struct timeval timeout, + EventTimeoutFunc * func, void * data) { EventTimeout * eventtimeout; if((eventtimeout = malloc(sizeof(EventTimeout))) == NULL) return 1; - eventtimeout->func = func; eventtimeout->timeout = timeout; + eventtimeout->func = func; eventtimeout->data = data; array_append(event->timeouts, eventtimeout); /* FIXME fast recompute next timeout */