ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
provsql_mmap.h
Go to the documentation of this file.
1/**
2 * @file provsql_mmap.h
3 * @brief Background worker and IPC primitives for mmap-backed circuit storage.
4 *
5 * ProvSQL persists the provenance circuit in memory-mapped files so that
6 * data survives transaction boundaries and is shared across backend
7 * processes. Because multiple backends may create gates concurrently, a
8 * dedicated PostgreSQL background worker (@c provsql_mmap_worker) is the
9 * sole writer to those files; normal backends communicate with it through
10 * a pair of anonymous pipes described in @c provsqlSharedState.
11 *
12 * This header exposes:
13 * - Functions to register, start, and manage the background worker.
14 * - A set of pipe I/O macros (@c READM, @c READB, @c WRITEB, @c WRITEM)
15 * that wrap @c read()/@c write() calls on the inter-process pipes.
16 * - A buffered-write interface (@c STARTWRITEM, @c ADDWRITEM, @c SENDWRITEM)
17 * that batches multiple fields into a single @c write() to stay within
18 * the atomic @c PIPE_BUF guarantee.
19 */
20#ifndef PROVSQL_MMAP_H
21#define PROVSQL_MMAP_H
22
23#include "limits.h"
24#include <unistd.h>
25
26#include "postgres.h"
27#include "provsql_utils.h"
28#include "provsql_config.h"
29
30/**
31 * @brief Entry point for the ProvSQL mmap background worker.
32 *
33 * Called by the postmaster when it launches the background worker.
34 * Enters the main loop (@c provsql_mmap_main_loop()) and never returns
35 * normally. The single @c Datum argument is required by the
36 * background-worker API but is not used.
37 */
38void provsql_mmap_worker(Datum);
39
40/**
41 * @brief Register the ProvSQL mmap background worker with PostgreSQL.
42 *
43 * Must be called from the extension's @c _PG_init() function so that
44 * the postmaster starts the worker on the next connection.
45 */
47
48/**
49 * @brief Open (or create) the mmap files and initialise the circuit store.
50 *
51 * Called once by the background worker at startup. Creates the four
52 * mmap-backed data files if they do not yet exist and maps them into the
53 * worker's address space.
54 */
56
57/**
58 * @brief Unmap and close the mmap files.
59 *
60 * Called by the background worker on shutdown to release resources and
61 * ensure all dirty pages are synced to disk via @c msync().
62 */
63void destroy_provsql_mmap(void);
64
65/**
66 * @brief Main processing loop of the mmap background worker.
67 *
68 * Waits for gate-creation requests from backend processes, processes them
69 * by writing to the mmap files, and handles SIGTERM for graceful shutdown.
70 */
71void provsql_mmap_main_loop(void);
72
73/**
74 * @brief Handle a single IPC message: read its payload and write its reply.
75 *
76 * The opcode @p c and database OID @p db_oid have already been consumed by
77 * the caller. Shared by the background-worker main loop (multi-process
78 * build) and the synchronous in-process dispatcher.
79 */
80void provsql_mmap_dispatch(char c, Oid db_oid);
81
82/**
83 * @brief Create a gate from in-extension C/C++ code (cache + worker IPC).
84 *
85 * Internal entry point behind the SQL-callable @c create_gate(), without
86 * Datum marshalling or gate-type-OID lookups; idempotent on
87 * already-mapped tokens.
88 *
89 * @param token UUID of the gate.
90 * @param type Gate type.
91 * @param nb_children Number of children.
92 * @param children_data Child UUIDs (may be NULL when @p nb_children is 0).
93 */
95 unsigned nb_children,
96 const pg_uuid_t *children_data);
97
98/**
99 * @brief Set an input gate's probability from in-extension C/C++ code.
100 *
101 * Internal entry point behind the SQL-callable @c set_prob().
102 *
103 * @param token UUID of the input gate.
104 * @param prob Probability value in [0,1].
105 * @return False if the worker rejected it (the token is not an input
106 * gate); true on success.
107 */
108bool provsql_internal_set_prob(const pg_uuid_t *token, double prob);
109
110/**
111 * @brief Set a gate's info fields from in-extension C/C++ code.
112 *
113 * Internal entry point behind the SQL-callable @c set_infos().
114 *
115 * @param token UUID of the gate.
116 * @param info1 First (gate-type-specific) info value.
117 * @param info2 Second info value.
118 */
119void provsql_internal_set_infos(const pg_uuid_t *token, unsigned info1,
120 unsigned info2);
121
122/**
123 * @brief Set a gate's extra string from in-extension C/C++ code.
124 *
125 * Internal entry point behind the SQL-callable @c set_extra().
126 *
127 * @param token UUID of the gate.
128 * @param str NUL-terminated extra string to attach.
129 */
130void provsql_internal_set_extra(const pg_uuid_t *token, const char *str);
131
132#ifdef PROVSQL_INPROCESS_STORE
133
134/**
135 * @brief In-process replacement for a pipe write of a complete request.
136 *
137 * Appends the message in @p buf (@p len bytes) to the request FIFO and runs
138 * @c provsql_mmap_dispatch once, leaving any reply in the response FIFO for
139 * the caller's @c READB / @c READB_BYTES to consume.
140 */
141bool provsql_inproc_send(const char *buf, size_t len);
142
143/** Growable shared write buffer used with @c STARTWRITEM / @c ADDWRITEM. */
144extern char *buffer;
145/** Current write position within @c buffer. */
146extern unsigned bufferpos;
147/** Allocated capacity of @c buffer. */
148extern size_t buffercap;
149/** @brief Ensure @c buffer can hold at least @p need bytes. */
150void provsql_buffer_ensure(size_t need);
151
152#define READM(var, type) provsql_fifo_pop (&provsql_shared_state->req, &(var), sizeof(type))
153#define READB(var, type) provsql_fifo_pop (&provsql_shared_state->resp, &(var), sizeof(type))
154#define WRITEB(pvar, type) provsql_fifo_push(&provsql_shared_state->resp, (pvar), sizeof(type))
155#define WRITEM(pvar, type) provsql_fifo_push(&provsql_shared_state->req, (pvar), sizeof(type))
156
157#define READB_BYTES(ptr, n) provsql_fifo_pop (&provsql_shared_state->resp, (ptr), (n))
158#define READM_BYTES(ptr, n) provsql_fifo_pop (&provsql_shared_state->req, (ptr), (n))
159#define WRITEB_BYTES(ptr, n) provsql_fifo_push(&provsql_shared_state->resp, (ptr), (n))
160
161#define STARTWRITEM() (bufferpos=0)
162#define ADDWRITEM(pvar, type) (provsql_buffer_ensure(bufferpos+sizeof(type)), memcpy(buffer+bufferpos, pvar, sizeof(type)), bufferpos+=sizeof(type))
163#define SENDWRITEM() provsql_inproc_send(buffer, bufferpos)
164
165#else
166
167/** @brief Read exactly @p n bytes from @p fd into @p dst; @c false on EOF/error. */
168bool provsql_read_all(int fd, void *dst, size_t n);
169
170/** Shared write buffer used with @c STARTWRITEM / @c ADDWRITEM / @c SENDWRITEM. */
171extern char buffer[PIPE_BUF];
172/** Current write position within @c buffer. */
173extern unsigned bufferpos;
174
175/** @brief Read one value of @p type from the background-to-main pipe. */
176#define READM(var, type) (read(provsql_shared_state->pipebmr, &var, sizeof(type))==(ssize_t)sizeof(type)) // flawfinder: ignore
177/** @brief Read one value of @p type from the main-to-background pipe. */
178#define READB(var, type) (read(provsql_shared_state->pipembr, &var, sizeof(type))==(ssize_t)sizeof(type)) // flawfinder: ignore
179/** @brief Write one value of @p type to the main-to-background pipe. */
180#define WRITEB(pvar, type) (write(provsql_shared_state->pipembw, pvar, sizeof(type))!=-1)
181/** @brief Write one value of @p type to the background-to-main pipe. */
182#define WRITEM(pvar, type) (write(provsql_shared_state->pipebmw, pvar, sizeof(type))!=-1)
183
184/** @brief Read exactly @p n bytes of a reply from the main-to-background pipe. */
185#define READB_BYTES(ptr, n) provsql_read_all(provsql_shared_state->pipembr, (ptr), (n)) // flawfinder: ignore
186/** @brief Read exactly @p n bytes of a request from the background-to-main pipe. */
187#define READM_BYTES(ptr, n) provsql_read_all(provsql_shared_state->pipebmr, (ptr), (n)) // flawfinder: ignore
188/** @brief Write @p n reply bytes to the main-to-background pipe. */
189#define WRITEB_BYTES(ptr, n) (write(provsql_shared_state->pipembw, (ptr), (n))!=-1)
190
191/** @brief Reset the shared write buffer for a new batched write. */
192#define STARTWRITEM() (bufferpos=0)
193/** @brief Append one value of @p type to the shared write buffer. */
194#define ADDWRITEM(pvar, type) (memcpy(buffer+bufferpos, pvar, sizeof(type)), bufferpos+=sizeof(type))
195/** @brief Flush the shared write buffer to the background-to-main pipe atomically. */
196#define SENDWRITEM() (write(provsql_shared_state->pipebmw, buffer, bufferpos)!=-1)
197
198#endif /* PROVSQL_INPROCESS_STORE */
199
200#endif /* PROVSQL_COLUMN_NAME */
Build-configuration switches shared across the C and C++ sources.
char buffer[PIPE_BUF]
Shared write buffer used with STARTWRITEM / ADDWRITEM / SENDWRITEM.
unsigned bufferpos
Current write position within buffer.
void provsql_internal_set_extra(const pg_uuid_t *token, const char *str)
Set a gate's extra string from in-extension C/C++ code.
void initialize_provsql_mmap(void)
Open (or create) the mmap files and initialise the circuit store.
void provsql_internal_create_gate(const pg_uuid_t *token, gate_type type, unsigned nb_children, const pg_uuid_t *children_data)
Create a gate from in-extension C/C++ code (cache + worker IPC).
void provsql_mmap_worker(Datum)
Entry point for the ProvSQL mmap background worker.
bool provsql_read_all(int fd, void *dst, size_t n)
Read exactly n bytes from fd into dst; false on EOF/error.
void provsql_mmap_dispatch(char c, Oid db_oid)
Handle a single IPC message: read its payload and write its reply.
void destroy_provsql_mmap(void)
Unmap and close the mmap files.
bool provsql_internal_set_prob(const pg_uuid_t *token, double prob)
Set an input gate's probability from in-extension C/C++ code.
void provsql_mmap_main_loop(void)
Main processing loop of the mmap background worker.
void provsql_internal_set_infos(const pg_uuid_t *token, unsigned info1, unsigned info2)
Set a gate's info fields from in-extension C/C++ code.
void RegisterProvSQLMMapWorker(void)
Register the ProvSQL mmap background worker with PostgreSQL.
Core types, constants, and utilities shared across ProvSQL.
UUID structure.