byedpi/conev.c

219 lines
5.0 KiB
C
Raw Permalink Normal View History

2024-05-02 16:36:29 +00:00
#include "conev.h"
2023-06-03 19:52:10 +00:00
#include <stdlib.h>
#include <string.h>
#include <limits.h>
2024-05-08 17:15:57 +00:00
#include <assert.h>
#include "error.h"
2023-06-03 19:52:10 +00:00
struct poolhd *init_pool(int count)
{
2024-05-04 14:55:48 +00:00
struct poolhd *pool = calloc(sizeof(struct poolhd), 1);
2023-06-03 19:52:10 +00:00
if (!pool) {
uniperror("init pool");
2023-06-03 19:52:10 +00:00
return 0;
}
pool->max = count;
pool->count = 0;
2024-05-04 14:11:04 +00:00
pool->iters = 0;
2023-06-03 19:52:10 +00:00
#ifndef NOEPOLL
int efd = epoll_create(count);
if (efd < 0) {
free(pool);
return 0;
}
pool->efd = efd;
#endif
pool->pevents = malloc(sizeof(*pool->pevents) * count);
pool->links = malloc(sizeof(*pool->links) * count);
pool->items = malloc(sizeof(*pool->items) * count);
2023-06-03 19:52:10 +00:00
if (!pool->pevents || !pool->links || !pool->items) {
uniperror("init pool");
2023-06-03 19:52:10 +00:00
destroy_pool(pool);
return 0;
}
for (int i = 0; i < count; i++) {
pool->links[i] = &(pool->items[i]);
}
memset(pool->items, 0, sizeof(*pool->items));
2023-06-03 19:52:10 +00:00
return pool;
}
struct eval *add_event(struct poolhd *pool, enum eid type,
int fd, int e)
{
2024-05-08 17:15:57 +00:00
assert(fd > 0);
2024-05-04 16:42:19 +00:00
if (pool->count >= pool->max) {
LOG(LOG_E, "add_event: pool is full\n");
2024-05-04 16:42:19 +00:00
return 0;
2024-05-04 15:58:23 +00:00
}
2024-05-04 16:42:19 +00:00
struct eval *val = pool->links[pool->count];
2024-03-08 00:37:02 +00:00
memset(val, 0, sizeof(*val));
2024-05-04 16:42:19 +00:00
val->mod_iter = pool->iters;
2023-06-03 19:52:10 +00:00
val->fd = fd;
2024-05-04 15:58:23 +00:00
val->index = pool->count;
2023-06-03 19:52:10 +00:00
val->type = type;
2023-06-03 19:52:10 +00:00
#ifndef NOEPOLL
2024-05-04 19:57:38 +00:00
struct epoll_event ev = { .events = EPOLLRDHUP | e, .data = {val} };
2023-06-03 19:52:10 +00:00
if (epoll_ctl(pool->efd, EPOLL_CTL_ADD, fd, &ev)) {
uniperror("add event");
2023-06-03 19:52:10 +00:00
return 0;
}
#else
2024-05-04 15:58:23 +00:00
struct pollfd *pfd = &(pool->pevents[pool->count]);
2023-06-03 19:52:10 +00:00
pfd->fd = fd;
2024-05-09 23:30:17 +00:00
pfd->events = POLLRDHUP | e;
2023-06-03 19:52:10 +00:00
pfd->revents = 0;
#endif
2023-06-03 19:52:10 +00:00
pool->count++;
return val;
}
void del_event(struct poolhd *pool, struct eval *val)
{
2024-05-09 23:30:17 +00:00
assert(val->fd >= -1 && val->mod_iter <= pool->iters);
2024-05-08 17:15:57 +00:00
if (val->fd == -1) {
2023-06-03 19:52:10 +00:00
return;
}
2024-05-09 23:30:17 +00:00
#ifdef NOEPOLL
assert(val->fd == pool->pevents[val->index].fd);
#else
epoll_ctl(pool->efd, EPOLL_CTL_DEL, val->fd, 0);
2024-05-09 23:30:17 +00:00
#endif
2024-03-08 00:37:02 +00:00
if (val->buff.data) {
2024-05-08 17:15:57 +00:00
assert(val->buff.size);
2024-03-08 00:37:02 +00:00
free(val->buff.data);
val->buff.data = 0;
2023-07-03 17:59:39 +00:00
}
2023-06-03 19:52:10 +00:00
close(val->fd);
2024-05-08 17:15:57 +00:00
val->fd = -1;
2024-05-04 16:42:19 +00:00
val->mod_iter = pool->iters;
2023-06-03 19:52:10 +00:00
pool->count--;
struct eval *ev = pool->links[pool->count];
if (ev != val)
{
int index = val->index;
pool->links[index] = ev;
pool->links[pool->count] = val;
#ifdef NOEPOLL
pool->pevents[index] = pool->pevents[pool->count];
#endif
ev->index = index;
}
if (val->pair) {
2024-05-08 17:15:57 +00:00
if (val->pair->pair == val) {
2023-07-06 18:21:44 +00:00
val->pair->pair = 0;
}
2024-05-08 17:15:57 +00:00
struct eval *e = val->pair;
2023-07-06 18:21:44 +00:00
val->pair = 0;
2024-05-08 17:15:57 +00:00
del_event(pool, e);
2023-06-03 19:52:10 +00:00
}
2024-05-08 17:15:57 +00:00
assert(pool->count > 0);
2023-06-03 19:52:10 +00:00
}
void destroy_pool(struct poolhd *pool)
{
for (int x = 0; x < pool->count; x++) {
struct eval *val = pool->links[x];
2023-07-03 17:59:39 +00:00
if (val->fd) {
close(val->fd);
2023-08-20 13:30:03 +00:00
val->fd = 0;
2023-07-03 17:59:39 +00:00
}
2024-03-08 00:37:02 +00:00
if (val->buff.data) {
free(val->buff.data);
val->buff.data = 0;
2023-07-03 17:59:39 +00:00
}
2023-06-03 19:52:10 +00:00
}
free(pool->items);
free(pool->links);
free(pool->pevents);
2023-06-03 19:52:10 +00:00
#ifndef NOEPOLL
if (pool->efd)
close(pool->efd);
#endif
memset(pool, 0, sizeof(*pool));
free(pool);
}
#ifndef NOEPOLL
struct eval *next_event(struct poolhd *pool, int *offs, int *type)
{
2024-05-04 16:42:19 +00:00
while (1) {
int i = *offs;
2024-07-25 12:06:27 +00:00
assert(i >= -1 && i < pool->max);
2023-06-03 19:52:10 +00:00
if (i < 0) {
2024-05-04 16:42:19 +00:00
i = (epoll_wait(pool->efd, pool->pevents, pool->max, -1) - 1);
if (i < 0) {
return 0;
}
pool->iters++;
2023-06-03 19:52:10 +00:00
}
2024-05-04 16:42:19 +00:00
struct eval *val = pool->pevents[i].data.ptr;
*offs = i - 1;
if (val->mod_iter == pool->iters) {
continue;
2024-05-04 14:55:48 +00:00
}
2024-05-04 16:42:19 +00:00
*type = pool->pevents[i].events;
return val;
2023-06-03 19:52:10 +00:00
}
}
int mod_etype(struct poolhd *pool, struct eval *val, int type)
2023-06-03 19:52:10 +00:00
{
2024-05-08 17:15:57 +00:00
assert(val->fd > 0);
2023-06-03 19:52:10 +00:00
struct epoll_event ev = {
2024-05-04 20:04:56 +00:00
.events = EPOLLRDHUP | type, .data = {val}
2023-06-03 19:52:10 +00:00
};
return epoll_ctl(pool->efd, EPOLL_CTL_MOD, val->fd, &ev);
2023-06-03 19:52:10 +00:00
}
#else
struct eval *next_event(struct poolhd *pool, int *offs, int *typel)
{
for (int i = *offs; ; i--) {
2024-05-08 17:15:57 +00:00
assert(i >= -1 && i < pool->max);
2023-06-03 19:52:10 +00:00
if (i < 0) {
if (poll(pool->pevents, pool->count, -1) <= 0) {
return 0;
}
i = pool->count - 1;
2024-05-04 14:55:48 +00:00
pool->iters++;
2023-06-03 19:52:10 +00:00
}
short type = pool->pevents[i].revents;
2024-05-04 16:42:19 +00:00
if (!type) {
continue;
}
struct eval *val = pool->links[i];
2024-05-08 17:15:57 +00:00
assert((i < pool->count) || (val->mod_iter == pool->iters));
2024-05-04 16:42:19 +00:00
if (val->mod_iter == pool->iters) {
2023-06-03 19:52:10 +00:00
continue;
2024-05-04 16:42:19 +00:00
}
2023-06-03 19:52:10 +00:00
pool->pevents[i].revents = 0;
*offs = i - 1;
*typel = type;
2024-05-04 16:42:19 +00:00
return val;
2023-06-03 19:52:10 +00:00
}
}
int mod_etype(struct poolhd *pool, struct eval *val, int type)
2023-06-03 19:52:10 +00:00
{
2024-05-08 17:15:57 +00:00
assert(val->index >= 0 && val->index < pool->count);
2024-05-09 23:30:17 +00:00
pool->pevents[val->index].events = POLLRDHUP | type;
2023-06-03 19:52:10 +00:00
return 0;
}
#endif