mirror of
https://github.com/sigmasternchen/CFloor
synced 2025-03-15 04:18:55 +00:00
restructured signal management to avoid multible threads in the same critical section
This commit is contained in:
parent
0dcb33fe68
commit
b39fb7bcd8
4 changed files with 40 additions and 17 deletions
|
@ -7,6 +7,10 @@
|
|||
#include <assert.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "logging.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -186,6 +190,9 @@ void vlogging(loglevel_t loglevel, const char* format, va_list argptr) {
|
|||
sem_wait(&(logger[i].write_sem));
|
||||
|
||||
fprintf(logger[i].file, "%s %s ", timestamp, loglevelString);
|
||||
#ifdef DEBUG
|
||||
fprintf(logger[i].file, "[%ld] ", pthread_self());
|
||||
#endif
|
||||
vfprintf(logger[i].file, format, local);
|
||||
fprintf(logger[i].file, "\n");
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ linkedList_t connectionList;
|
|||
|
||||
linkedList_t connectionsToFree;
|
||||
void cleanup() {
|
||||
signal_block_all();
|
||||
|
||||
link_t* link = linked_first(&connectionList);
|
||||
|
||||
int length = 0;
|
||||
|
@ -629,8 +627,6 @@ void* responseThread(void* data) {
|
|||
void* requestThread(void* data) {
|
||||
struct connection* connection = (struct connection*) data;
|
||||
|
||||
signal_block_all();
|
||||
|
||||
struct handler handler = networkingConfig.getHandler(connection->metaData, headers_get(&(connection->headers), "Host"), connection->bind);
|
||||
|
||||
if (handler.handler == NULL) {
|
||||
|
@ -692,7 +688,7 @@ void startRequestHandler(struct connection* connection) {
|
|||
|
||||
pthread_t dataThreadId;
|
||||
|
||||
void dataHandler(int signo) {
|
||||
void dataHandler() {
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
debug("networking: data handler got called.");
|
||||
|
@ -868,6 +864,7 @@ void dataHandler(int signo) {
|
|||
// if the connection ends (tmp == 0)
|
||||
// the connection has to be dropped to free resources before the timeout
|
||||
if (dropConnection) {
|
||||
connection->currentHeaderLength = 0;
|
||||
if (connection->currentHeader != NULL)
|
||||
free(connection->currentHeader);
|
||||
connection->currentHeader = NULL;
|
||||
|
@ -886,19 +883,17 @@ void dataHandler(int signo) {
|
|||
}
|
||||
}
|
||||
void* dataThread(void* ignore) {
|
||||
signal_block_all();
|
||||
signal_allow(SIGIO);
|
||||
|
||||
signal_setup(SIGIO, &dataHandler);
|
||||
|
||||
while(true) {
|
||||
sleep(0xffff);
|
||||
if (signal_wait(SIGIO) != 0) {
|
||||
error("networking: data thread: sigwait: %s", strerror(errno));
|
||||
debug("networking: data thread: waiting 1s");
|
||||
sleep(1);
|
||||
}
|
||||
dataHandler();
|
||||
}
|
||||
}
|
||||
|
||||
void* listenThread(void* _bind) {
|
||||
signal_block_all();
|
||||
|
||||
struct bind* bindObj = (struct bind*) _bind;
|
||||
|
||||
info("networking: Starting to listen on %s:%s", bindObj->address, bindObj->port);
|
||||
|
@ -1127,13 +1122,27 @@ void* listenThread(void* _bind) {
|
|||
}
|
||||
}
|
||||
|
||||
void cleanupThread() {
|
||||
while(true) {
|
||||
if (signal_wait(SIGALRM) != 0) {
|
||||
error("networking: clean up thread: sigwait: %s", strerror(errno));
|
||||
debug("networking: clean up thread: waiting 1s");
|
||||
sleep(1);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
void networking_init(struct networkingConfig _networkingConfig) {
|
||||
networkingConfig = _networkingConfig;
|
||||
|
||||
connectionList = linked_create();
|
||||
connectionsToFree = linked_create();
|
||||
|
||||
timer_t timer = timer_createThreadTimer(&cleanup);
|
||||
signal_block(SIGIO);
|
||||
signal_block(SIGALRM);
|
||||
|
||||
timer_t timer = timer_createSignalTimer(SIGALRM);
|
||||
if (timer == NULL) {
|
||||
critical("networking: Couldn't create cleaup timer.");
|
||||
return;
|
||||
|
@ -1148,9 +1157,6 @@ void networking_init(struct networkingConfig _networkingConfig) {
|
|||
return;
|
||||
}
|
||||
|
||||
signal_block(SIGIO);
|
||||
signal_block(SIGALRM);
|
||||
|
||||
for(int i = 0; i < networkingConfig.binds.number; i++) {
|
||||
struct bind* bind = &(networkingConfig.binds.binds[i]);
|
||||
if (pthread_create(&(bind->_private.threadId), NULL, &listenThread, bind) != 0) {
|
||||
|
|
|
@ -39,6 +39,15 @@ int signal_allow(int signo) {
|
|||
return pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
int signal_wait(int signo) {
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, signo);
|
||||
|
||||
int _;
|
||||
return sigwait(&mask, &_);
|
||||
}
|
||||
|
||||
static void timerHandler(union sigval target) {
|
||||
((void (*)(void))(target.sival_ptr))();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ int signal_block_all();
|
|||
int signal_allow_all();
|
||||
int signal_block(int signo);
|
||||
int signal_allow(int signo);
|
||||
int signal_wait(int signo);
|
||||
|
||||
timer_t timer_createThreadTimer(void (*handler)());
|
||||
timer_t timer_createSignalTimer(int signo);
|
||||
|
|
Loading…
Reference in a new issue