From 9501343314fa326026a3052c75ced2ea88b88e33 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 17 Sep 2005 22:58:38 +0000 Subject: [PATCH] Nicer code --- include/event.h | 3 ++ src/appserver.c | 91 +++++++++++++++++++++---------- src/event.c | 138 ++++++++++++++++++++++-------------------------- 3 files changed, 128 insertions(+), 104 deletions(-) diff --git a/include/event.h b/include/event.h index 5e62985..c575771 100644 --- a/include/event.h +++ b/include/event.h @@ -29,5 +29,8 @@ 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); +int event_unregister_io_read(Event * event, int fd); +int event_unregister_io_write(Event * event, int fd); +int event_unregister_timeout(Event * event, EventTimeoutFunc func); #endif /* !_EVENT_H */ diff --git a/src/appserver.c b/src/appserver.c index b876706..ec8bc4a 100644 --- a/src/appserver.c +++ b/src/appserver.c @@ -28,8 +28,10 @@ typedef struct _AppServerClient int fd; uint32_t addr; /* FIXME uint8_t[4] instead? */ uint16_t port; - char buffer_read[ASC_BUFSIZE]; - char buffer_write[ASC_BUFSIZE]; + char buf_read[ASC_BUFSIZE]; + unsigned int buf_read_cnt; + char buf_write[ASC_BUFSIZE]; + unsigned int buf_write_cnt; } AppServerClient; @@ -44,6 +46,8 @@ AppServerClient * appserverclient_new(int fd, uint32_t addr, uint16_t port) asc->fd = fd; asc->addr = addr; asc->port = port; + asc->buf_read_cnt = 0; + asc->buf_write_cnt = 0; return asc; } @@ -86,25 +90,60 @@ static int _appserver_accept(int fd, AppServer * appserver) return 1; if((asc = appserverclient_new(newfd, sa.sin_addr.s_addr, sa.sin_port)) == NULL) - return 1; + { + /* FIXME report error */ + close(newfd); + return 0; + } array_append(appserver->clients, asc); - event_register_io_read(appserver->event, newfd, _appserver_read, - appserver); -/* event_register_io_write(appserver->event, newfd, _appserver_write, - appserver); */ + event_register_io_read(appserver->event, newfd, + (EventIOFunc)_appserver_read, appserver); return 0; } static int _appserver_read(int fd, AppServer * appserver) +{ + AppServerClient * asc = NULL; + unsigned int i; + ssize_t len; + + for(i = 0; i < array_count(appserver->clients); i++) + { + if(array_get(appserver->clients, i, &asc)) + break; + if(fd == asc->fd) + break; + asc = NULL; + } + if(asc == NULL) + return 1; + if((len = sizeof(asc->buf_read) - asc->buf_read_cnt) < 0 + || (len = read(fd, &asc->buf_read[asc->buf_read_cnt], + len)) <= 0) + { + if(asc->buf_write_cnt > 0) + event_unregister_io_write(appserver->event, fd); + event_unregister_io_read(appserver->event, fd); + appserverclient_delete(asc); + array_remove_pos(appserver->clients, i); + return 1; + } + asc->buf_read_cnt+=len; +#ifdef DEBUG + fprintf(stderr, "%s%d%s%d%s", "_appserver_read(", fd, + ", appserver): ", len, " characters read\n"); +#endif + return 0; +} + + +static int _appserver_write(int fd, AppServer * appserver) { AppServerClient * asc = NULL; unsigned int i; int len; -#ifdef DEBUG - fprintf(stderr, "%s%d%s", "_appserver_read(", fd, ", appserver)\n"); -#endif for(i = 0; i < array_count(appserver->clients); i++) { if(!array_get(appserver->clients, i, &asc)) @@ -113,27 +152,23 @@ static int _appserver_read(int fd, AppServer * appserver) break; asc = NULL; } - if(asc == NULL || (len = read(fd, asc->buffer_read, - sizeof(asc->buffer_read)-1)) < 0) + if(asc == NULL) return 1; - if(len == 0) + len = asc->buf_read_cnt; + if((len = write(fd, asc->buf_write, len)) <= 0) { -#ifdef DEBUG - perror("read"); -#endif - close(fd); + if(asc->buf_read_cnt == ASC_BUFSIZE) + event_unregister_io_read(appserver->event, fd); + event_unregister_io_write(appserver->event, fd); + array_remove_pos(appserver->clients, i); + appserverclient_delete(asc); return 1; } - asc->buffer_read[len] = '\0'; - fprintf(stderr, "\"%s\"\n", asc->buffer_read); - return 0; -} - - -static int _appserver_write(int fd, AppServer * appserver) -{ + memmove(asc->buf_write, &asc->buf_write[len], len); + asc->buf_write_cnt-=len; #ifdef DEBUG - fprintf(stderr, "%s%d%s", "_appserver_write(", fd, ", appserver)\n"); + fprintf(stderr, "%s%d%s%d%s", "_appserver_write(", fd, + ", appserver): ", len, " characters written\n"); #endif return 0; } @@ -216,8 +251,8 @@ static int _new_server(AppServer * appserver, int options) perror("close"); /* FIXME report error appropriately */ return 1; } - event_register_io_read(appserver->event, fd, _appserver_accept, - appserver); + event_register_io_read(appserver->event, fd, + (EventIOFunc)_appserver_accept, appserver); return 0; } diff --git a/src/event.c b/src/event.c index ace5b01..a80323a 100644 --- a/src/event.c +++ b/src/event.c @@ -61,12 +61,13 @@ Event * event_new(void) free(event); return NULL; } - event->timeout.tv_sec = LONG_MAX; - event->timeout.tv_usec = LONG_MAX; - event->reads = eventioarray_new(); /* FIXME */ - event->writes = eventioarray_new(); /* FIXME */ + event->fdmax = -1; FD_ZERO(&event->rfds); FD_ZERO(&event->wfds); + event->reads = eventioarray_new(); /* FIXME */ + event->writes = eventioarray_new(); /* FIXME */ + event->timeout.tv_sec = LONG_MAX; + event->timeout.tv_usec = LONG_MAX; return event; } @@ -83,8 +84,7 @@ void event_delete(Event * event) /* useful */ static void _loop_timeout(Event * event); -static void _loop_io_read(Event * event, fd_set * rfds); -static void _loop_io_write(Event * event, fd_set * wfds); +static void _loop_io(Event * event, eventioArray * eios, fd_set * fds); int event_loop(Event * event) { struct timeval * timeout = event->timeout.tv_sec == LONG_MAX @@ -96,8 +96,8 @@ int event_loop(Event * event) while((ret = select(event->fdmax+1, &rfds, &wfds, NULL, timeout)) != -1) { _loop_timeout(event); - _loop_io_read(event, &rfds); - _loop_io_write(event, &wfds); + _loop_io(event, event->reads, &rfds); + _loop_io(event, event->writes, &wfds); timeout = event->timeout.tv_sec == LONG_MAX && event->timeout.tv_usec == LONG_MAX ? NULL : &event->timeout; @@ -107,8 +107,8 @@ int event_loop(Event * event) if(ret != -1) return 0; #ifdef DEBUG - sleep(1); perror("select"); + sleep(1); #endif return 1; } @@ -131,84 +131,27 @@ static void _loop_timeout(Event * event) } } -static int _io_fd_remove(Event * event, int fd); -static void _loop_io_read(Event * event, fd_set * rfds) +static void _loop_io(Event * event, eventioArray * eios, fd_set * fds) { unsigned int i = 0; EventIO * eio; + int fd; - while(i < array_count(event->reads)) + while(i < array_count(eios)) { - array_get(event->reads, i, &eio); + array_get(eios, i, &eio); #ifdef DEBUG - fprintf(stderr, "%s%d%s%p%s", "_loop_reads(): i=", i, + fprintf(stderr, "%s%d%s%p%s", "_loop_io(): i=", i, ", eio=", eio, "\n"); #endif - if(FD_ISSET(eio->fd, rfds) - && eio->func(eio->fd, eio->data) != 0) - { - event->fdmax = _io_fd_remove(event, eio->fd); - continue; - } - i++; + if((fd = eio->fd) <= event->fdmax && FD_ISSET(fd, fds) + && eio->func(fd, eio->data) != 0) + event_unregister_io_read(event, fd); + else + i++; } } -static void _loop_io_write(Event * event, fd_set * wfds) -{ - unsigned int i = 0; - EventIO * eio; - - while(i < array_count(event->writes)) - { - array_get(event->writes, i, &eio); /* FIXME check error */ -#ifdef DEBUG - fprintf(stderr, "%s%d%s%p%s", "_loop_writes(): i=", i, - ", eio=", eio, "\n"); -#endif - if(FD_ISSET(eio->fd, wfds) - && eio->func(eio->fd, eio->data) != 0) - { - event->fdmax = _io_fd_remove(event, eio->fd); - continue; - } - i++; - } -} - -static int _io_fd_remove(Event * event, int fd) -{ - unsigned int i; - int fdmax = -1; - EventIO * eio; - - for(i = 0; i < array_count(event->reads); i++) - { - array_get(event->reads, i, &eio); /* FIXME check error */ - if(eio->fd != fd) - { - fdmax = max(fdmax, eio->fd); - continue; - } - FD_CLR(eio->fd, &event->rfds); - free(eio); - array_remove_pos(event->reads, i); - } - for(i = 0; i < array_count(event->writes); i++) - { - array_get(event->writes, i, &eio); /* FIXME check error */ - if(eio->fd != fd) - { - fdmax = max(fdmax, eio->fd); - continue; - } - FD_CLR(eio->fd, &event->wfds); - free(eio); - array_remove_pos(event->writes, i); - } - return fdmax; -} - /* event_register_io_read */ int event_register_io_read(Event * event, int fd, EventIOFunc func, @@ -267,3 +210,46 @@ int event_register_timeout(Event * event, struct timeval timeout, } return 0; } + + +/* event_unregister_io_read */ +static int _unregister_io(eventioArray * eios, fd_set * fds, int fd); +int event_unregister_io_read(Event * event, int fd) +{ + event->fdmax = _unregister_io(event->reads, &event->rfds, fd); + event->fdmax = max(event->fdmax, _unregister_io(event->writes, NULL, + -1)); + return 0; +} + + +/* event_unregister_io_write */ +int event_unregister_io_write(Event * event, int fd) +{ + event->fdmax = _unregister_io(event->writes, &event->wfds, fd); + event->fdmax = max(event->fdmax, _unregister_io(event->reads, NULL, + -1)); + return 0; +} + +static int _unregister_io(eventioArray * eios, fd_set * fds, int fd) +{ + unsigned int i = 0; + EventIO * eio; + int fdmax = -1; + + while(i < array_count(eios)) + { + array_get(eios, i, &eio); + if(eio->fd != fd) + { + fdmax = max(fdmax, eio->fd); + i++; + continue; + } + FD_CLR(fd, fds); + array_remove_pos(eios, i); + free(eio); + } + return fdmax; +}