comparison src/c/urweb.c @ 1707:c05e2e4bdde7

Refactor to avoid dependence on recursive mutexes
author Adam Chlipala <adam@chlipala.net>
date Sun, 08 Apr 2012 16:24:16 -0400
parents 6f2f74cc4ead
children e263dab7b579
comparison
equal deleted inserted replaced
1706:0152f65ced6a 1707:c05e2e4bdde7
157 // Persistent client state 157 // Persistent client state
158 158
159 static client **clients, *clients_free, *clients_used; 159 static client **clients, *clients_free, *clients_used;
160 static unsigned n_clients; 160 static unsigned n_clients;
161 161
162 static pthread_mutex_t clients_mutex = 162 static pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
163 #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
164 PTHREAD_RECURSIVE_MUTEX_INITIALIZER
165 #else
166 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
167 #endif
168 ;
169 size_t uw_messages_max = SIZE_MAX; 163 size_t uw_messages_max = SIZE_MAX;
170 size_t uw_clients_max = SIZE_MAX; 164 size_t uw_clients_max = SIZE_MAX;
171 165
172 void *uw_init_client_data(); 166 void *uw_init_client_data();
173 void uw_free_client_data(void *); 167 void uw_free_client_data(void *);
228 --c->refcount; 222 --c->refcount;
229 pthread_mutex_unlock(&c->lock); 223 pthread_mutex_unlock(&c->lock);
230 } 224 }
231 225
232 static const char begin_msgs[] = "Content-type: text/plain\r\n\r\n"; 226 static const char begin_msgs[] = "Content-type: text/plain\r\n\r\n";
227 static pthread_t pruning_thread;
228 static int pruning_thread_initialized = 0;
233 229
234 static client *find_client(unsigned id) { 230 static client *find_client(unsigned id) {
235 client *c; 231 client *c;
236 232
237 pthread_mutex_lock(&clients_mutex); 233 if (!pruning_thread_initialized || !pthread_equal(pruning_thread, pthread_self())) pthread_mutex_lock(&clients_mutex);
238 234
239 if (id >= n_clients) { 235 if (id >= n_clients) {
240 pthread_mutex_unlock(&clients_mutex); 236 if (!pruning_thread_initialized || !pthread_equal(pruning_thread, pthread_self())) pthread_mutex_unlock(&clients_mutex);
241 return NULL; 237 return NULL;
242 } 238 }
243 239
244 c = clients[id]; 240 c = clients[id];
245 241
246 pthread_mutex_unlock(&clients_mutex); 242 if (!pruning_thread_initialized || !pthread_equal(pruning_thread, pthread_self())) pthread_mutex_unlock(&clients_mutex);
247 return c; 243 return c;
248 } 244 }
249 245
250 static char *on_success = "HTTP/1.1 200 OK\r\n"; 246 static char *on_success = "HTTP/1.1 200 OK\r\n";
251 static char *on_redirect = "HTTP/1.1 303 See Other\r\n"; 247 static char *on_redirect = "HTTP/1.1 303 See Other\r\n";
3289 time_t cutoff; 3285 time_t cutoff;
3290 3286
3291 cutoff = time(NULL) - ctx->app->timeout; 3287 cutoff = time(NULL) - ctx->app->timeout;
3292 3288
3293 pthread_mutex_lock(&clients_mutex); 3289 pthread_mutex_lock(&clients_mutex);
3290 pruning_thread = pthread_self();
3291 pruning_thread_initialized = 1;
3294 3292
3295 for (c = clients_used; c; c = next) { 3293 for (c = clients_used; c; c = next) {
3296 next = c->next; 3294 next = c->next;
3297 pthread_mutex_lock(&c->lock); 3295 pthread_mutex_lock(&c->lock);
3298 if (c->last_contact < cutoff && c->refcount == 0) { 3296 if (c->last_contact < cutoff && c->refcount == 0) {