libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_reg.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * @stability stable
4 * Use of this source code is governed by the ISC License.
5 *
6 * src/inc/xtc_reg.h
7 * Process registry: name -> xtc_pid_t lookup. M10.5.
8 *
9 * Erlang's gen_server-via-name pattern: spawn a service, register
10 * it under a stable name, and the rest of the system finds it by
11 * name rather than by passing pids around. We provide this as a
12 * per-application table guarded by a mutex; entries are
13 * registered/unregistered explicitly.
14 */
15
16#ifndef XTC_REG_H
17#define XTC_REG_H
18
19#include "xtc_export.h"
20
21#include <stddef.h>
22
23#include "xtc.h"
24#include "xtc_proc.h"
25
26typedef struct xtc_reg xtc_reg_t;
27
28/*
29 * PUBLIC: int xtc_reg_create __P((xtc_reg_t **));
30 * PUBLIC: void xtc_reg_destroy __P((xtc_reg_t *));
31 * PUBLIC: int xtc_reg_register __P((xtc_reg_t *, const char *, xtc_pid_t));
32 * PUBLIC: int xtc_reg_unregister __P((xtc_reg_t *, const char *));
33 * PUBLIC: int xtc_reg_whereis __P((xtc_reg_t *, const char *, xtc_pid_t *));
34 * PUBLIC: int xtc_reg_count __P((const xtc_reg_t *));
35 * PUBLIC: int xtc_reg_register_dup __P((xtc_reg_t *, const char *, xtc_pid_t));
36 * PUBLIC: int xtc_reg_unregister_pid __P((xtc_reg_t *, const char *, xtc_pid_t));
37 * PUBLIC: int xtc_reg_drop_pid __P((xtc_reg_t *, xtc_pid_t));
38 * PUBLIC: void xtc_reg_reaper __P((void *));
39 * PUBLIC: int xtc_reg_register_mon __P((xtc_reg_t *, const char *, xtc_pid_t));
40 * PUBLIC: int xtc_svr_call_name __P((xtc_reg_t *, const char *, const void *, size_t, void **, size_t *, int64_t));
41 * PUBLIC: int xtc_reg_members __P((xtc_reg_t *, const char *, int (*)(xtc_pid_t, void *), void *));
42 */
43XTC_API int xtc_reg_create(xtc_reg_t **out);
44XTC_API void xtc_reg_destroy(xtc_reg_t *r);
45
46/* Register name -> pid. Fails with XTC_E_INVAL if name already taken. */
47XTC_API int xtc_reg_register(xtc_reg_t *r, const char *name, xtc_pid_t pid);
48
49/* Remove a name. Returns XTC_E_INVAL if not registered. */
50XTC_API int xtc_reg_unregister(xtc_reg_t *r, const char *name);
51
52/* Look up a pid by name. Writes to *out_pid on success. */
53XTC_API int xtc_reg_whereis(xtc_reg_t *r, const char *name, xtc_pid_t *out_pid);
54
55XTC_API int xtc_reg_count(const xtc_reg_t *r);
56
57/* Duplicate-key (pub/sub, group-membership) registration: many pids may
58 * share one key. The substrate for process groups. Registering the
59 * same (key, pid) twice is idempotent. */
60XTC_API int xtc_reg_register_dup(xtc_reg_t *r, const char *key, xtc_pid_t pid);
61
62/* Remove one (key, pid) duplicate-key entry (a group leave). */
63XTC_API int xtc_reg_unregister_pid(xtc_reg_t *r, const char *key, xtc_pid_t pid);
64
65/* Remove `pid` from EVERY key it is registered under (unique names and
66 * all duplicate-key groups). The "process left everything" cleanup an
67 * embedder calls when a process exits or a connection closes, until the
68 * registry gains an automatic monitor-on-DOWN. Returns the number of
69 * entries removed. */
70XTC_API int xtc_reg_drop_pid(xtc_reg_t *r, xtc_pid_t pid);
71
72/* The crash-aware registry. Spawn ONE proc with this body and the
73 * registry as its argument (xtc_proc_spawn(loop, xtc_reg_reaper, reg,
74 * ...)). It registers itself, then auto-drops any pid registered via
75 * xtc_reg_register_mon when that pid goes DOWN -- the automatic form of
76 * xtc_reg_drop_pid. Runs until its loop is torn down. */
77XTC_API void xtc_reg_reaper(void *reg);
78
79/* Register `name` -> `pid` (like xtc_reg_register) AND, if a reaper proc
80 * is running, arrange for the entry to be auto-dropped when `pid` goes
81 * DOWN. With no reaper it is exactly xtc_reg_register (the caller may
82 * still xtc_reg_drop_pid manually). */
83XTC_API int xtc_reg_register_mon(xtc_reg_t *r, const char *name, xtc_pid_t pid);
84
85/* Via-dispatch: look up `name` -> pid, then xtc_svr_call it. Returns
86 * XTC_E_NOTFOUND if the name is not registered, otherwise the result of
87 * xtc_svr_call. Lets a client address a gen_server by registered name
88 * instead of holding its pid (the Erlang {via, ...} / global name
89 * pattern). */
90XTC_API int xtc_svr_call_name(xtc_reg_t *r, const char *name,
91 const void *req, size_t req_size,
92 void **out_reply, size_t *out_size,
93 int64_t timeout_ns);
94
95/* Visit every pid registered under `key`. The callback runs under the
96 * registry lock (keep it brief; do not re-enter the registry); a nonzero
97 * return stops the walk. Returns the number of members visited. */
98XTC_API int xtc_reg_members(xtc_reg_t *r, const char *key,
99 int (*fn)(xtc_pid_t pid, void *user), void *user);
100
101#endif /* XTC_REG_H */