#include "util.h"
#include <uv.h>
+#include <algorithm>
namespace netpoll {
#define NETPOLL_MAXFDS 1024
return ev;
}
-static int search(SOCKET fd) {
- int l = 0, r = nfds;
- while (l != r) {
- int m = (l+r)/2;
- if (fds[m].fd < fd)
- l = m+1;
- else if (fd < fds[m].fd)
- r = m;
- else
- l = r = m;
+static int 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;
+ if (found == add)
+ abortf("netpoll::search: duplicate or missing socket\n");
+ if (add) {
+ if (nfds == NETPOLL_MAXFDS)
+ abortf("netpoll::add: NETPOLL_MAXFDS limit\n");
+ memmove(it+1, it, sizeof(fds[0])*(fds+nfds-it));
+ nfds++;
+ *it = net_pollfd{};
+ it->fd = fd;
}
- return l;
+ return it - fds;
}
-#define IS_FOUND(i, f) ((i) < nfds && fds[i].fd == (f))
void add(SOCKET fd, int type, void *assoc)
{
- if (fd == INVALID_SOCKET)
- abortf("netpoll::add: INVALID_SOCKET\n");
- int i = search(fd);
- if (IS_FOUND(i, fd))
- abortf("netpoll::add: socket already added\n");
- if (nfds == NETPOLL_MAXFDS)
- abortf("netpoll::add: NETPOLL_MAXFDS limit\n");
- memmove(fds+i+1, fds+i, sizeof(fds[0])*(nfds-i));
- nfds++;
- fds[i] = (struct net_pollfd){ .assoc = assoc, .fd = fd, .type = type };
+ int i = search(fd, true);
+ fds[i].assoc = assoc;
+ fds[i].type = type;
add_impl(i);
}
void del_and_close(SOCKET fd)
{
- if (fd == INVALID_SOCKET)
- abortf("netpoll::del_and_close: INVALID_SOCKET\n");
- int i = search(fd);
- if (!IS_FOUND(i, fd))
- abortf("netpoll::del_and_close: socket not added\n");
+ int i = search(fd, false);
reg_impl(i, 0);
del_impl(i);
memmove(fds+i, fds+i+1, sizeof(fds[0])*(nfds-(i+1)));
}
void reg(SOCKET fd, int ev)
{
- if (fd == INVALID_SOCKET)
- abortf("netpoll::reg: INVALID_SOCKET\n");
- int i = search(fd);
- if (!IS_FOUND(i, fd))
- abortf("netpoll::reg: socket not added\n");
- reg_impl(i, ev);
+ reg_impl(search(fd, false), ev);
}
void change_type(SOCKET fd, int type)
{
- if (fd == INVALID_SOCKET)
- abortf("netpoll::change_type: INVALID_SOCKET\n");
- int i = search(fd);
- if (!IS_FOUND(i, fd))
- abortf("netpoll::change_type: socket not added\n");
- fds[i].type = type;
+ fds[search(fd, false)].type = type;
}
}