CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
queue.h
Go to the documentation of this file.
1
9
10#pragma once
11// This header file is auto-generated!
12// Do not make changes to this file or they will be overwritten.
13// clang-format off
14#include <cx/obj.h>
15#include <cx/struct.h>
16#include <cx/net/net_shared.h>
17#include <cx/thread.h>
18#include <cx/net/pool.h>
19
20CX_C_BEGIN
21
22typedef struct NetQueue NetQueue;
23typedef struct NetQueue_WeakRef NetQueue_WeakRef;
25saDeclarePtr(NetQueue_WeakRef);
26#define _sti_NetQueue _sti_object
27#define SType_NetQueue NetQueue*
28#define STStorageType_NetQueue NetQueue*
29#define STypeArg_NetQueue(type, val) stgeneric(object, (ObjInst*)objInstCheckClass(NetQueue, val))
30#define STypeArgPtr_NetQueue(type, val) (stgeneric*)objInstCheckClassPtr(NetQueue, val)
31#define STypeCheckedArg_NetQueue(type, val) stType(type), stArg(type, val)
32#define STypeCheckedPtrArg_NetQueue(type, val) stType(type), stArgPtr(type, val)
33
34
35
36typedef struct NetQueue_ClassIf {
37 ObjIface* _implements;
38 ObjIface* _parent;
39 size_t _size;
40
41 bool (*addSocket)(_In_ void* self, NetSocket* socket);
42 bool (*removeSocket)(_In_ void* self, NetSocket* socket);
43 NetSocket* (*socket)(_In_ void* self, NetSocketType type);
44 // Begin one outbound connect attempt against a single resolved address
45 // // The one backend-specific piece of connect. By the time this is called, the portable state
46 // machine has already picked the address and armed the deadline; this just gets a fresh OS
47 // handle of the address's family and starts the attempt. A readiness backend resets the
48 // handle, issues a non-blocking connect(), and watches it for writability (and the except
49 // set, where Windows signals a failed connect). A completion backend resets and binds the
50 // handle and posts an overlapped ConnectEx.
51 // // The outcome is reported back through netsocket_connectResult() -- immediately for a
52 // synchronous result, or later from readiness, a completion, or the timeout sweep.
53 // // @param sock Socket to connect (a stream socket in NS_Connecting)
54 // @param addr Address to attempt
55 // @return true if the attempt was initiated or resolved, false if it could not be started
56 bool (*connectBegin)(_In_ void* self, NetSocket* sock, const NetAddr* addr);
57 // React to a socket having just become connected
58 // // Called once, after a successful connect has transitioned the socket to NS_Connected and
59 // its NET_Connection event has been queued. The backend starts servicing the socket for
60 // receive here -- select rebuilds its watch set to read-watch it, IOCP posts the first
61 // WSARecv -- the same thing addSocket() does for a socket that was already connected when it
62 // joined the queue.
63 // // @param sock Socket that just connected
64 void (*connectArm)(_In_ void* self, NetSocket* sock);
65 // Begin (or resume) accepting connections on a now-listening socket
66 // // The accept-side counterpart of connectArm. Called once the socket enters NS_Listening --
67 // from the platform listen(), or from addSocket() if the socket was already listening when
68 // it joined the queue. A readiness backend wakes its loop so the next rebuild read-watches
69 // the listener; a completion backend posts its initial batch of overlapped AcceptEx
70 // operations. Each accepted connection is wrapped and handed to netsocket_accepted().
71 // // @param sock Listening socket (a stream socket in NS_Listening)
72 void (*acceptArm)(_In_ void* self, NetSocket* sock);
73 bool (*shutdown)(_In_ void* self, int64 timeout);
74 bool (*tick)(_In_ void* self, int64 wait);
75} NetQueue_ClassIf;
76extern NetQueue_ClassIf NetQueue_ClassIf_tmpl;
77
79typedef struct NetQueue {
80 union {
81 NetQueue_ClassIf* _;
82 void* _is_NetQueue;
83 void* _is_ObjInst;
84 };
85 ObjClassInfo* _clsinfo;
86 atomic(uintptr) _ref;
87 atomic(ptr) _weakref;
88
96 void* handlerCtx;
99 Weak(ObjInst)* handlerWeak;
101 hashtable sockets;
120 atomic(uint32) gcLastLo;
125 atomic(uint32) droppedNoBuf;
126 atomic(uint32) nflows;
130 NetTimerEntry* timers;
131 uint32 ntimers;
132 uint32 timersCap;
133 uint64 timerSerial;
134 hashtable timerIdx;
139 atomic(uint32) timersLive;
145 sa_Thread workers;
147 atomic(uint32) shutdownReq;
154 NetSendPumpFn sendPump;
155 void* sendCtx;
160 NetWakeFn wake;
161 void* wakeCtx;
162} NetQueue;
163extern ObjClassInfo NetQueue_clsinfo;
164#define NetQueue(inst) objInstCheckClass(NetQueue, inst)
165#define NetQueueNone ((NetQueue*)NULL)
166
167typedef struct NetQueue_WeakRef {
168 union {
169 ObjInst* _inst;
170 void* _is_NetQueue_WeakRef;
171 void* _is_ObjInst_WeakRef;
172 };
173 atomic(uintptr) _ref;
174 RWLock _lock;
175} NetQueue_WeakRef;
176#define NetQueue_WeakRef(inst) objWeakRefCheckClass(NetQueue, inst)
177
178void NetQueue_presetClient(_Out_ NetQueueConfig* conf);
187#define netqueuePresetClient(conf) NetQueue_presetClient(conf)
188
189void NetQueue_presetServer(_Out_ NetQueueConfig* conf);
198#define netqueuePresetServer(conf) NetQueue_presetServer(conf)
199
200_Ret_maybenull_ NetSocket* NetQueue_connect(_In_ NetQueue* self, _In_opt_ strref host, uint16 port, _In_opt_ const NetHandlers* handlers, _In_opt_ void* ctx);
224#define netqueueConnect(self, host, port, handlers, ctx) NetQueue_connect(NetQueue(self), host, port, handlers, ctx)
225
226_Ret_maybenull_ NetSocket* NetQueue_connectPrep(_In_ NetQueue* self, _In_opt_ strref host, uint16 port, _In_opt_ const NetHandlers* handlers, _In_opt_ void* ctx, NetConnectPrepCB prep, _In_opt_ void* prepctx);
254#define netqueueConnectPrep(self, host, port, handlers, ctx, prep, prepctx) NetQueue_connectPrep(NetQueue(self), host, port, handlers, ctx, prep, prepctx)
255
256_Ret_maybenull_ NetSocket* NetQueue_listen(_In_ NetQueue* self, _In_ const NetAddr* addr, int backlog, _In_opt_ const NetHandlers* handlers, _In_opt_ void* ctx);
282#define netqueueListen(self, addr, backlog, handlers, ctx) NetQueue_listen(NetQueue(self), addr, backlog, handlers, ctx)
283
284void NetQueue_setHandlers(_In_ NetQueue* self, _In_opt_ const NetHandlers* handlers, _In_opt_ void* ctx);
295#define netqueueSetHandlers(self, handlers, ctx) NetQueue_setHandlers(NetQueue(self), handlers, ctx)
296
297void NetQueue_setHandlersObj(_In_ NetQueue* self, _In_opt_ const NetHandlers* handlers, _In_opt_ ObjInst* ctx);
306#define netqueueSetHandlersObj(self, handlers, ctx) NetQueue_setHandlersObj(NetQueue(self), handlers, ObjInst(ctx))
307
308_Ret_maybenull_ NetFlow* NetQueue_promoteFlow(_In_ NetQueue* self, _Inout_ NetSocket* sock, _In_ const NetAddr* peer);
324#define netqueuePromoteFlow(self, sock, peer) NetQueue_promoteFlow(NetQueue(self), sock, peer)
325
326uint32 NetQueue_droppedNoBuf(_In_ NetQueue* self);
336#define netqueueDroppedNoBuf(self) NetQueue_droppedNoBuf(NetQueue(self))
337
338void NetQueue__applyConfig(_In_ NetQueue* self, _In_opt_ const NetQueueConfig* conf);
339// void netqueue_applyConfig(NetQueue* self, const NetQueueConfig* conf);
340//
341// -----------------------------------------------------------------------------------------
342// PRIVATE IMPLEMENTATION DETAILS
343// // Everything below this point is internal plumbing between the net module's own translation
344// units and the platform backends. It is not a stable API and carries no compatibility
345// promise -- signatures and semantics change whenever the implementation needs them to.
346// -----------------------------------------------------------------------------------------
347// Construction (queue.c)
348// Apply a configuration to a queue under construction. Called by a backend's factory before
349// objInstInit(), so that the sizes everything else is built from are already in place when the
350// base class initializes. `conf` is NULL for the client preset.
351#define netqueue_applyConfig(self, conf) NetQueue__applyConfig(NetQueue(self), conf)
352
353void NetQueue__startWorkers(_In_ NetQueue* self, int32 n);
354// void netqueue_startWorkers(NetQueue* self, int32 n);
355//
356// Worker pool (queue.c)
357// // The generic dispatch pool the base class owns: N threads that drain the runqueue and block
358// on runqSema when it is empty. A backend's factory starts them in threaded mode; polled
359// queues never call these and run everything on the caller's tick() thread.
360// Start n dispatch worker threads. Fewer may end up running if thread creation fails; the
361// actual count lands in self->workers.
362#define netqueue_startWorkers(self, n) NetQueue__startWorkers(NetQueue(self), n)
363
364void NetQueue__stopWorkers(_In_ NetQueue* self, int64 timeout);
365// void netqueue_stopWorkers(NetQueue* self, int64 timeout);
366//
367// Ask every dispatch worker to exit and join it. Each worker drains the runqueue one last time
368// on its way out, so terminal events queued during shutdown are still delivered. `timeout`
369// <= 0 waits indefinitely. Idempotent -- safe to call when no workers are running.
370#define netqueue_stopWorkers(self, timeout) NetQueue__stopWorkers(NetQueue(self), timeout)
371
372bool NetQueue__ingestDatagram(_In_ NetQueue* self, _Inout_ NetSocket* sock, _In_ NetAddr* peer, _In_opt_ const NetPktInfo* info, _Inout_ Buffer* buf);
373// bool netqueue_ingestDatagram(NetQueue* self, NetSocket* sock, NetAddr* peer, const NetPktInfo* info, Buffer* buf);
374//
375// Ingest (queue.c)
376// // Where a packet enters the core. _ingestDatagram is the datagram front door and belongs to the
377// queue; _submit is the runqueue's producer half and lives beside its consumer in dispatch.c.
378// Hand a received datagram to the core for demultiplexing and dispatch. Takes ownership of
379// `buf`, which must have come from the queue's own buffer pool. Resolves the flow for the
380// source address (creating one, reclaiming under cap pressure, or falling back to the
381// flowRefused handler), pushes the packet onto that flow's inbox, and enqueues the flow if it
382// was idle. Returns true if the packet was queued to a flow, false if it was dropped or handed
383// to a NET_FlowRefused handler instead.
384#define netqueue_ingestDatagram(self, sock, peer, info, buf) NetQueue__ingestDatagram(NetQueue(self), sock, peer, info, buf)
385
386void NetQueue__submit(_In_ NetQueue* self, _Inout_ NetFlow* flow, _Inout_ NetMessage* msg);
387// void netqueue_submit(NetQueue* self, NetFlow* flow, NetMessage* msg);
388//
389// Hand a message to a flow and make sure something will come along to run it. Takes ownership
390// of the message. `self` may be NULL, in which case the message is simply released.
391#define netqueue_submit(self, flow, msg) NetQueue__submit(NetQueue(self), flow, msg)
392
393bool NetQueue__dispatch(_In_ NetQueue* self);
394// bool netqueue_dispatch(NetQueue* self);
395//
396// Dispatch (dispatch.c)
397// // The runqueue and the event delivery it feeds. _submit above is the producer half of the same
398// claim protocol _dispatch consumes.
399// Claim one flow from the runqueue and drain it. This is the body of a worker thread, and it
400// is also what tick() runs inline in polled mode -- the same code either way, just without the
401// threads. Returns false if the runqueue was empty.
402#define netqueue_dispatch(self) NetQueue__dispatch(NetQueue(self))
403
404void NetQueue__deliver(_In_ NetQueue* self, _In_opt_ NetSocket* sock, _In_opt_ NetFlow* flow, _Inout_ NetEvent* ev);
405// void netqueue_deliver(NetQueue* self, NetSocket* sock, NetFlow* flow, NetEvent* ev);
406//
407// Resolve and invoke the handler for an event, filling in the event's queue/socket/flow/ctx
408// fields; a no-op when no level supplies a handler. In dev builds the callback is timed, and
409// one that holds its worker past the warning threshold gets logged with the socket and event
410// type -- handlers are expected to return quickly, and this is how we notice when one doesn't.
411// Every callback invocation should go through here so timing stays consistent. `self` may be
412// NULL, in which case only the socket and flow levels are consulted.
413#define netqueue_deliver(self, sock, flow, ev) NetQueue__deliver(NetQueue(self), sock, flow, ev)
414
415void NetQueue__maint(_In_ NetQueue* self);
416// void netqueue_maint(NetQueue* self);
417//
418// Maintenance (queue.c)
419// Opportunistic GC of the queue's dynamic PrQueues (runqueue and receive pool). Call it from a
420// thread that has just drained the runqueue and is about to idle -- the moment the PrQueue
421// docs recommend for collection. Time-gated and single-runner, so a whole worker pool or a
422// tight poll loop costs one GC attempt per interval; safe to call as often as convenient.
423#define netqueue_maint(self) NetQueue__maint(NetQueue(self))
424
425NetTimerId NetQueue__addTimer(_In_ NetQueue* self, _Inout_ NetFlow* flow, int64 delay, flags_t flags, NetTimerFn fn, _In_opt_ void* ctx);
426// NetTimerId netqueue_addTimer(NetQueue* self, NetFlow* flow, int64 delay, flags_t flags, NetTimerFn fn, void* ctx);
427//
428// Timers (timer.c)
429// // The queue-wide deadline heap behind netflowAddTimer(). Backends drive it with two calls per
430// wait: _nextDeadline() to bound the sleep, and _timerSweep() to fire whatever came due.
431// Arm a timer on a flow, `delay` microseconds from now. `fn` is NULL for an application timer
432// (delivered as NET_Timer through the flow's inbox) or a framework hook fired inline on the
433// sweeping thread. Returns the new id, or 0 if the flow is already dying or has no queue.
434#define netqueue_addTimer(self, flow, delay, flags, fn, ctx) NetQueue__addTimer(NetQueue(self), flow, delay, flags, fn, ctx)
435
436bool NetQueue__cancelTimer(_In_ NetQueue* self, NetTimerId id);
437// bool netqueue_cancelTimer(NetQueue* self, NetTimerId id);
438//
439// Cancel an armed timer. Returns true only if this call removed it from the heap -- a timer
440// already popped for delivery answers false. A successful cancel means the caller is the one
441// that gets to act on it. Cancelling an unknown or already-fired id is a harmless false.
442#define netqueue_cancelTimer(self, id) NetQueue__cancelTimer(NetQueue(self), id)
443
444bool NetQueue__rearmTimer(_In_ NetQueue* self, NetTimerId id, int64 delay);
445// bool netqueue_rearmTimer(NetQueue* self, NetTimerId id, int64 delay);
446//
447// Move an armed timer's deadline to `delay` microseconds from now. Returns false if the timer
448// is not armed (cancelled, or already popped for delivery).
449#define netqueue_rearmTimer(self, id, delay) NetQueue__rearmTimer(NetQueue(self), id, delay)
450
451void NetQueue__cancelFlowTimers(_In_ NetQueue* self, _Inout_ NetFlow* flow);
452// void netqueue_cancelFlowTimers(NetQueue* self, NetFlow* flow);
453//
454// Cancel every timer armed on a flow. Called on the flow's terminal path so a long deadline on
455// a dead connection cannot keep the flow object alive until it expires.
456#define netqueue_cancelFlowTimers(self, flow) NetQueue__cancelFlowTimers(NetQueue(self), flow)
457
458void NetQueue__timerSweep(_In_ NetQueue* self);
459// void netqueue_timerSweep(NetQueue* self);
460//
461// Fire every timer whose deadline has passed. A no-op on one relaxed load while nothing is
462// armed. Entries are popped under timerLock and fired outside it, so a callback is free to arm,
463// cancel, or send. Called by every backend right after its wait returns, beside _maint().
464#define netqueue_timerSweep(self) NetQueue__timerSweep(NetQueue(self))
465
466int64 NetQueue__nextDeadline(_In_ NetQueue* self);
467// int64 netqueue_nextDeadline(NetQueue* self);
468//
469// The nearest armed deadline in absolute clockTimer() microseconds, or 0 if nothing is armed.
470// Backends cap their wait to this so a timer fires close to when it is due rather than on the
471// next unrelated wakeup.
472#define netqueue_nextDeadline(self) NetQueue__nextDeadline(NetQueue(self))
473
474_Ret_maybenull_ NetFlow* NetQueue__findFlow(_In_ NetQueue* self, _Inout_ NetSocket* sock, _In_ NetAddr* peer, bool create);
475// NetFlow* netqueue_findFlow(NetQueue* self, NetSocket* sock, NetAddr* peer, bool create);
476//
477// Flow table and lifecycle (flow.c)
478// Find the flow for a peer address, creating one if there is room under the cap. Returns a
479// strong reference the caller must release, or NULL if the queue is at its cap and nothing
480// could be reclaimed -- in which case the caller should fall back to the flowRefused handler.
481// A stream or QUIC socket has no address-keyed table, so `peer` is ignored there and the
482// socket's single control flow is returned.
483#define netqueue_findFlow(self, sock, peer, create) NetQueue__findFlow(NetQueue(self), sock, peer, create)
484
485_Ret_maybenull_ NetFlow* NetQueue__admitFlow(_In_ NetQueue* self, _Inout_ NetSocket* sock, _In_ NetAddr* peer);
486// NetFlow* netqueue_admitFlow(NetQueue* self, NetSocket* sock, NetAddr* peer);
487//
488// Create a flow for a peer and register it with the socket, bypassing the cap check. Returns a
489// strong reference the caller must release. A thin wrapper over _admitFlowObj below.
490#define netqueue_admitFlow(self, sock, peer) NetQueue__admitFlow(NetQueue(self), sock, peer)
491
492_Ret_maybenull_ NetFlow* NetQueue__admitFlowObj(_In_ NetQueue* self, _Inout_ NetSocket* sock, _Inout_ NetFlow* flow);
493// NetFlow* netqueue_admitFlowObj(NetQueue* self, NetSocket* sock, NetFlow* flow);
494//
495// Register an already-constructed flow with its socket: build its filter chain, publish it in
496// the socket's table (keyed on `peer` for a datagram socket, `key` for a QUIC one), count it
497// against the queue, queue its NET_FlowOpen ahead of anything else that could land in its
498// inbox, and prime the chain. Split out of _admitFlow so cxquic can register a NetFlow
499// subclass of its own for a QUIC stream.
500// // Consumes the caller's reference and returns the one to use, which is normally the same flow
501// -- but is the winner's flow when another thread inserted the same key first, and NULL if the
502// table lost it. Do not use `flow` after the call; use the return value.
503#define netqueue_admitFlowObj(self, sock, flow) NetQueue__admitFlowObj(NetQueue(self), sock, flow)
504
505uint32 NetQueue__reclaimFlows(_In_ NetQueue* self, _Inout_ NetSocket* sock);
506// uint32 netqueue_reclaimFlows(NetQueue* self, NetSocket* sock);
507//
508// Mark up to reclaimBatch least-recently-active flows on this socket for teardown, skipping
509// flows active more recently than reclaimMinIdle allows. Runs inline on the ingest path at the
510// moment of a cap hit; there is no timer thread.
511#define netqueue_reclaimFlows(self, sock) NetQueue__reclaimFlows(NetQueue(self), sock)
512
522#define netqueueAddSocket(self, socket) (self)->_->addSocket(NetQueue(self), socket)
532#define netqueueRemoveSocket(self, socket) (self)->_->removeSocket(NetQueue(self), socket)
541#define netqueueSocket(self, type) (self)->_->socket(NetQueue(self), type)
542// bool netqueueConnectBegin(NetQueue* self, NetSocket* sock, const NetAddr* addr);
543//
544// Begin one outbound connect attempt against a single resolved address
545// // The one backend-specific piece of connect. By the time this is called, the portable state
546// machine has already picked the address and armed the deadline; this just gets a fresh OS
547// handle of the address's family and starts the attempt. A readiness backend resets the
548// handle, issues a non-blocking connect(), and watches it for writability (and the except
549// set, where Windows signals a failed connect). A completion backend resets and binds the
550// handle and posts an overlapped ConnectEx.
551// // The outcome is reported back through netsocket_connectResult() -- immediately for a
552// synchronous result, or later from readiness, a completion, or the timeout sweep.
553// // @param sock Socket to connect (a stream socket in NS_Connecting)
554// @param addr Address to attempt
555// @return true if the attempt was initiated or resolved, false if it could not be started
556#define netqueueConnectBegin(self, sock, addr) (self)->_->connectBegin(NetQueue(self), sock, addr)
557// void netqueueConnectArm(NetQueue* self, NetSocket* sock);
558//
559// React to a socket having just become connected
560// // Called once, after a successful connect has transitioned the socket to NS_Connected and
561// its NET_Connection event has been queued. The backend starts servicing the socket for
562// receive here -- select rebuilds its watch set to read-watch it, IOCP posts the first
563// WSARecv -- the same thing addSocket() does for a socket that was already connected when it
564// joined the queue.
565// // @param sock Socket that just connected
566#define netqueueConnectArm(self, sock) (self)->_->connectArm(NetQueue(self), sock)
567// void netqueueAcceptArm(NetQueue* self, NetSocket* sock);
568//
569// Begin (or resume) accepting connections on a now-listening socket
570// // The accept-side counterpart of connectArm. Called once the socket enters NS_Listening --
571// from the platform listen(), or from addSocket() if the socket was already listening when
572// it joined the queue. A readiness backend wakes its loop so the next rebuild read-watches
573// the listener; a completion backend posts its initial batch of overlapped AcceptEx
574// operations. Each accepted connection is wrapped and handed to netsocket_accepted().
575// // @param sock Listening socket (a stream socket in NS_Listening)
576#define netqueueAcceptArm(self, sock) (self)->_->acceptArm(NetQueue(self), sock)
587#define netqueueShutdown(self, timeout) (self)->_->shutdown(NetQueue(self), timeout)
599#define netqueueTick(self, wait) (self)->_->tick(NetQueue(self), wait)
600
601CX_C_END
#define saDeclarePtr(name)
Definition sarray.h:100
void(* NetConnectPrepCB)(NetSocket *sock, void *ctx)
Definition net_shared.h:714
uint64 NetTimerId
Handle to an armed timer, unique for the lifetime of its queue.
Definition net_shared.h:210
NetSocketType
Socket types.
Definition net_shared.h:134
CX Struct System - Introspectable, serializable POD structures in C.
Threading system aggregated header.
CX Object System - Object-oriented programming in C.
Definition mutex.h:60
Network Event Structure.
Definition net_shared.h:600
A single ordering domain: one connection, or one datagram peer.
Definition flow.h:116
Set of event handlers, registered per flow, per socket, or queue-wide.
Definition net_shared.h:678
A received packet, as delivered to a handler.
Definition net_shared.h:361
Per-datagram information the IP layer carries alongside the payload.
Definition net_shared.h:328
Shared, capped pool of network message buffers and headers.
Definition pool.h:51
NetQueue manages one or more sockets and a thread pool of workers.
Definition queue.h:79
NetTimerEntry * timers
Armed timers across every flow on this queue, kept as a min-heap ordered by deadline.
Definition queue.h:130
PrQueue runq
Flows with work pending, waiting for a worker to claim them.
Definition queue.h:108
Weak(ObjInst) *handlerWeak
Context passed to queue-wide handlers, set by setHandlersObj() – NULL when handlerCtx is in use inste...
hashtable timerIdx
Maps a timer id to its current index in timers
Definition queue.h:134
void * sendCtx
Definition queue.h:155
atomic(uint32) shutdownReq
Set when shutdown begins, so ingest stops producing and addSocket is refused.
uint64 timerSerial
Source of NetTimerId values; never reused, never 0.
Definition queue.h:133
void * handlerCtx
Definition queue.h:96
NetQueueConfig conf
Definition queue.h:89
atomic(uint32) droppedNoBuf
Datagrams dropped for lack of a receive buffer.
atomic(uint32) timersLive
Number of armed timers, readable without taking timerLock
NetHandlers handlers
Queue-wide fallback handlers.
Definition queue.h:95
atomic(uint32) gcLastLo
Timestamp of the last opportunistic GC pass, used to rate-limit it.
hashtable sockets
Sockets this queue is managing, keyed by pointer identity.
Definition queue.h:101
RWLock lock
Definition queue.h:102
NetPool * pool
Shared, capped storage every NetMessage on this queue is drawn from.
Definition queue.h:114
NetWakeFn wake
Backend hook that wakes a parked wait so it can recompute its timeout.
Definition queue.h:160
atomic(uint32) nflows
Mutex timerLock
Guards the timer heap and every flow's list of armed timer ids.
Definition queue.h:138
uint32 timersCap
Entries allocated in timers
Definition queue.h:132
NetSendPumpFn sendPump
Backend hook invoked when the send path leaves outbound data queued on a socket.
Definition queue.h:154
sa_Thread workers
Dispatch worker threads draining the runqueue (empty in polled mode)
Definition queue.h:145
RWLock handlerLock
Guards handlers/handlerCtx/handlerWeak against a concurrent setHandlers()/setHandlersObj()
Definition queue.h:100
uint32 ntimers
Entries in use in timers
Definition queue.h:131
Semaphore runqSema
Posted once per flow enqueued; dispatch workers wait on it when the runqueue is dry.
Definition queue.h:146
void * wakeCtx
Context passed to wake, normally the derived queue.
Definition queue.h:161
Counting semaphore synchronization primitive.
Definition sema.h:46