ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
provsql_shmem.h
Go to the documentation of this file.
1/**
2 * @file provsql_shmem.h
3 * @brief Shared-memory segment and inter-process pipe management.
4 *
5 * ProvSQL uses a small PostgreSQL shared-memory segment (@c provsqlSharedState)
6 * to hold the file descriptors of the anonymous pipes that connect
7 * normal backends to the mmap background worker, together with a
8 * lightweight lock that serialises concurrent gate-creation requests.
9 *
10 * This header declares:
11 * - @c provsqlSharedState, the layout of the shared segment.
12 * - Hook functions (@c provsql_shmem_startup, @c provsql_shmem_request)
13 * that integrate with PostgreSQL's shared-memory lifecycle.
14 * - Convenience wrappers (@c provsql_shmem_lock_exclusive, etc.) around
15 * the embedded @c LWLock.
16 * - Saved pointers to the previous hook functions so that ProvSQL can
17 * chain into an existing hook chain.
18 */
19#ifndef PROVSQL_SHMEM_H
20#define PROVSQL_SHMEM_H
21
22#include "postgres.h"
23#include "miscadmin.h"
24#include "storage/ipc.h"
25#include "storage/lwlock.h"
26
27#include "provsql_config.h"
28
29/** @brief Saved pointer to the previous @c shmem_startup_hook, for chaining. */
30extern shmem_startup_hook_type prev_shmem_startup;
31#if (PG_VERSION_NUM >= 150000) || defined(DOXYGEN)
32/** @brief Saved pointer to the previous @c shmem_request_hook (PG ≥ 15), for chaining. */
33extern shmem_request_hook_type prev_shmem_request;
34#endif
35
36/**
37 * @brief Initialise the ProvSQL shared-memory segment.
38 *
39 * Called from the @c shmem_startup_hook. Creates (or attaches to) the
40 * @c provsqlSharedState segment and initialises the embedded @c LWLock
41 * and pipe file descriptors. Chains to @c prev_shmem_startup if set.
42 */
43void provsql_shmem_startup(void);
44
45/**
46 * @brief Return the number of bytes required for the shared-memory segment.
47 *
48 * Used by PostgreSQL's shared-memory allocator during startup.
49 *
50 * @return Size in bytes of the @c provsqlSharedState structure.
51 */
52Size provsql_memsize(void);
53
54/**
55 * @brief Request shared memory from PostgreSQL (PG ≥ 15).
56 *
57 * Called from the @c shmem_request_hook (introduced in PostgreSQL 15) to
58 * reserve the segment before shared memory is finalised. Chains to
59 * @c prev_shmem_request if set. On older PostgreSQL versions this is a
60 * no-op because memory reservation happened in @c _PG_init().
61 */
62void provsql_shmem_request(void);
63
64/**
65 * @brief Shared state stored in the PostgreSQL shared-memory segment.
66 *
67 * All backends and the background worker access this structure through
68 * the @c provsql_shared_state global pointer.
69 *
70 * @c lock serialises gate-creation messages so that only one backend
71 * writes to the pipe at a time. The four @c long fields hold OS file
72 * descriptors for the two anonymous pipes:
73 * - @c pipembr / @c pipembw: main-backend → background (write end in main)
74 * - @c pipebmr / @c pipebmw: background → main-backend (write end in worker)
75 */
76#ifdef PROVSQL_INPROCESS_STORE
77
78/**
79 * @brief Growable byte FIFO backing the in-process request/response channel.
80 *
81 * Replaces the inter-process pipes when there is a single PostgreSQL
82 * process (browser/WASM target). Bytes are appended at @c tail and
83 * consumed from @c head; the buffer is reclaimed (head reset to 0) once
84 * fully drained and grown on demand.
85 */
86typedef struct provsql_fifo
87{
88 unsigned char *buf; ///< Backing storage (NULL until first push)
89 size_t head; ///< Read offset
90 size_t tail; ///< Write offset (== valid bytes once head is 0)
91 size_t cap; ///< Allocated capacity
92} provsql_fifo;
93
94/** @brief Append @p n bytes from @p src to @p f, growing as needed. */
95bool provsql_fifo_push(provsql_fifo *f, const void *src, size_t n);
96/** @brief Pop @p n bytes from @p f into @p dst; @c false on underflow. */
97bool provsql_fifo_pop(provsql_fifo *f, void *dst, size_t n);
98
99typedef struct provsqlSharedState
100{
101 provsql_fifo req; ///< Request channel: backend → in-process dispatch
102 provsql_fifo resp; ///< Response channel: dispatch → backend
103 char kcmcp_endpoint[256]; ///< Live endpoint of the managed KCMCP server
104 ///< ("" when none).
106
107/** @brief Point @c provsql_shared_state at the process-local state. */
108void provsql_inproc_init(void);
109
110#else
111
112typedef struct provsqlSharedState
113{
114 LWLock *lock; ///< Mutual-exclusion lock for pipe writes
115 long pipebmr; ///< Background-to-main pipe: read end (worker reads)
116 long pipebmw; ///< Background-to-main pipe: write end (worker writes)
117 long pipembr; ///< Main-to-background pipe: read end (worker reads)
118 long pipembw; ///< Main-to-background pipe: write end (backend writes)
119 char kcmcp_endpoint[256]; ///< Live endpoint of the managed KCMCP server
120 ///< ("" when none): written by the supervisor
121 ///< worker, read by the in-extension client.
123
124#endif /* PROVSQL_INPROCESS_STORE */
125
126/** @brief Pointer to the ProvSQL shared-memory segment (set in @c provsql_shmem_startup). */
128
129/**
130 * @brief Acquire the ProvSQL LWLock in exclusive mode.
131 *
132 * Callers must pair this with @c provsql_shmem_unlock().
133 */
135
136/**
137 * @brief Acquire the ProvSQL LWLock in shared mode.
138 *
139 * Multiple backends may hold the shared lock simultaneously.
140 * Callers must pair this with @c provsql_shmem_unlock().
141 */
143
144/**
145 * @brief Release the ProvSQL LWLock.
146 *
147 * Must be called after @c provsql_shmem_lock_exclusive() or
148 * @c provsql_shmem_lock_shared().
149 */
150void provsql_shmem_unlock(void);
151
152#endif /* ifndef PROVSQL_SHMEM_H */
Build-configuration switches shared across the C and C++ sources.
provsqlSharedState * provsql_shared_state
Pointer to the ProvSQL shared-memory segment (set in provsql_shmem_startup).
shmem_startup_hook_type prev_shmem_startup
Saved pointer to the previous shmem_startup_hook, for chaining.
void provsql_shmem_unlock(void)
Release the ProvSQL LWLock.
void provsql_shmem_lock_exclusive(void)
Acquire the ProvSQL LWLock in exclusive mode.
void provsql_shmem_request(void)
Request shared memory from PostgreSQL (PG ≥ 15).
void provsql_shmem_startup(void)
Initialise the ProvSQL shared-memory segment.
Size provsql_memsize(void)
Return the number of bytes required for the shared-memory segment.
shmem_request_hook_type prev_shmem_request
Saved pointer to the previous shmem_request_hook (PG ≥ 15), for chaining.
void provsql_shmem_lock_shared(void)
Acquire the ProvSQL LWLock in shared mode.
Shared state stored in the PostgreSQL shared-memory segment.
long pipebmr
Background-to-main pipe: read end (worker reads).
LWLock * lock
Mutual-exclusion lock for pipe writes.
long pipembr
Main-to-background pipe: read end (worker reads).
long pipebmw
Background-to-main pipe: write end (worker writes).
long pipembw
Main-to-background pipe: write end (backend writes).
char kcmcp_endpoint[256]
Live endpoint of the managed KCMCP server ("" when none): written by the supervisor worker,...