Rewrote connection list code
This commit is contained in:
@@ -49,8 +49,9 @@ static struct sockaddr_un addr;
|
|||||||
/* We want to be able to handle a signal at any time, so some global variables
|
/* We want to be able to handle a signal at any time, so some global variables
|
||||||
* are needed. */
|
* are needed. */
|
||||||
static const int signals[] = {
|
static const int signals[] = {
|
||||||
SIGPIPE, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
|
SIGPIPE, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS,
|
||||||
SIGKILL, SIGSEGV, SIGTERM, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ,
|
SIGFPE, SIGKILL, SIGSEGV, SIGTERM, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
|
||||||
|
SIGXFSZ,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void exitClean(int signal) {
|
static void exitClean(int signal) {
|
||||||
@@ -196,6 +197,7 @@ int main(int argc, char **argv) {
|
|||||||
if (pending[j] < pending[lowestproc])
|
if (pending[j] < pending[lowestproc])
|
||||||
lowestproc = j;
|
lowestproc = j;
|
||||||
sendFd(fd, runners[lowestproc].fd, &i, sizeof i);
|
sendFd(fd, runners[lowestproc].fd, &i, sizeof i);
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
172
src/runner.c
172
src/runner.c
@@ -31,19 +31,39 @@
|
|||||||
#include <swebs/sitefile.h>
|
#include <swebs/sitefile.h>
|
||||||
#include <swebs/connections.h>
|
#include <swebs/connections.h>
|
||||||
|
|
||||||
void runServer(int connfd, Sitefile *site, volatile int *pending, int id) {
|
typedef struct {
|
||||||
int allocConns = 100;
|
|
||||||
struct pollfd *fds;
|
struct pollfd *fds;
|
||||||
Connection *connections;
|
Connection *conns;
|
||||||
int connCount;
|
int len;
|
||||||
|
int alloc;
|
||||||
|
} ConnList;
|
||||||
|
|
||||||
|
static int createConnList(ConnList *list);
|
||||||
|
static int addConnList(ConnList *list, struct pollfd *fd, Connection *conn);
|
||||||
|
static void removeConnList(ConnList *list, int ind);
|
||||||
|
static void pollConnList(ConnList *list);
|
||||||
|
static void freeConnList(ConnList *list);
|
||||||
|
|
||||||
|
void runServer(int connfd, Sitefile *site, volatile int *pending, int id) {
|
||||||
Context **contexts;
|
Context **contexts;
|
||||||
int i;
|
int i;
|
||||||
|
ConnList conns;
|
||||||
|
|
||||||
connCount = 1;
|
if (createConnList(&conns))
|
||||||
fds = xmalloc(allocConns * sizeof *fds);
|
return;
|
||||||
connections = xmalloc(allocConns * sizeof *connections);
|
|
||||||
fds[0].fd = connfd;
|
{
|
||||||
fds[0].events = POLLIN;
|
struct pollfd newfd;
|
||||||
|
Connection newconn;
|
||||||
|
|
||||||
|
newfd.fd = connfd;
|
||||||
|
newfd.events = POLLIN;
|
||||||
|
|
||||||
|
if (addConnList(&conns, &newfd, &newconn)) {
|
||||||
|
freeConnList(&conns);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* connections are 1 indexed because fds[0] is the notify fd. I hate
|
/* connections are 1 indexed because fds[0] is the notify fd. I hate
|
||||||
* that poll() forces us to do these hacks. */
|
* that poll() forces us to do these hacks. */
|
||||||
|
|
||||||
@@ -86,86 +106,106 @@ void runServer(int connfd, Sitefile *site, volatile int *pending, int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
poll(fds, connCount, -1);
|
pollConnList(&conns);
|
||||||
|
|
||||||
createFormatLog("poll() finished with %d connections", connCount);
|
createFormatLog("poll() finished with %d connections",
|
||||||
|
conns.len);
|
||||||
|
|
||||||
for (i = 1; i < connCount; i++) {
|
for (i = 1; i < conns.len; i++) {
|
||||||
if (fds[i].revents & POLLIN) {
|
if (conns.fds[i].revents & POLLIN) {
|
||||||
createFormatLog("Connection %d has data", i);
|
createFormatLog("Connection %d has data", i);
|
||||||
if (updateConnection(connections + i, site))
|
if (updateConnection(conns.conns + i, site)) {
|
||||||
goto remove;
|
removeConnList(&conns, i);
|
||||||
}
|
--i;
|
||||||
continue;
|
}
|
||||||
remove:
|
|
||||||
{
|
|
||||||
int remove, replace;
|
|
||||||
remove = i;
|
|
||||||
replace = connCount - 1;
|
|
||||||
freeConnection(connections + remove);
|
|
||||||
|
|
||||||
memcpy(fds + remove, fds + replace,
|
|
||||||
sizeof(struct pollfd));
|
|
||||||
memcpy(connections + remove,
|
|
||||||
connections + replace,
|
|
||||||
sizeof(struct pollfd));
|
|
||||||
|
|
||||||
--pending[id];
|
|
||||||
|
|
||||||
--i;
|
|
||||||
--connCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[0].revents & POLLIN) {
|
if (conns.fds[0].revents & POLLIN) {
|
||||||
Stream *newstream;
|
Stream *newstream;
|
||||||
int newfd;
|
Connection newconn;
|
||||||
int portind;
|
int portind;
|
||||||
|
struct pollfd newfd;
|
||||||
|
|
||||||
createLog("Main fd has data");
|
createLog("Main fd has data");
|
||||||
newfd = recvFd(connfd, &portind, sizeof portind);
|
newfd.fd = recvFd(connfd, &portind, sizeof portind);
|
||||||
if (newfd < 0) {
|
if (newfd.fd < 0) {
|
||||||
createLog("Message received that included an invalid fd, quitting");
|
createLog("Message received that included an invalid fd, quitting");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
newfd.events = POLLIN;
|
||||||
|
|
||||||
newstream = createStream(contexts[portind], O_NONBLOCK, newfd);
|
newstream = createStream(contexts[portind],
|
||||||
|
O_NONBLOCK, newfd.fd);
|
||||||
if (newstream == NULL) {
|
if (newstream == NULL) {
|
||||||
createLog(
|
createLog(
|
||||||
"Stream couldn't be created from file descriptor");
|
"Stream couldn't be created from file descriptor");
|
||||||
shutdown(newfd, SHUT_RDWR);
|
shutdown(newfd.fd, SHUT_RDWR);
|
||||||
close(newfd);
|
close(newfd.fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connCount >= allocConns) {
|
if (newConnection(newstream, &newconn, portind)) {
|
||||||
struct pollfd *newfds;
|
|
||||||
Connection *newconns;
|
|
||||||
allocConns *= 2;
|
|
||||||
newfds = realloc(fds,
|
|
||||||
sizeof(struct pollfd) * allocConns);
|
|
||||||
if (newfds == NULL) {
|
|
||||||
allocConns /= 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
fds = newfds;
|
|
||||||
|
|
||||||
newconns = realloc(connections,
|
|
||||||
sizeof(Connection) * allocConns);
|
|
||||||
if (newconns == NULL) {
|
|
||||||
allocConns /= 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
connections = newconns;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newConnection(newstream, connections + connCount, portind)) {
|
|
||||||
createLog("Couldn't initialize connection from stream");
|
createLog("Couldn't initialize connection from stream");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fds[connCount].fd = newfd;
|
|
||||||
fds[connCount].events = POLLIN;
|
if (addConnList(&conns, &newfd, &newconn)) {
|
||||||
connCount++;
|
freeConnection(&newconn);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pending[id]++;
|
pending[id]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int createConnList(ConnList *list) {
|
||||||
|
list->alloc = 100;
|
||||||
|
list->fds = xmalloc(list->alloc * sizeof *list->fds);
|
||||||
|
list->conns = xmalloc(list->alloc * sizeof *list->conns);
|
||||||
|
list->len = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int addConnList(ConnList *list, struct pollfd *fd, Connection *conn) {
|
||||||
|
if (list->len >= list->alloc) {
|
||||||
|
int newalloc;
|
||||||
|
struct pollfd *newfds;
|
||||||
|
Connection *newconns;
|
||||||
|
newalloc = list->alloc * 2;
|
||||||
|
newfds = realloc(list->fds, newalloc * sizeof *list->fds);
|
||||||
|
if (newfds == NULL)
|
||||||
|
return 1;
|
||||||
|
newconns = realloc(list->conns, newalloc * sizeof *list->conns);
|
||||||
|
if (newconns == NULL)
|
||||||
|
return 1;
|
||||||
|
list->alloc = newalloc;
|
||||||
|
list->fds = newfds;
|
||||||
|
list->conns = newconns;
|
||||||
|
}
|
||||||
|
memcpy(list->fds + list->len, fd, sizeof *fd);
|
||||||
|
memcpy(list->conns + list->len, conn, sizeof *conn);
|
||||||
|
++list->len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeConnList(ConnList *list, int ind) {
|
||||||
|
const int replace = list->len - 1;
|
||||||
|
|
||||||
|
memcpy(list->fds + ind, list->fds + replace, sizeof *list->fds);
|
||||||
|
memcpy(list->conns + ind, list->conns + replace, sizeof *list->conns);
|
||||||
|
|
||||||
|
--list->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pollConnList(ConnList *list) {
|
||||||
|
poll(list->fds, list->len, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeConnList(ConnList *list) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < list->len; ++i)
|
||||||
|
freeConnection(list->conns + i);
|
||||||
|
free(list->fds);
|
||||||
|
free(list->conns);
|
||||||
|
}
|
||||||
|
|||||||
@@ -486,8 +486,6 @@ void freeSitefile(Sitefile *site) {
|
|||||||
for (i = 0; i < site->size; ++i) {
|
for (i = 0; i < site->size; ++i) {
|
||||||
regfree(&site->content[i].path);
|
regfree(&site->content[i].path);
|
||||||
regfree(&site->content[i].host);
|
regfree(&site->content[i].host);
|
||||||
/* This doesn't break because free(NULL) is harmless. */
|
|
||||||
|
|
||||||
free(site->content[i].arg);
|
free(site->content[i].arg);
|
||||||
free(site->content[i].ports);
|
free(site->content[i].ports);
|
||||||
free(site->content[i].contenttype);
|
free(site->content[i].contenttype);
|
||||||
|
|||||||
Reference in New Issue
Block a user