#include "util.h"
#include <algorithm>
+#include <vector>
namespace netpoll {
struct pollfd {
int type;
};
#define NETPOLL_MAXFDS 1024
-static struct pollfd fds[NETPOLL_MAXFDS] = {};
-static int nfds = 0;
+static std::vector<pollfd*> fds;
#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
struct polldata {
};
static polldata *uvpoll[NETPOLL_MAXFDS] = {};
static uv_loop_t *uvloop = 0;
-static int lastptr = 0;
+static size_t lastptr = 0;
namespace uvalloc {
static polldata uvpollbuf[NETPOLL_MAXFDS] = {};
static polldata *freelist = 0;
}
void begin(void)
{
- for (int i = 0; i < nfds; i++) {
+ for (size_t i = 0; i < fds.size(); i++) {
if (uvpoll[i]->dead == 0) {
uv_poll_start(&uvpoll[i]->uv, uvpoll[i]->events, cb);
uvpoll[i]->revents = 0;
}
bool get(event &out)
{
- while (lastptr != nfds && !uvpoll[lastptr]->revents) {
+ while (lastptr != fds.size() && !uvpoll[lastptr]->revents) {
lastptr++;
}
- if (lastptr == nfds)
+ if (lastptr == fds.size())
return false;
- pollfd &pfd = fds[lastptr];
- out.assoc = pfd.assoc;
- out.fd = pfd.fd;
- out.type = pfd.type;
+ pollfd *pfd = fds[lastptr];
+ out.assoc = pfd->assoc;
+ out.fd = pfd->fd;
+ out.type = pfd->type;
out.revents = uvpoll[lastptr]->revents;
lastptr++;
return true;
}
-static int search(SOCKET fd, bool add) {
+static size_t search(SOCKET fd, bool add) {
if (fd == INVALID_SOCKET)
abortf("netpoll::search: INVALID_SOCKET\n");
- auto it = std::partition_point(fds, fds+nfds, [fd](const auto &p){ return p.fd < fd; });
- bool found = it != fds+nfds && it->fd == fd;
+ auto it = std::partition_point(fds.begin(), fds.end(), [fd](const auto &p){ return p->fd < fd; });
+ bool found = it != fds.end() && (*it)->fd == fd;
if (found == add)
abortf("netpoll::search: duplicate or missing socket\n");
if (add) {
- if (nfds == NETPOLL_MAXFDS)
+ if (fds.size() == NETPOLL_MAXFDS)
abortf("netpoll::add: NETPOLL_MAXFDS limit\n");
- memmove(it+1, it, sizeof(fds[0])*(fds+nfds-it));
- nfds++;
- *it = pollfd{};
- it->fd = fd;
+ it = fds.insert(it, new pollfd());
+ (*it)->fd = fd;
}
- return it - fds;
+ return it - fds.begin();
}
void add(SOCKET fd, int type, void *assoc)
{
- int i = search(fd, true);
- fds[i].assoc = assoc;
- fds[i].type = type;
+ size_t i = search(fd, true);
+ fds[i]->assoc = assoc;
+ fds[i]->type = type;
struct polldata *poll = uvalloc::get();
- memmove(uvpoll+i+1, uvpoll+i, sizeof(uvpoll[0])*(nfds-1-i));
+ memmove(uvpoll+i+1, uvpoll+i, sizeof(uvpoll[0])*(fds.size()-1-i));
uvpoll[i] = poll;
poll->events = 0;
poll->revents = 0;
- poll->fd = fds[i].fd;
+ poll->fd = fds[i]->fd;
poll->dead = 0;
- uv_poll_init_socket(uvloop, &poll->uv, fds[i].fd);
+ uv_poll_init_socket(uvloop, &poll->uv, fds[i]->fd);
if (lastptr >= i)
lastptr++;
}
void del_and_close(SOCKET fd)
{
- int i = search(fd, false);
+ size_t i = search(fd, false);
uvpoll[i]->events = 0;
struct polldata *poll = uvpoll[i];
- memmove(uvpoll+i, uvpoll+i+1, sizeof(uvpoll[0])*(nfds-(i+1)));
+ memmove(uvpoll+i, uvpoll+i+1, sizeof(uvpoll[0])*(fds.size()-(i+1)));
uv_close((uv_handle_t *)&poll->uv, [](uv_handle_t *handle){
struct polldata *p = container_of(handle, struct polldata, uv);
closesocket(p->fd);
});
if (lastptr > i)
lastptr--;
- memmove(fds+i, fds+i+1, sizeof(fds[0])*(nfds-(i+1)));
- nfds--;
+
+ delete fds[i];
+ fds.erase(fds.begin()+i);
}
void reg(SOCKET fd, int ev)
{
}
void change_type(SOCKET fd, int type)
{
- fds[search(fd, false)].type = type;
+ fds[search(fd, false)]->type = type;
}
}