changeset 2282:19b233bb3176

Make cache flushes safe for transactions (not sure about LRU bump on read).
author Ziv Scully <ziv@mit.edu>
date Thu, 12 Nov 2015 09:47:20 -0500
parents 75cb60a7f6f1
children 4afaab523213
files src/c/urweb.c
diffstat 1 files changed, 48 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/c/urweb.c	Thu Nov 12 09:15:50 2015 -0500
+++ b/src/c/urweb.c	Thu Nov 12 09:47:20 2015 -0500
@@ -424,6 +424,12 @@
   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 @@
   // Sqlcache.
   int numRecording;
   int recordingOffset;
+  uw_Sqlcache_Inval *inval;
 
   int remoteSock;
 };
@@ -4661,7 +4668,7 @@
   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 @@
   // 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;
+}