Initial import of libucore
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "iomux_impl.h"
|
||||
|
||||
|
||||
//dispatchers for the IOMux implementations */
|
||||
|
||||
struct IOMux *iomux_create(enum IOMUX_TYPE type)
|
||||
{
|
||||
struct IOMux *mux = calloc(1, sizeof *mux);
|
||||
int rc = -1;
|
||||
|
||||
|
||||
switch(type) {
|
||||
case IOMUX_TYPE_DEFAULT:
|
||||
case IOMUX_TYPE_EPOLL:
|
||||
rc = iomux_epoll_init(mux);
|
||||
break;
|
||||
case IOMUX_TYPE_SELECT:
|
||||
rc = iomux_select_init(mux);
|
||||
break;
|
||||
}
|
||||
|
||||
if(rc != 0) {
|
||||
//try fallback to select
|
||||
rc = iomux_select_init(mux);
|
||||
}
|
||||
|
||||
if(rc == 0) {
|
||||
rc = gettimeofday(&mux->now, NULL);
|
||||
assert(rc == 0);
|
||||
uc_timers_init(&mux->timers);
|
||||
} else {
|
||||
free(mux);
|
||||
mux = NULL;
|
||||
}
|
||||
|
||||
return mux;
|
||||
}
|
||||
|
||||
void iomux_delete(struct IOMux *mux)
|
||||
{
|
||||
mux->delete_impl(mux);
|
||||
memset(mux, 0xfa, sizeof *mux);
|
||||
free(mux);
|
||||
}
|
||||
|
||||
//convert the difference between future and now
|
||||
static inline void future_to_interval(struct timeval *future, const struct timeval *now, struct timeval *result)
|
||||
{
|
||||
if(timercmp(future, now, >)) {
|
||||
timersub(future, now, result);
|
||||
} else {
|
||||
result->tv_sec = 0;
|
||||
result->tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int iomux_run(struct IOMux *mux)
|
||||
{
|
||||
for(;;) {
|
||||
int rc;
|
||||
struct timeval first_timer;
|
||||
struct timeval timeout;
|
||||
struct timeval *timeoutp;;
|
||||
int has_timers = 0;
|
||||
|
||||
|
||||
rc = gettimeofday(&mux->now, NULL);
|
||||
assert(rc == 0);
|
||||
|
||||
if(uc_timers_first(&mux->timers, &first_timer) == 0) {
|
||||
future_to_interval(&first_timer, &mux->now, &timeout);
|
||||
timeoutp = &timeout;
|
||||
/* fprintf(stdout, "now %d %d future %d %d interval %d %d\n", mux->now.tv_sec, mux->now.tv_usec,
|
||||
first_timer.tv_sec, first_timer.tv_usec,
|
||||
timeout.tv_sec, timeout.tv_usec);
|
||||
fflush(stdout);
|
||||
*/
|
||||
|
||||
assert(timeout.tv_sec >= 0);
|
||||
assert(timeout.tv_usec >= 0);
|
||||
|
||||
has_timers = 1;
|
||||
} else {
|
||||
timeoutp = NULL; //no timeout
|
||||
}
|
||||
rc = mux->run_impl(mux, timeoutp);
|
||||
if(rc < 0)
|
||||
return rc;
|
||||
|
||||
if(rc == 0 && !has_timers) //no more events, ever
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iomux_timers_run(struct IOMux *mux)
|
||||
{
|
||||
int event_cnt;
|
||||
gettimeofday(&mux->now, NULL);
|
||||
|
||||
event_cnt = uc_timers_run(&mux->timers, &mux->now);
|
||||
assert(event_cnt >= 0);
|
||||
|
||||
return event_cnt;
|
||||
}
|
||||
|
||||
int iomux_register_fd(struct IOMux *mux, struct IOMuxFD *fd)
|
||||
{
|
||||
assert(mux != NULL);
|
||||
assert(fd != NULL);
|
||||
assert(fd->callback != NULL);
|
||||
return mux->register_fd_impl(mux, fd);
|
||||
}
|
||||
|
||||
int iomux_unregister_fd(struct IOMux *mux, struct IOMuxFD *fd)
|
||||
{
|
||||
assert(mux != NULL);
|
||||
assert(fd != NULL);
|
||||
return mux->unregister_fd_impl(mux, fd);
|
||||
}
|
||||
|
||||
int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd)
|
||||
{
|
||||
assert(mux != NULL);
|
||||
assert(fd != NULL);
|
||||
assert(fd->callback != NULL);
|
||||
return mux->update_events_impl(mux, fd);
|
||||
}
|
||||
|
||||
struct UCTimers *iomux_get_timers(struct IOMux *mux)
|
||||
{
|
||||
return &mux->timers;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user