CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
Queue

Data Structures

struct  NetQueue
 NetQueue manages one or more sockets and a thread pool of workers. More...
 

Macros

#define netqueuePresetClient(conf)   NetQueue_presetClient(conf)
 
#define netqueuePresetServer(conf)   NetQueue_presetServer(conf)
 
#define netqueueConnect(self, host, port, handlers, ctx)   NetQueue_connect(NetQueue(self), host, port, handlers, ctx)
 
#define netqueueConnectPrep(self, host, port, handlers, ctx, prep, prepctx)   NetQueue_connectPrep(NetQueue(self), host, port, handlers, ctx, prep, prepctx)
 
#define netqueueListen(self, addr, backlog, handlers, ctx)   NetQueue_listen(NetQueue(self), addr, backlog, handlers, ctx)
 
#define netqueueSetHandlers(self, handlers, ctx)   NetQueue_setHandlers(NetQueue(self), handlers, ctx)
 
#define netqueueSetHandlersObj(self, handlers, ctx)   NetQueue_setHandlersObj(NetQueue(self), handlers, ObjInst(ctx))
 
#define netqueuePromoteFlow(self, sock, peer)   NetQueue_promoteFlow(NetQueue(self), sock, peer)
 
#define netqueueDroppedNoBuf(self)   NetQueue_droppedNoBuf(NetQueue(self))
 
#define netqueueAddSocket(self, socket)   (self)->_->addSocket(NetQueue(self), socket)
 
#define netqueueRemoveSocket(self, socket)   (self)->_->removeSocket(NetQueue(self), socket)
 
#define netqueueSocket(self, type)   (self)->_->socket(NetQueue(self), type)
 
#define netqueueShutdown(self, timeout)   (self)->_->shutdown(NetQueue(self), timeout)
 
#define netqueueTick(self, wait)   (self)->_->tick(NetQueue(self), wait)
 

Typedefs

typedef struct NetQueue NetQueue
 NetQueue manages one or more sockets and a thread pool of workers.
 

Functions

NetQueuenetqueueCreate (const NetQueueConfig *conf)
 

Detailed Description

NetQueue is an abstraction for servicing one or more sockets using platform-specific backends. Sockets can be added to a queue to handle I/O operations efficiently. The queue can be operated in single-threaded polled mode or with a pool of worker threads for asynchronous operation.

Macro Definition Documentation

◆ netqueueAddSocket

#define netqueueAddSocket (   self,
  socket 
)    (self)->_->addSocket(NetQueue(self), socket)

bool netqueueAddSocket(NetQueue* self, NetSocket* socket);

Add a socket to be managed by the queue

The socket must be compatible with the NetQueue implementation. The netqueueSocket() factory can be used to create compatible sockets.

Parameters
socketSocket to add to the queue
Returns
true if the socket was successfully added, false otherwise

Definition at line 522 of file queue.h.

◆ netqueueConnect

#define netqueueConnect (   self,
  host,
  port,
  handlers,
  ctx 
)    NetQueue_connect(NetQueue(self), host, port, handlers, ctx)

NetSocket* netqueueConnect(NetQueue* self, strref host, uint16 port, const NetHandlers* handlers, void* ctx);

Create a stream socket on the queue and start connecting it, in one call

Composes the whole client setup – netqueueSocket(), netqueueAddSocket(), handler registration, and netsocketConnect() – so a single outbound connection is one call instead of four. Handlers are registered before the connect begins, so the NET_Connection event cannot slip past. Purely a convenience over the public API; use the individual calls when the socket needs configuration between the steps.

Parameters
hostHostname or literal address to connect to (NULL/empty means loopback)
portPort number, host byte order
handlersPer-socket handler overrides, or NULL for none. Not copied – must outlive the socket, so it is usually static const
ctxContext passed to these handlers on NetEvent.ctx
Returns
The connecting socket (a reference the caller must release), or NULL if any step failed – nothing is left registered on the queue in that case

Example:

static const NetHandlers handlers = { .connection = onConn, .recv = onRecv };
NetSocket* s = netqueueConnect(q, _SL("example.com"), 443, &handlers, &state);
#define netqueueConnect(self, host, port, handlers, ctx)
Definition queue.h:224
#define _SL(s)
Inline ASCII string literal with compile-time embedded length (STR_LEN8). Content must be < 200 bytes...
Definition strliteral.h:207
Set of event handlers, registered per flow, per socket, or queue-wide.
Definition net_shared.h:678
NetEventCB connection
NET_Connection: established, failed, or state changed.
Definition net_shared.h:679

Definition at line 224 of file queue.h.

◆ netqueueConnectPrep

#define netqueueConnectPrep (   self,
  host,
  port,
  handlers,
  ctx,
  prep,
  prepctx 
)    NetQueue_connectPrep(NetQueue(self), host, port, handlers, ctx, prep, prepctx)

NetSocket* netqueueConnectPrep(NetQueue* self, strref host, uint16 port, const NetHandlers* handlers, void* ctx, NetConnectPrepCB prep, void* prepctx);

Create a stream socket, hand it over, and start connecting it, in one call

netqueueConnect() with one addition: prep is called with the finished socket immediately before the connect begins. Use it when the socket has to be reachable from somewhere else – a request, a session, a cancel path – before its first event can arrive, which the return value is too late for: the connect can complete on another thread while this call is still returning.

A NULL return means nothing was started. Anything prep stored is the caller's to clean up.

Parameters
hostHostname or literal address to connect to (NULL/empty means loopback)
portPort number, host byte order
handlersPer-socket handler overrides, or NULL for none. Not copied – must outlive the socket, so it is usually static const
ctxContext passed to these handlers on NetEvent.ctx
prepCalled with the socket just before it connects, or NULL for none
prepctxContext passed to prep
Returns
The connecting socket (a reference the caller must release), or NULL if any step failed – nothing is left registered on the queue in that case

Example:

NetSocket* s = netqueueConnectPrep(q, _SL("example.com"), 443, &handlers, &state,
publishSock, &state);
#define netqueueConnectPrep(self, host, port, handlers, ctx, prep, prepctx)
Definition queue.h:254

Definition at line 254 of file queue.h.

◆ netqueueDroppedNoBuf

#define netqueueDroppedNoBuf (   self)    NetQueue_droppedNoBuf(NetQueue(self))

uint32 netqueueDroppedNoBuf(NetQueue* self);

Datagrams dropped for lack of a receive buffer

A silent drop is indistinguishable from a network problem. A counter that is nonzero turns "the network is flaky" into "the pool is too small or a callback is too slow" immediately, so this is worth logging at whatever cadence the application already has.

Returns
Monotonic count of dropped datagrams since the queue was created

Definition at line 336 of file queue.h.

◆ netqueueListen

#define netqueueListen (   self,
  addr,
  backlog,
  handlers,
  ctx 
)    NetQueue_listen(NetQueue(self), addr, backlog, handlers, ctx)

NetSocket* netqueueListen(NetQueue* self, const NetAddr* addr, int backlog, const NetHandlers* handlers, void* ctx);

Create a stream socket on the queue and start it listening, in one call

The accept-side counterpart of netqueueConnect(): composes netqueueSocket(), netqueueAddSocket(), handler registration, netsocketBind(), and netsocketListen(). Incoming connections arrive as NET_Accepted events on the listener; with NQ_AutoAccept set on the queue they are registered with it automatically.

Parameters
addrLocal address to bind (port 0 lets the OS pick one)
backlogListen backlog, or 0 for a platform-specific default
handlersPer-socket handler overrides, or NULL for none. Not copied – must outlive the socket, so it is usually static const
ctxContext passed to these handlers on NetEvent.ctx
Returns
The listening socket (a reference the caller must release), or NULL if any step failed – nothing is left registered on the queue in that case

Example:

static const NetHandlers handlers = { .accepted = onAccept };
netAddrFromStr(&la, _SL("0.0.0.0"));
la.port = 8080;
NetSocket* s = netqueueListen(q, &la, 0, &handlers, &state);
bool netAddrFromStr(NetAddr *addr, strref str)
#define netqueueListen(self, addr, backlog, handlers, ctx)
Definition queue.h:282
uint16 port
Port number.
Definition net_shared.h:290
NetEventCB accepted
NET_Accepted: new incoming connection.
Definition net_shared.h:681

Definition at line 282 of file queue.h.

◆ netqueuePresetClient

#define netqueuePresetClient (   conf)    NetQueue_presetClient(conf)

void netqueuePresetClient(NetQueueConfig* conf);

Fill in a configuration suited to a client or a single connection

Polled mode, a small buffer pool, and few flows. Nothing here starts a thread, so a program that drives its own loop with netqueueTick() never spawns one.

Parameters
confConfiguration structure to populate

Definition at line 187 of file queue.h.

◆ netqueuePresetServer

#define netqueuePresetServer (   conf)    NetQueue_presetServer(conf)

void netqueuePresetServer(NetQueueConfig* conf);

Fill in a configuration suited to a server

A worker pool sized to the machine, a large buffer pool, and a high flow cap. Suitable as-is for a process multiplexing many peers over a single datagram socket.

Parameters
confConfiguration structure to populate

Definition at line 198 of file queue.h.

◆ netqueuePromoteFlow

#define netqueuePromoteFlow (   self,
  sock,
  peer 
)    NetQueue_promoteFlow(NetQueue(self), sock, peer)

NetFlow* netqueuePromoteFlow(NetQueue* self, NetSocket* sock, const NetAddr* peer);

Admit a peer that was refused by the flow cap

Called from a NET_FlowRefused handler once the application has validated the packet – completed a handshake, checked a crypto negotiation, whatever its protocol requires. This is what makes a public datagram port safe: past the cap the queue stops allocating on its own and hands raw packets to code that already knows how to tell a real client from a flood. The admitted flow fires NET_FlowOpen like any other, ordered ahead of its first packet.

Parameters
sockSocket the packet arrived on
peerSource address to admit
Returns
The new flow (a reference the caller must release), or NULL if there is still no room

Definition at line 324 of file queue.h.

◆ netqueueRemoveSocket

#define netqueueRemoveSocket (   self,
  socket 
)    (self)->_->removeSocket(NetQueue(self), socket)

bool netqueueRemoveSocket(NetQueue* self, NetSocket* socket);

Remove a socket from the queue, usually when the socket is closed

For some implementations this will also attempt to cancel pending I/O requests that reference the socket's owned buffers.

Parameters
socketSocket to remove from the queue
Returns
true if the socket was successfully removed, false otherwise

Definition at line 532 of file queue.h.

◆ netqueueSetHandlers

#define netqueueSetHandlers (   self,
  handlers,
  ctx 
)    NetQueue_setHandlers(NetQueue(self), handlers, ctx)

void netqueueSetHandlers(NetQueue* self, const NetHandlers* handlers, void* ctx);

Register the queue-wide fallback handlers

This is the last level of the per-field fallthrough described in Event Handlers, and is generally the right place for logging and error handling. The handler struct is not copied – it must outlive the queue, which is why it is usually static const.

Parameters
handlersHandler set, or NULL to clear
ctxContext passed to these handlers on NetEvent.ctx

Definition at line 295 of file queue.h.

◆ netqueueSetHandlersObj

#define netqueueSetHandlersObj (   self,
  handlers,
  ctx 
)    NetQueue_setHandlersObj(NetQueue(self), handlers, ObjInst(ctx))

void netqueueSetHandlersObj(NetQueue* self, const NetHandlers* handlers, ObjInst* ctx);

Register the queue-wide fallback handlers, with an object as the context

Same as setHandlers(), except ctx is held weakly rather than borrowed.

Parameters
handlersHandler set, or NULL to clear
ctxObject passed to these handlers on NetEvent.ctx, held weakly; NULL to clear

Definition at line 306 of file queue.h.

◆ netqueueShutdown

#define netqueueShutdown (   self,
  timeout 
)    (self)->_->shutdown(NetQueue(self), timeout)

bool netqueueShutdown(NetQueue* self, int64 timeout);

Shut down the queue

Removes all sockets from the queue and shuts down worker threads. Will shut down the queue in the background even if false is returned.

Parameters
timeoutHow long to wait for workers to terminate, in microseconds (see timeS() / timeMS()), or 0 or less to wait forever
Returns
true if the queue is fully shut down

Definition at line 587 of file queue.h.

◆ netqueueSocket

#define netqueueSocket (   self,
  type 
)    (self)->_->socket(NetQueue(self), type)

NetSocket* netqueueSocket(NetQueue* self, NetSocketType type);

Factory for creating sockets

This does NOT add the socket to the queue.

Parameters
typeType of socket to create (connection-oriented or connectionless)
Returns
Newly created socket, or NULL on failure

Definition at line 541 of file queue.h.

◆ netqueueTick

#define netqueueTick (   self,
  wait 
)    (self)->_->tick(NetQueue(self), wait)

bool netqueueTick(NetQueue* self, int64 wait);

Process events in polled mode

Only for a queue created with nthreads set to 0. A queue with worker threads already does this work on its own threads, and calling tick() on one puts two threads in the same place.

Parameters
waitHow long to wait for an event, in microseconds (see timeS() / timeMS()), 0 to return immediately, or timeForever to wait until something happens. A wait of under a millisecond is rounded up to one on some platforms, so treat it as a lower bound.
Returns
true if any events were processed, false if the wait timeout was reached

Definition at line 599 of file queue.h.

Function Documentation

◆ netqueueCreate()

NetQueue * netqueueCreate ( const NetQueueConfig conf)

Create a network queue

Parameters
confCreation configuration; start from a preset and override what you need
Returns
Pointer to the created NetQueue (must be released with objRelease)
Note
If the select() backend is being used with a thread pool, one additional thread will be created to handle the select() loop.

Example:

conf.maxflows = 50000;
NetQueue * netqueueCreate(const NetQueueConfig *conf)
#define netqueuePresetServer(conf)
Definition queue.h:198
uint32 maxflows
Cap on concurrent flows across the queue (0 = unlimited)
Definition net_shared.h:66
NetQueue manages one or more sockets and a thread pool of workers.
Definition queue.h:79