mirror of
https://github.com/versity/versitygw.git
synced 2026-09-22 07:54:14 +00:00
rdma: add terminal notification callback to the RC server ABI
RC sessions that never reach a completion (expired, abandoned, or canceled before READY) currently vanish inside the reaper without any trace on the operational surface. Add a terminal notification callback to the C ABI so the server reports the final outcome of every session exactly once, fired from the reaper with no server lock held.
This commit is contained in:
@@ -101,6 +101,11 @@ struct rc_server {
|
||||
* races an in-flight sink pointer swap. */
|
||||
rc_log_fn log_fn = nullptr;
|
||||
void *log_ctx = nullptr;
|
||||
/* Terminal notification sink: same lifetime contract as log_fn
|
||||
* (installed once at init, cleared by destroy after the reaper
|
||||
* joined). Fired by reapSession with no lock held. */
|
||||
rc_terminal_fn term_fn = nullptr;
|
||||
void *term_ctx = nullptr;
|
||||
std::atomic<uint64_t> epoch_counter{1};
|
||||
/* resource accounting (global buckets; per-principal map). */
|
||||
std::mutex acct_mtx;
|
||||
@@ -253,6 +258,13 @@ void reapSession(rc_server *srv, RcSession *s) {
|
||||
* is actually gone: a surviving QP still holds the device. */
|
||||
if (destroyed) hipObj::v2::releaseDevice(srv->device);
|
||||
limitsRelease(srv, s->principal, s->staging_len);
|
||||
/* Terminal notification: the sink runs after every server-side
|
||||
* bookkeeping above so it observes the session as fully gone,
|
||||
* and no lock is held here per the callback contract. */
|
||||
rc_terminal_fn tfn = srv->term_fn;
|
||||
if (tfn)
|
||||
tfn(srv->term_ctx, s->core.id.c_str(), s->last_outcome,
|
||||
(uint64_t)s->staging_len);
|
||||
}
|
||||
|
||||
/* Runs the reap pass: sessions marked reap_pending (or in the
|
||||
@@ -301,6 +313,13 @@ void rc_server_set_log_sink(rc_server *srv, rc_log_fn fn, void *ctx) {
|
||||
srv->log_ctx = ctx;
|
||||
}
|
||||
|
||||
void rc_server_set_terminal_notify(rc_server *srv, rc_terminal_fn fn,
|
||||
void *ctx) {
|
||||
if (!srv) return;
|
||||
srv->term_fn = fn;
|
||||
srv->term_ctx = ctx;
|
||||
}
|
||||
|
||||
int rc_server_init(const rc_device_opts *opts, rc_server **out) {
|
||||
if (!opts || !out) return RC_E_ARG;
|
||||
if (!hipObj::ibv.ensureLoaded()) {
|
||||
|
||||
@@ -52,6 +52,21 @@ typedef struct rc_server rc_server;
|
||||
|
||||
void rc_server_set_log_sink(rc_server *srv, rc_log_fn fn, void *ctx);
|
||||
|
||||
/* Terminal session notification. Fired exactly once per session
|
||||
* when the reaper destroys it (expiry, CANCEL, or destroy),
|
||||
* carrying the last outcome observed for the session. `id` is
|
||||
* only valid for the duration of the call. Called with no server
|
||||
* lock held; the sink must return promptly and must not call back
|
||||
* into the server. Sessions that end inside a READY/FinishPut
|
||||
* handler still fire this notification after the handler's own
|
||||
* terminal bookkeeping, so the sink can treat it as the single
|
||||
* authoritative "the session is gone" signal. */
|
||||
typedef void (*rc_terminal_fn)(void *ctx, const char *id, int outcome,
|
||||
uint64_t bytes);
|
||||
|
||||
void rc_server_set_terminal_notify(rc_server *srv, rc_terminal_fn fn,
|
||||
void *ctx);
|
||||
|
||||
/* Device selection: matching GID prefix when gid_hint is set,
|
||||
* otherwise the first verbs device. */
|
||||
typedef struct {
|
||||
|
||||
Reference in New Issue
Block a user