summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ziv Scully <ziv@mit.edu>2015-11-12 09:47:20 -0500
committerGravatar Ziv Scully <ziv@mit.edu>2015-11-12 09:47:20 -0500
commit7fff147bd1fad81381fb36396021c3acb33da44d (patch)
tree2cb41f2191567b0e29f0eb5cb387a017eaabd202
parent011b7148c87f8b0d90abee2f454ef7689493e1f9 (diff)
Make cache flushes safe for transactions (not sure about LRU bump on read).
-rw-r--r--src/c/urweb.c49
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;
+}