Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -1,7 +1,7 @@ CC = gcc -CFLAGS = -I. -std=gnu11 -Wall -W -pthread -O3 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE $(FILED_EXTRA_CFLAGS) +CFLAGS = -I. -Wall -W -pthread -O3 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE $(FILED_EXTRA_CFLAGS) LDFLAGS = -pthread $(FILED_EXTRA_LDFLAGS) LIBS = -lpthread $(FILED_EXTRA_LIBS) MIMETYPES = /etc/httpd/mime.types PREFIX = /usr/local Index: filed.c ================================================================== --- filed.c +++ filed.c @@ -609,20 +609,24 @@ #define filed_sockettimeout_thread_init() 0 #define filed_sockettimeout_init() 0 #define filed_sockettimeout_accept(x) /**/ #define filed_sockettimeout_processing_start(x) /**/ #define filed_sockettimeout_processing_end(x) /**/ -#define filed_sockettimeout_close(x) /**/ +#define filed_sockettimeout_close(x, y) /**/ #else time_t filed_sockettimeout_time; struct { time_t expiration_time; pthread_t thread_id; - int valid; + enum { + filed_sockettimeout_valid, + filed_sockettimeout_invalid, + } valid; } *filed_sockettimeout_sockstatus; long filed_sockettimeout_sockstatus_length; int filed_sockettimeout_devnull_fd; +pthread_mutex_t filed_sockettimeout_mutex = PTHREAD_MUTEX_INITIALIZER; static int filed_sockettimeout_sockfd_in_range(int sockfd) { if (sockfd < 3) { return(0); } @@ -632,62 +636,82 @@ } return(1); } -static void filed_sockettimeout_expire(int sockfd, int length) { +static void filed_sockettimeout_expire(int sockfd, int length, int lockheld) { time_t now, expire; - now = atomic_load(&filed_sockettimeout_time); + if (!lockheld) { + pthread_mutex_lock(&filed_sockettimeout_mutex); + } + + now = filed_sockettimeout_time; expire = now + length; - atomic_store(&filed_sockettimeout_sockstatus[sockfd].expiration_time, expire); + filed_sockettimeout_sockstatus[sockfd].expiration_time = expire; + + if (!lockheld) { + pthread_mutex_unlock(&filed_sockettimeout_mutex); + } return; } static void filed_sockettimeout_accept(int sockfd) { if (!filed_sockettimeout_sockfd_in_range(sockfd)) { return; } - filed_sockettimeout_expire(sockfd, 60); + pthread_mutex_lock(&filed_sockettimeout_mutex); - atomic_store(&filed_sockettimeout_sockstatus[sockfd].thread_id, pthread_self()); + filed_sockettimeout_expire(sockfd, 60, 1); - atomic_store(&filed_sockettimeout_sockstatus[sockfd].valid, true); + filed_sockettimeout_sockstatus[sockfd].thread_id = pthread_self(); + + filed_sockettimeout_sockstatus[sockfd].valid = filed_sockettimeout_valid; + + pthread_mutex_unlock(&filed_sockettimeout_mutex); return; } static void filed_sockettimeout_processing_start(int sockfd) { if (!filed_sockettimeout_sockfd_in_range(sockfd)) { return; } - filed_sockettimeout_expire(sockfd, 86400); + filed_sockettimeout_expire(sockfd, 86400, 0); return; } static void filed_sockettimeout_processing_end(int sockfd) { if (!filed_sockettimeout_sockfd_in_range(sockfd)) { return; } - filed_sockettimeout_expire(sockfd, 60); + filed_sockettimeout_expire(sockfd, 60, 0); return; } -static void filed_sockettimeout_close(int sockfd) { +static void filed_sockettimeout_close(int sockfd, int lockheld) { if (!filed_sockettimeout_sockfd_in_range(sockfd)) { return; } - atomic_store(&filed_sockettimeout_sockstatus[sockfd].valid, false); + if (!lockheld) { + pthread_mutex_lock(&filed_sockettimeout_mutex); + } + + filed_sockettimeout_sockstatus[sockfd].valid = filed_sockettimeout_invalid; + + if (!lockheld) { + pthread_mutex_unlock(&filed_sockettimeout_mutex); + } return; } static void *filed_sockettimeout_thread(void *arg) { @@ -702,36 +726,44 @@ for (count = 0; count < 10; count++) { sleep_time.tv_sec = 30; sleep_time.tv_nsec = 0; nanosleep(&sleep_time, NULL); + pthread_mutex_lock(&filed_sockettimeout_mutex); + now = time(NULL); - atomic_store(&filed_sockettimeout_time, now); + filed_sockettimeout_time = now; + + pthread_mutex_unlock(&filed_sockettimeout_mutex); } + + pthread_mutex_lock(&filed_sockettimeout_mutex); for (idx = 0; idx < filed_sockettimeout_sockstatus_length; idx++) { - valid = atomic_load(&filed_sockettimeout_sockstatus[idx].valid); + valid = filed_sockettimeout_sockstatus[idx].valid; - if (!valid) { + if (valid != filed_sockettimeout_valid) { continue; } - expiration_time = atomic_load(&filed_sockettimeout_sockstatus[idx].expiration_time); + expiration_time = filed_sockettimeout_sockstatus[idx].expiration_time; - thread_id = atomic_load(&filed_sockettimeout_sockstatus[idx].thread_id); + thread_id = filed_sockettimeout_sockstatus[idx].thread_id; if (expiration_time > now) { continue; } - filed_sockettimeout_close(idx); + filed_sockettimeout_close(idx, 1); dup2(filed_sockettimeout_devnull_fd, idx); pthread_kill(thread_id, SIGPIPE); } + + pthread_mutex_unlock(&filed_sockettimeout_mutex); } return(NULL); /* NOTREACH: We don't actually take any arguments */ @@ -759,11 +791,11 @@ if (filed_sockettimeout_sockstatus == NULL) { return(-1); } for (idx = 0; idx < maxfd; idx++) { - filed_sockettimeout_sockstatus[idx].valid = false; + filed_sockettimeout_sockstatus[idx].valid = filed_sockettimeout_invalid; } filed_sockettimeout_devnull_fd = open("/dev/null", O_RDWR); if (filed_sockettimeout_devnull_fd < 0) { return(-1); @@ -1175,11 +1207,11 @@ log->http_code = error_number; filed_log_entry(log); /* Close connection */ - filed_sockettimeout_close(fileno(fp)); + filed_sockettimeout_close(fileno(fp), 0); fclose(fp); return; } @@ -1200,11 +1232,11 @@ log->http_code = http_code; filed_log_entry(log); /* Close connection */ - filed_sockettimeout_close(fileno(fp)); + filed_sockettimeout_close(fileno(fp), 0); fclose(fp); return; @@ -1240,11 +1272,11 @@ date_current = filed_format_time(date_current_b, sizeof(date_current_b), time(NULL)); /* Open socket as ANSI I/O for ease of use */ fp = fdopen(fd, "w+b"); if (fp == NULL) { - filed_sockettimeout_close(fd); + filed_sockettimeout_close(fd, 0); close(fd); log->buffer[0] = '\0'; log->http_code = -1; @@ -1433,11 +1465,11 @@ filed_log_entry(log); close(fileinfo->fd); if (request->headers.connection != FILED_CONNECTION_KEEP_ALIVE) { - filed_sockettimeout_close(fd); + filed_sockettimeout_close(fd, 0); fclose(fp); return(FILED_CONNECTION_CLOSE); }