diff options
author | Ziv Scully <ziv@mit.edu> | 2015-11-12 09:47:20 -0500 |
---|---|---|
committer | Ziv Scully <ziv@mit.edu> | 2015-11-12 09:47:20 -0500 |
commit | 7fff147bd1fad81381fb36396021c3acb33da44d (patch) | |
tree | 2cb41f2191567b0e29f0eb5cb387a017eaabd202 | |
parent | 011b7148c87f8b0d90abee2f454ef7689493e1f9 (diff) |
Make cache flushes safe for transactions (not sure about LRU bump on read).
-rw-r--r-- | src/c/urweb.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c index 71130cc7..050a06c9 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -424,6 +424,12 @@ typedef struct { void (*free)(void*); } global; +typedef struct uw_Sqlcache_Inval { + uw_Sqlcache_Cache *cache; + char **keys; + struct uw_Sqlcache_Inval *next; +} uw_Sqlcache_Inval; + struct uw_context { uw_app *app; int id; @@ -491,6 +497,7 @@ struct uw_context { // Sqlcache. int numRecording; int recordingOffset; + uw_Sqlcache_Inval *inval; int remoteSock; }; @@ -4661,7 +4668,7 @@ void uw_Sqlcache_store(uw_Sqlcache_Cache *cache, char **keys, uw_Sqlcache_Value entry->value->timeValid = timeNow; } -void uw_Sqlcache_flush(uw_Sqlcache_Cache *cache, char **keys) { +void uw_Sqlcache_flushCommitOne(uw_Sqlcache_Cache *cache, char **keys) { size_t numKeys = cache->numKeys; char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys); char *buf = key; @@ -4691,3 +4698,43 @@ void uw_Sqlcache_flush(uw_Sqlcache_Cache *cache, char **keys) { // All the keys were non-null and the relevant entry is present, so we delete it. uw_Sqlcache_delete(cache, entry); } + +void uw_Sqlcache_flushFree(void *data, int dontCare) { + uw_Sqlcache_Inval *inval = (uw_Sqlcache_Inval *)data; + while (inval) { + char** keys = inval->keys; + size_t numKeys = inval->cache->numKeys; + while (numKeys-- > 0) { + free(keys[numKeys]); + } + free(keys); + uw_Sqlcache_Inval *nextInval = inval->next; + free(inval); + inval = nextInval; + } +} + +void uw_Sqlcache_flushCommit(void *data) { + uw_Sqlcache_Inval *inval = (uw_Sqlcache_Inval *)data; + uw_Sqlcache_Inval *invalFirst = inval; + while (inval) { + uw_Sqlcache_Cache *cache = inval->cache; + char **keys = inval->keys; + uw_Sqlcache_flushCommitOne(cache, keys); + inval = inval->next; + } + uw_Sqlcache_flushFree(invalFirst, 0); +} + +void uw_Sqlcache_flush(uw_context ctx, uw_Sqlcache_Cache *cache, char **keys) { + uw_Sqlcache_Inval *inval = malloc(sizeof(uw_Sqlcache_Inval)); + inval->cache = cache; + inval->keys = keys; + inval->next = NULL; + if (ctx->inval) { + ctx->inval->next = inval; + } else { + uw_register_transactional(ctx, inval, uw_Sqlcache_flushCommit, NULL, uw_Sqlcache_flushFree); + } + ctx->inval = inval; +} |