Mercurial > urweb
diff 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 |
line wrap: on
line diff
--- a/src/c/urweb.c Sun Mar 29 11:37:29 2009 -0400 +++ b/src/c/urweb.c Sun Mar 29 13:30:01 2009 -0400 @@ -208,7 +208,7 @@ } static void free_client(client *c) { - printf("Freeing client %d\n", c->id); + printf("Freeing client %u\n", c->id); c->mode = UNUSED; c->pass = -1; @@ -217,34 +217,6 @@ clients_free = c; } -extern int uw_timeout; - -void uw_prune_clients() { - client *c, *next, *prev = NULL; - time_t cutoff; - - cutoff = time(NULL) - uw_timeout; - - pthread_mutex_lock(&clients_mutex); - - for (c = clients_used; c; c = next) { - next = c->next; - pthread_mutex_lock(&c->lock); - if (c->last_contact < cutoff) { - if (prev) - prev->next = next; - else - clients_used = next; - free_client(c); - } - else - prev = c; - pthread_mutex_unlock(&c->lock); - } - - pthread_mutex_unlock(&clients_mutex); -} - static uw_Basis_channel new_channel(client *c) { uw_Basis_channel ch = {c->id, c->n_channels++}; return ch; @@ -322,7 +294,7 @@ char error_message[ERROR_BUF_LEN]; }; -extern int uw_inputs_len; +extern int uw_inputs_len, uw_timeout; uw_context uw_init(size_t outHeaders_len, size_t script_len, size_t page_len, size_t heap_len) { uw_context ctx = malloc(sizeof(struct uw_context)); @@ -1888,3 +1860,53 @@ return uw_db_rollback(ctx); } + + +// "Garbage collection" + +void uw_expunger(uw_context ctx, uw_Basis_client cli); + +static failure_kind uw_expunge(uw_context ctx, uw_Basis_client cli) { + int r = setjmp(ctx->jmp_buf); + + if (r == 0) + uw_expunger(ctx, cli); + + return r; +} + +void uw_prune_clients(uw_context ctx) { + client *c, *next, *prev = NULL; + time_t cutoff; + + cutoff = time(NULL) - uw_timeout; + + pthread_mutex_lock(&clients_mutex); + + for (c = clients_used; c; c = next) { + next = c->next; + pthread_mutex_lock(&c->lock); + if (c->last_contact < cutoff) { + failure_kind fk = UNLIMITED_RETRY; + if (prev) + prev->next = next; + else + clients_used = next; + while (fk == UNLIMITED_RETRY) { + uw_reset(ctx); + fk = uw_expunge(ctx, c->id); + if (fk == SUCCESS) { + free_client(c); + break; + } + } + if (fk != SUCCESS) + printf("Expunge blocked by error: %s\n", uw_error_message(ctx)); + } + else + prev = c; + pthread_mutex_unlock(&c->lock); + } + + pthread_mutex_unlock(&clients_mutex); +}