Mercurial > urweb
comparison src/c/urweb.c @ 683:9a2c18dab11d
Expunging non-nullable rows
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 29 Mar 2009 13:30:01 -0400 |
parents | 5bbb542243e8 |
children | f0224c7f12bb |
comparison
equal
deleted
inserted
replaced
682:5bbb542243e8 | 683:9a2c18dab11d |
---|---|
206 | 206 |
207 pthread_mutex_unlock(&c->lock); | 207 pthread_mutex_unlock(&c->lock); |
208 } | 208 } |
209 | 209 |
210 static void free_client(client *c) { | 210 static void free_client(client *c) { |
211 printf("Freeing client %d\n", c->id); | 211 printf("Freeing client %u\n", c->id); |
212 | 212 |
213 c->mode = UNUSED; | 213 c->mode = UNUSED; |
214 c->pass = -1; | 214 c->pass = -1; |
215 | 215 |
216 c->next = clients_free; | 216 c->next = clients_free; |
217 clients_free = c; | 217 clients_free = c; |
218 } | |
219 | |
220 extern int uw_timeout; | |
221 | |
222 void uw_prune_clients() { | |
223 client *c, *next, *prev = NULL; | |
224 time_t cutoff; | |
225 | |
226 cutoff = time(NULL) - uw_timeout; | |
227 | |
228 pthread_mutex_lock(&clients_mutex); | |
229 | |
230 for (c = clients_used; c; c = next) { | |
231 next = c->next; | |
232 pthread_mutex_lock(&c->lock); | |
233 if (c->last_contact < cutoff) { | |
234 if (prev) | |
235 prev->next = next; | |
236 else | |
237 clients_used = next; | |
238 free_client(c); | |
239 } | |
240 else | |
241 prev = c; | |
242 pthread_mutex_unlock(&c->lock); | |
243 } | |
244 | |
245 pthread_mutex_unlock(&clients_mutex); | |
246 } | 218 } |
247 | 219 |
248 static uw_Basis_channel new_channel(client *c) { | 220 static uw_Basis_channel new_channel(client *c) { |
249 uw_Basis_channel ch = {c->id, c->n_channels++}; | 221 uw_Basis_channel ch = {c->id, c->n_channels++}; |
250 return ch; | 222 return ch; |
320 client *client; | 292 client *client; |
321 | 293 |
322 char error_message[ERROR_BUF_LEN]; | 294 char error_message[ERROR_BUF_LEN]; |
323 }; | 295 }; |
324 | 296 |
325 extern int uw_inputs_len; | 297 extern int uw_inputs_len, uw_timeout; |
326 | 298 |
327 uw_context uw_init(size_t outHeaders_len, size_t script_len, size_t page_len, size_t heap_len) { | 299 uw_context uw_init(size_t outHeaders_len, size_t script_len, size_t page_len, size_t heap_len) { |
328 uw_context ctx = malloc(sizeof(struct uw_context)); | 300 uw_context ctx = malloc(sizeof(struct uw_context)); |
329 | 301 |
330 ctx->headers = ctx->headers_end = NULL; | 302 ctx->headers = ctx->headers_end = NULL; |
1886 if (ctx->client) | 1858 if (ctx->client) |
1887 pthread_mutex_unlock(&ctx->client->lock); | 1859 pthread_mutex_unlock(&ctx->client->lock); |
1888 | 1860 |
1889 return uw_db_rollback(ctx); | 1861 return uw_db_rollback(ctx); |
1890 } | 1862 } |
1863 | |
1864 | |
1865 // "Garbage collection" | |
1866 | |
1867 void uw_expunger(uw_context ctx, uw_Basis_client cli); | |
1868 | |
1869 static failure_kind uw_expunge(uw_context ctx, uw_Basis_client cli) { | |
1870 int r = setjmp(ctx->jmp_buf); | |
1871 | |
1872 if (r == 0) | |
1873 uw_expunger(ctx, cli); | |
1874 | |
1875 return r; | |
1876 } | |
1877 | |
1878 void uw_prune_clients(uw_context ctx) { | |
1879 client *c, *next, *prev = NULL; | |
1880 time_t cutoff; | |
1881 | |
1882 cutoff = time(NULL) - uw_timeout; | |
1883 | |
1884 pthread_mutex_lock(&clients_mutex); | |
1885 | |
1886 for (c = clients_used; c; c = next) { | |
1887 next = c->next; | |
1888 pthread_mutex_lock(&c->lock); | |
1889 if (c->last_contact < cutoff) { | |
1890 failure_kind fk = UNLIMITED_RETRY; | |
1891 if (prev) | |
1892 prev->next = next; | |
1893 else | |
1894 clients_used = next; | |
1895 while (fk == UNLIMITED_RETRY) { | |
1896 uw_reset(ctx); | |
1897 fk = uw_expunge(ctx, c->id); | |
1898 if (fk == SUCCESS) { | |
1899 free_client(c); | |
1900 break; | |
1901 } | |
1902 } | |
1903 if (fk != SUCCESS) | |
1904 printf("Expunge blocked by error: %s\n", uw_error_message(ctx)); | |
1905 } | |
1906 else | |
1907 prev = c; | |
1908 pthread_mutex_unlock(&c->lock); | |
1909 } | |
1910 | |
1911 pthread_mutex_unlock(&clients_mutex); | |
1912 } |