aboutsummaryrefslogtreecommitdiffstats
path: root/prototypes/connections/store-tree.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-26 22:56:32 +0100
committereunhhu <[email protected]>2026-09-26 22:56:32 +0100
commit42021a500d19dbe091075338d1a621498a81f167 (patch)
treeee3e2df5f0d1ba20ef5d681bf67a148d8c896b03 /prototypes/connections/store-tree.c
parentd2adae5deacc1545cd5dbdfcc5b80697c91dac09 (diff)
downloadpure-42021a500d19dbe091075338d1a621498a81f167.tar.gz
pure-42021a500d19dbe091075338d1a621498a81f167.zip
Snapshot an app's saved states for readers on other threads
Right after a save, pure_app_snapshot makes a read-only snapshot of the saved states: numbers are copied, text states are frozen drafts that share the store mapping (pure_draft_freeze, no copy), and lists are copies of their item pointers that share the items. An unchanged list shares the last snapshot's copy. pure_app_read binds a reader app on another thread to a snapshot so the existing view functions read it. A shared item never changes again: a list stamps each item with its share count, copies a shared item it changes, and retires shared items it lets go instead of freeing them. Snapshots form a chain that goes oldest first, and items retired while a snapshot was the newest go with it. References are atomic and may be released on any thread. test-module checks that each snapshot equals the app, that kept snapshots stay as made through changes, removals, a module switch, the app stopping and the store closing, that a failed save's snapshot equals the one before, and that two threads read the newest snapshots while the app goes on (also under ASan, UBSan and LeakSanitizer).
Diffstat (limited to 'prototypes/connections/store-tree.c')
-rw-r--r--prototypes/connections/store-tree.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/prototypes/connections/store-tree.c b/prototypes/connections/store-tree.c
index 45d470e..322a163 100644
--- a/prototypes/connections/store-tree.c
+++ b/prototypes/connections/store-tree.c
@@ -1288,6 +1288,19 @@ PureDraft *pure_draft_new(void) {
return calloc(1, sizeof(PureDraft)); /* no path: nothing mapped, nothing to commit */
}
+PureDraft *pure_draft_freeze(const PureDraft *draft) {
+ if (!draft->tree.shared || (draft->root.ref & MEMORY_BIT)) return NULL;
+ PureDraft *frozen = calloc(1, sizeof(*frozen));
+ if (!frozen) return NULL;
+ Mapping *mapping = draft->tree.shared;
+ __atomic_add_fetch(&mapping->refs, 1, __ATOMIC_RELAXED);
+ *frozen = (PureDraft){.tree = {.map = mapping->map, .end = mapping->end, .shared = mapping},
+ .device = draft->device, .inode = draft->inode, .root = draft->root,
+ .revision = draft->revision};
+ memcpy(frozen->key, draft->key, sizeof(frozen->key));
+ return frozen;
+}
+
void pure_draft_close(PureDraft *draft) {
if (!draft) return;
release_tree(&draft->tree);