cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
async_tls.c
Go to the documentation of this file.
1
12#include "async_internal.h"
14#include <stdatomic.h>
15#include <stdio.h>
16#include <stdlib.h>
17
18static __thread const cwist_async *t_pending_async = NULL;
19static __thread const cwist_http_response *t_pending_res = NULL;
20
21static _Atomic bool g_misuse_reported = false;
22
23/* Report an exchange whose public deferred/async fields disagree with what
24 * cwist_async_defer() recorded. Prints once per process; with
25 * CWIST_ASYNC_STRICT=1 it aborts so the misuse leaves a core. */
26static void cwist_async_report_misuse(const char *what) {
27 const char *strict = getenv("CWIST_ASYNC_STRICT");
28 bool abort_now = strict && strict[0] == '1';
29 if (!atomic_exchange(&g_misuse_reported, true) || abort_now) {
31 "cwist: async misuse: %s; producers must not write res->deferred or "
32 "res->async (see cwist_async_wait_dispatched())\n",
33 what);
34 }
35 if (abort_now) abort();
36}
37
38void cwist_async_record_pending(cwist_async *a, const cwist_http_response *res) {
39 t_pending_async = a;
40 t_pending_res = res;
41}
42
43void cwist_async_forget_handle(const cwist_async *a) {
44 if (a && t_pending_async == a) {
45 t_pending_async = NULL;
46 t_pending_res = NULL;
47 }
48}
49
51 if (res && t_pending_res == res) {
52 t_pending_async = NULL;
53 t_pending_res = NULL;
54 }
55}
56
58 cwist_async *a = t_pending_res == res ? (cwist_async *)t_pending_async : NULL;
59 t_pending_async = NULL;
60 t_pending_res = NULL;
61 if (!res) return NULL;
62 if (a) {
63 if (!res->deferred || res->async != a)
64 cwist_async_report_misuse("res->deferred/res->async changed before the dispatch ack");
65 } else if (res->deferred) {
66 cwist_async_report_misuse("res->deferred set without cwist_async_defer()");
67 }
68 return a;
69}
70
72 return res && (res->deferred || (t_pending_async && t_pending_res == res));
73}
Deferred-response (async handler) API for CWIST.
struct cwist_async cwist_async
Definition async.h:54
Private wiring between the deferred-response path (async.c) and the C1M connection engine (http....
void cwist_async_forget_handle(const cwist_async *a)
Definition async_tls.c:43
bool cwist_async_res_deferred(const cwist_http_response *res)
Definition async_tls.c:71
void cwist_async_forget_response(const cwist_http_response *res)
Definition async_tls.c:50
void cwist_async_record_pending(cwist_async *a, const cwist_http_response *res)
Definition async_tls.c:38
cwist_async * cwist_async_dispatch_take(cwist_http_response *res)
Definition async_tls.c:57
size_t cap
Definition otel.c:56
HTTP Response Object. Supports standard string body or Zero-Copy pointer body.
Definition http.h:82
void * async
Owning cwist_async while deferred (read-only).
Definition http.h:245
bool deferred
Deferred-response handoff (internal; see net/http/async.h)
Definition http.h:244