2017-04-07 14:43:12 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* machinarium.
|
|
|
|
*
|
|
|
|
* cooperative multitasking engine.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <machinarium_private.h>
|
|
|
|
#include <machinarium.h>
|
|
|
|
|
|
|
|
typedef struct mm_epoll_t mm_epoll_t;
|
|
|
|
|
|
|
|
struct mm_epoll_t {
|
2017-04-07 14:52:10 +00:00
|
|
|
mm_poll_t poll;
|
|
|
|
int fd;
|
|
|
|
struct epoll_event *list;
|
|
|
|
int size;
|
|
|
|
int count;
|
2017-04-07 14:43:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static mm_poll_t*
|
|
|
|
mm_epoll_create(void)
|
|
|
|
{
|
|
|
|
mm_epoll_t *epoll;
|
|
|
|
epoll = malloc(sizeof(mm_epoll_t));
|
|
|
|
if (epoll == NULL)
|
|
|
|
return NULL;
|
|
|
|
epoll->poll.iface = &mm_epoll_if;
|
2017-04-07 14:52:10 +00:00
|
|
|
epoll->count = 0;
|
|
|
|
epoll->size = 1024;
|
|
|
|
int size = sizeof(struct epoll_event) * epoll->size;
|
|
|
|
epoll->list = malloc(size);
|
|
|
|
if (epoll->list == NULL) {
|
|
|
|
free(epoll);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
memset(epoll->list, 0, size);
|
|
|
|
epoll->fd = epoll_create(epoll->size);
|
|
|
|
if (epoll->fd == -1) {
|
|
|
|
free(epoll->list);
|
|
|
|
free(epoll);
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-04-07 14:43:12 +00:00
|
|
|
return &epoll->poll;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
mm_epoll_free(mm_poll_t *poll)
|
|
|
|
{
|
2017-04-07 14:52:10 +00:00
|
|
|
mm_epoll_t *epoll = (mm_epoll_t*)poll;
|
|
|
|
if (epoll->list)
|
|
|
|
free(epoll->list);
|
2017-04-07 14:43:12 +00:00
|
|
|
free(poll);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
mm_epoll_shutdown(mm_poll_t *poll)
|
|
|
|
{
|
2017-04-07 14:52:10 +00:00
|
|
|
mm_epoll_t *epoll = (mm_epoll_t*)poll;
|
|
|
|
if (epoll->fd != -1) {
|
|
|
|
close(epoll->fd);
|
|
|
|
epoll->fd = -1;
|
|
|
|
}
|
2017-04-07 14:43:12 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-04-07 14:52:10 +00:00
|
|
|
mm_epoll_step(mm_poll_t *poll, int timeout)
|
2017-04-07 14:43:12 +00:00
|
|
|
{
|
2017-04-07 14:52:10 +00:00
|
|
|
mm_epoll_t *epoll = (mm_epoll_t*)poll;
|
|
|
|
int count;
|
|
|
|
count = epoll_wait(epoll->fd, epoll->list, epoll->count, timeout);
|
|
|
|
if (count <= 0)
|
|
|
|
return 0;
|
|
|
|
int i = 0;
|
|
|
|
while (i < count) {
|
|
|
|
struct epoll_event *ev = &epoll->list[i];
|
|
|
|
mm_fd_t *fd = ev->data.ptr;
|
|
|
|
int events = 0;
|
|
|
|
if (ev->events & EPOLLIN) {
|
|
|
|
events = MM_R;
|
|
|
|
}
|
|
|
|
if (ev->events & EPOLLOUT ||
|
|
|
|
ev->events & EPOLLERR ||
|
|
|
|
ev->events & EPOLLHUP) {
|
|
|
|
events |= MM_W;
|
|
|
|
}
|
|
|
|
fd->callback(fd, events);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return count;
|
2017-04-07 14:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
mm_epoll_add(mm_poll_t *poll, mm_fd_t *fd, int mask)
|
|
|
|
{
|
|
|
|
(void)poll;
|
|
|
|
(void)fd;
|
|
|
|
(void)mask;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
mm_epoll_modify(mm_poll_t *poll, mm_fd_t *fd, int mask)
|
|
|
|
{
|
|
|
|
(void)poll;
|
|
|
|
(void)fd;
|
|
|
|
(void)mask;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
mm_epoll_del(mm_poll_t *poll, mm_fd_t *fd)
|
|
|
|
{
|
|
|
|
(void)poll;
|
|
|
|
(void)fd;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mm_pollif_t mm_epoll_if =
|
|
|
|
{
|
|
|
|
.name = "epoll",
|
|
|
|
.create = mm_epoll_create,
|
|
|
|
.free = mm_epoll_free,
|
|
|
|
.shutdown = mm_epoll_shutdown,
|
|
|
|
.step = mm_epoll_step,
|
|
|
|
.add = mm_epoll_add,
|
|
|
|
.modify = mm_epoll_modify,
|
|
|
|
.del = mm_epoll_del
|
|
|
|
};
|