Mercurial > urweb
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) { |