summaryrefslogtreecommitdiff
path: root/ot_accesslist.c
diff options
context:
space:
mode:
authorerdgeist <>2009-07-17 18:00:26 +0000
committererdgeist <>2009-07-17 18:00:26 +0000
commitbb770a45a6a6b013d52d6e0a4b27fd630e365d30 (patch)
tree074274c297fb9b28efdbeb1f101d3783165be6fb /ot_accesslist.c
parent57f85fc7cccab846351dc36c8c25084793b4de0a (diff)
Make accesslists thread safe. Signal handler is working in its own thread now, waiting for a signal. All other threads ignore signals.
Diffstat (limited to 'ot_accesslist.c')
-rw-r--r--ot_accesslist.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/ot_accesslist.c b/ot_accesslist.c
index 65eceb7..cdf7731 100644
--- a/ot_accesslist.c
+++ b/ot_accesslist.c
@@ -4,6 +4,7 @@
4 $id$ */ 4 $id$ */
5 5
6/* System */ 6/* System */
7#include <pthread.h>
7#include <stdlib.h> 8#include <stdlib.h>
8#include <string.h> 9#include <string.h>
9#include <stdio.h> 10#include <stdio.h>
@@ -26,25 +27,18 @@
26 char *g_accesslist_filename; 27 char *g_accesslist_filename;
27static ot_hash *g_accesslist; 28static ot_hash *g_accesslist;
28static size_t g_accesslist_size; 29static size_t g_accesslist_size;
30static pthread_mutex_t g_accesslist_mutex;
29 31
30static int vector_compare_hash(const void *hash1, const void *hash2 ) { 32static int vector_compare_hash(const void *hash1, const void *hash2 ) {
31 return memcmp( hash1, hash2, OT_HASH_COMPARE_SIZE ); 33 return memcmp( hash1, hash2, OT_HASH_COMPARE_SIZE );
32} 34}
33 35
34void accesslist_deinit( void ) {
35 free( g_accesslist );
36 g_accesslist = 0;
37 g_accesslist_size = 0;
38}
39
40/* Read initial access list */ 36/* Read initial access list */
41static void accesslist_readfile( int sig ) { 37static void accesslist_readfile( void ) {
42 ot_hash *info_hash, *accesslist_new = NULL, *accesslist_old; 38 ot_hash *info_hash, *accesslist_new = NULL;
43 char *map, *map_end, *read_offs; 39 char *map, *map_end, *read_offs;
44 size_t maplen; 40 size_t maplen;
45 41
46 if( sig != SIGHUP ) return;
47
48 if( ( map = mmap_read( g_accesslist_filename, &maplen ) ) == NULL ) { 42 if( ( map = mmap_read( g_accesslist_filename, &maplen ) ) == NULL ) {
49 char *wd = getcwd( NULL, 0 ); 43 char *wd = getcwd( NULL, 0 );
50 fprintf( stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).\nPWD: %s\n", g_accesslist_filename, wd ); 44 fprintf( stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).\nPWD: %s\n", g_accesslist_filename, wd );
@@ -84,7 +78,7 @@ static void accesslist_readfile( int sig ) {
84 while( read_offs < map_end && *(read_offs++) != '\n' ); 78 while( read_offs < map_end && *(read_offs++) != '\n' );
85 } 79 }
86#ifdef _DEBUG 80#ifdef _DEBUG
87 fprintf( stderr, "Added %d info_hashes to accesslist\n", info_hash - accesslist_new ); 81 fprintf( stderr, "Added %zd info_hashes to accesslist\n", (size_t)(info_hash - accesslist_new) );
88#endif 82#endif
89 83
90 mmap_unmap( map, maplen); 84 mmap_unmap( map, maplen);
@@ -92,15 +86,20 @@ static void accesslist_readfile( int sig ) {
92 qsort( accesslist_new, info_hash - accesslist_new, sizeof( *info_hash ), vector_compare_hash ); 86 qsort( accesslist_new, info_hash - accesslist_new, sizeof( *info_hash ), vector_compare_hash );
93 87
94 /* Now exchange the accesslist vector in the least race condition prone way */ 88 /* Now exchange the accesslist vector in the least race condition prone way */
95 g_accesslist_size = 0; 89 pthread_mutex_lock(&g_accesslist_mutex);
96 accesslist_old = g_accesslist; 90 free( g_accesslist );
97 g_accesslist = accesslist_new; 91 g_accesslist = accesslist_new;
98 g_accesslist_size = info_hash - accesslist_new; 92 g_accesslist_size = info_hash - accesslist_new;
99 free( accesslist_old ); 93 pthread_mutex_unlock(&g_accesslist_mutex);
100} 94}
101 95
102int accesslist_hashisvalid( ot_hash hash ) { 96int accesslist_hashisvalid( ot_hash hash ) {
103 void *exactmatch = bsearch( hash, g_accesslist, g_accesslist_size, OT_HASH_COMPARE_SIZE, vector_compare_hash ); 97 void *exactmatch;
98
99 /* Lock should hardly ever be contended */
100 pthread_mutex_lock(&g_accesslist_mutex);
101 exactmatch = bsearch( hash, g_accesslist, g_accesslist_size, OT_HASH_COMPARE_SIZE, vector_compare_hash );
102 pthread_mutex_unlock(&g_accesslist_mutex);
104 103
105#ifdef WANT_ACCESSLIST_BLACK 104#ifdef WANT_ACCESSLIST_BLACK
106 return exactmatch == NULL; 105 return exactmatch == NULL;
@@ -109,12 +108,38 @@ int accesslist_hashisvalid( ot_hash hash ) {
109#endif 108#endif
110} 109}
111 110
112void accesslist_init( ) { 111static void * accesslist_worker( void * args ) {
113 /* Passing "0" since read_blacklist_file also is SIGHUP handler */ 112 int sig;
114 if( g_accesslist_filename ) { 113 sigset_t signal_mask;
115 accesslist_readfile( SIGHUP ); 114
116 signal( SIGHUP, accesslist_readfile ); 115 sigemptyset(&signal_mask);
116 sigaddset(&signal_mask, SIGHUP);
117
118 (void)args;
119
120 while( 1 ) {
121
122 /* Initial attempt to read accesslist */
123 accesslist_readfile( );
124
125 /* Wait for signals */
126 while( sigwait (&signal_mask, &sig) != 0 && sig != SIGHUP );
117 } 127 }
128 return NULL;
129}
130
131static pthread_t thread_id;
132void accesslist_init( ) {
133 pthread_mutex_init(&g_accesslist_mutex, NULL);
134 pthread_create( &thread_id, NULL, accesslist_worker, NULL );
135}
136
137void accesslist_deinit( void ) {
138 pthread_cancel( thread_id );
139 pthread_mutex_destroy(&g_accesslist_mutex);
140 free( g_accesslist );
141 g_accesslist = 0;
142 g_accesslist_size = 0;
118} 143}
119#endif 144#endif
120 145