It's a whole mess. Shit. Trying anyway.
This commit is contained in:
parent
33e10406ef
commit
f3b3c2f12c
|
@ -23,4 +23,7 @@ AppServer * appserver_new(const char * app, int options);
|
||||||
AppServer * appserver_new_event(const char * app, int options, Event * event);
|
AppServer * appserver_new_event(const char * app, int options, Event * event);
|
||||||
void appserver_delete(AppServer * appserver);
|
void appserver_delete(AppServer * appserver);
|
||||||
|
|
||||||
|
/* useful */
|
||||||
|
int appserver_loop(AppServer * appserver);
|
||||||
|
|
||||||
#endif /* !_APPSERVER_H */
|
#endif /* !_APPSERVER_H */
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
|
|
||||||
# define ARRAY(type, name) \
|
# define ARRAY(type, name) \
|
||||||
typedef Array name ## Array; \
|
typedef Array type ## Array; \
|
||||||
Array * name ## ArrayNew(void) { return array_new(sizeof(type)); }
|
Array * name ## array_new(void) { return array_new(sizeof(type)); }
|
||||||
|
|
||||||
|
|
||||||
/* types */
|
/* types */
|
||||||
|
@ -25,5 +25,8 @@ void array_delete(Array * array);
|
||||||
int array_append(Array * array, void * data);
|
int array_append(Array * array, void * data);
|
||||||
void array_apply(Array * array, ArrayApplyFunc func, void * userdata);
|
void array_apply(Array * array, ArrayApplyFunc func, void * userdata);
|
||||||
unsigned int array_count(Array * array);
|
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 */
|
#endif /* !_ARRAY_H */
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
/* types */
|
/* types */
|
||||||
typedef struct _Event Event;
|
typedef struct _Event Event;
|
||||||
|
|
||||||
typedef void (*EventFunc)(int fd, void * data);
|
typedef int (*EventIOFunc)(int fd, void * data);
|
||||||
typedef void (*EventTimeoutFunc)(void * data);
|
typedef int (*EventTimeoutFunc)(void * data);
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
|
@ -23,8 +23,11 @@ void event_delete(Event * event);
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
int event_loop(Event * event);
|
int event_loop(Event * event);
|
||||||
int event_register_fd_read(Event * event, int fd, EventFunc * func);
|
int event_register_io_read(Event * event, int fd, EventIOFunc func,
|
||||||
int event_register_timeout(Event * event, EventTimeoutFunc * func,
|
void * userdata);
|
||||||
struct timeval timeout, 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 */
|
#endif /* !_EVENT_H */
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <array.h>
|
#include "array.h"
|
||||||
#include <string.h>
|
#include "string.h"
|
||||||
#include "appserver.h"
|
#include "appserver.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ struct _AppServer
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
static void _appserver_accept(int fd, AppServer * appserver)
|
static int _appserver_accept(int fd, AppServer * appserver)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
int sa_size = sizeof(struct sockaddr_in);
|
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 */
|
/* FIXME append client to the clients list with the appropriate state */
|
||||||
if((fd2 = accept(fd, (struct sockaddr *)&sa, &sa_size)) == -1)
|
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))
|
if((asc = appserverclient_new(fd2, sa.sin_addr.s_addr, sa.sin_port))
|
||||||
== NULL)
|
== NULL)
|
||||||
return;
|
return 0;
|
||||||
array_append(appserver->clients, asc);
|
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)
|
static int _new_interface(AppServer * appserver, const char * app)
|
||||||
{
|
|
||||||
/* FIXME interfaces are hardcoded */
|
/* FIXME interfaces are hardcoded */
|
||||||
|
{
|
||||||
if(string_compare(app, "Session") == 0)
|
if(string_compare(app, "Session") == 0)
|
||||||
{
|
{
|
||||||
appserver->port = 4242; /* FIXME */
|
appserver->port = 4242; /* FIXME */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if(string_compare(app, "Network") == 0)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
else if(string_compare(app, "Probe") == 0)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +158,8 @@ static int _new_server(AppServer * appserver, int options)
|
||||||
return 1; /* FIXME report error */
|
return 1; /* FIXME report error */
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
sa.sin_port = htons(appserver->port);
|
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
|
if(bind(fd, (struct sockaddr *)&sa, sizeof(sa)) != 0
|
||||||
|| listen(fd, 5) != 0)
|
|| listen(fd, 5) != 0)
|
||||||
{
|
{
|
||||||
|
@ -155,7 +168,7 @@ static int _new_server(AppServer * appserver, int options)
|
||||||
perror("close"); /* FIXME report error appropriately */
|
perror("close"); /* FIXME report error appropriately */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
event_register_fd_read(appserver->event, fd, _appserver_accept);
|
event_register_io_read(appserver->event, fd, _appserver_accept, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,3 +179,10 @@ void appserver_delete(AppServer * appserver)
|
||||||
event_delete(appserver->event);
|
event_delete(appserver->event);
|
||||||
free(appserver);
|
free(appserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* useful */
|
||||||
|
int appserver_loop(AppServer * appserver)
|
||||||
|
{
|
||||||
|
return event_loop(appserver->event);
|
||||||
|
}
|
||||||
|
|
21
src/array.c
21
src/array.c
|
@ -65,3 +65,24 @@ unsigned int array_count(Array * array)
|
||||||
{
|
{
|
||||||
return array->count;
|
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;
|
||||||
|
}
|
||||||
|
|
192
src/event.c
192
src/event.c
|
@ -3,110 +3,103 @@
|
||||||
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/select.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
|
||||||
|
#define max(a, b) ((a) >= (b)) ? (a) : (b)
|
||||||
|
|
||||||
|
|
||||||
/* Event */
|
/* Event */
|
||||||
|
/* private */
|
||||||
|
/* types */
|
||||||
typedef struct _EventTimeout
|
typedef struct _EventTimeout
|
||||||
{
|
{
|
||||||
EventTimeoutFunc * func;
|
|
||||||
void * data;
|
|
||||||
struct timeval now;
|
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
EventTimeoutFunc func;
|
||||||
|
void * data;
|
||||||
} EventTimeout;
|
} EventTimeout;
|
||||||
ARRAY(EventTimeout, EventTimeout);
|
ARRAY(EventTimeout, eventtimeout);
|
||||||
|
|
||||||
|
typedef struct _EventIO
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
EventIOFunc func;
|
||||||
|
void * data;
|
||||||
|
} EventIO;
|
||||||
|
ARRAY(EventIO, eventio);
|
||||||
|
|
||||||
struct _Event
|
struct _Event
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
fd_set wfds;
|
fd_set wfds;
|
||||||
EventTimeoutArray * timeouts;
|
EventTimeoutArray * timeouts;
|
||||||
struct timeval now;
|
struct timeval timeout;
|
||||||
struct timeval * timeout;
|
EventIOArray * reads;
|
||||||
|
EventIOArray * writes;
|
||||||
|
int fdmax;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
/* public */
|
||||||
static void _debug_timeval(struct timeval * tv, char * message)
|
/* functions */
|
||||||
{
|
/* event_new */
|
||||||
fprintf(stderr, "%s%s%lu%s%lu%s", message, ": ", tv->tv_sec, "s, ",
|
|
||||||
tv->tv_usec, "us\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Event * event_new(void)
|
Event * event_new(void)
|
||||||
{
|
{
|
||||||
Event * event;
|
Event * event;
|
||||||
|
|
||||||
if((event = malloc(sizeof(Event))) == NULL)
|
if((event = malloc(sizeof(Event))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if(gettimeofday(&event->now, NULL) != 0
|
if((event->timeouts = eventtimeoutarray_new()) == NULL)
|
||||||
|| (event->timeouts = EventTimeoutArrayNew()) == NULL)
|
|
||||||
{
|
{
|
||||||
perror("event");
|
|
||||||
free(event);
|
free(event);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
event->timeout.tv_sec = LONG_MAX;
|
||||||
_debug_timeval(&event->now, "event_new()");
|
event->timeout.tv_usec = LONG_MAX;
|
||||||
#endif
|
event->reads = eventioarray_new(); /* FIXME */
|
||||||
|
event->writes = eventioarray_new(); /* FIXME */
|
||||||
FD_ZERO(&event->rfds);
|
FD_ZERO(&event->rfds);
|
||||||
FD_ZERO(&event->wfds);
|
FD_ZERO(&event->wfds);
|
||||||
event->timeout = NULL;
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* event_delete */
|
||||||
void event_delete(Event * event)
|
void event_delete(Event * event)
|
||||||
{
|
{
|
||||||
|
array_delete(event->timeouts);
|
||||||
|
array_delete(event->reads);
|
||||||
|
array_delete(event->writes);
|
||||||
free(event);
|
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 */
|
/* useful */
|
||||||
|
static void _loop_timeouts(Event * event);
|
||||||
|
static void _loop_reads(Event * event);
|
||||||
|
static void _loop_writes(Event * event);
|
||||||
int event_loop(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;
|
int ret;
|
||||||
|
|
||||||
for(_event_timeout_set(event);
|
for(; (ret = select(event->fdmax+1, &event->rfds, &event->wfds, NULL,
|
||||||
(ret = select(0, &event->rfds, &event->wfds, NULL,
|
timeout)) != -1;
|
||||||
event->timeout)) != -1;
|
timeout = event->timeout.tv_sec == LONG_MAX
|
||||||
_event_timeout_set(event))
|
&& event->timeout.tv_usec == LONG_MAX
|
||||||
|
? NULL : &event->timeout)
|
||||||
{
|
{
|
||||||
if(_event_timeout_hit(event))
|
_loop_timeouts(event);
|
||||||
continue;
|
_loop_reads(event);
|
||||||
/* FIXME */
|
_loop_writes(event);
|
||||||
}
|
}
|
||||||
if(ret != -1)
|
if(ret != -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -114,16 +107,101 @@ int event_loop(Event * event)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _loop_timeouts(Event * event)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
int event_timeout(Event * event, EventTimeoutFunc * func,
|
if(gettimeofday(&now, NULL) != 0)
|
||||||
struct timeval timeout, void * data)
|
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;
|
EventTimeout * eventtimeout;
|
||||||
|
|
||||||
if((eventtimeout = malloc(sizeof(EventTimeout))) == NULL)
|
if((eventtimeout = malloc(sizeof(EventTimeout))) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
eventtimeout->func = func;
|
|
||||||
eventtimeout->timeout = timeout;
|
eventtimeout->timeout = timeout;
|
||||||
|
eventtimeout->func = func;
|
||||||
eventtimeout->data = data;
|
eventtimeout->data = data;
|
||||||
array_append(event->timeouts, eventtimeout);
|
array_append(event->timeouts, eventtimeout);
|
||||||
/* FIXME fast recompute next timeout */
|
/* FIXME fast recompute next timeout */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user