Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ACCEPT_POOL: parallel accept pool for high-performance connection handling

Data Structures

struct  NETW_ACCEPT_POOL
 Structure of a parallel accept pool. More...
 
struct  NETW_ACCEPT_POOL_STATS
 Statistics for the accept pool. More...
 

Macros

#define netw_accept_pool_atomic_read_state(pool)   __atomic_load_n(&(pool)->state, __ATOMIC_ACQUIRE)
 Lock-free atomic read of the accept pool state.
 
#define netw_accept_pool_atomic_write_state(pool, val)   __atomic_store_n(&(pool)->state, (val), __ATOMIC_RELEASE)
 Lock-free atomic write of the accept pool state.
 
#define NETW_ACCEPT_POOL_IDLE   0
 accept pool state: idle, not yet started
 
#define NETW_ACCEPT_POOL_RUNNING   1
 accept pool state: running and accepting connections
 
#define NETW_ACCEPT_POOL_STOPPED   3
 accept pool state: fully stopped
 
#define NETW_ACCEPT_POOL_STOPPING   2
 accept pool state: stop requested
 

Typedefs

typedef void(* netw_accept_callback_t) (NETWORK *accepted, void *user_data)
 callback type for accepted connections.
 

Functions

NETW_ACCEPT_POOLnetw_accept_pool_create (NETWORK *server, size_t nb_threads, int accept_timeout, netw_accept_callback_t callback, void *user_data)
 Create a new accept pool.
 
int netw_accept_pool_destroy (NETW_ACCEPT_POOL **pool)
 Destroy an accept pool.
 
int netw_accept_pool_get_stats (NETW_ACCEPT_POOL *pool, NETW_ACCEPT_POOL_STATS *stats)
 Get a snapshot of pool statistics (thread-safe copy)
 
int netw_accept_pool_start (NETW_ACCEPT_POOL *pool)
 Start the accept pool (launches accept threads)
 
int netw_accept_pool_stop (NETW_ACCEPT_POOL *pool)
 Request the accept pool to stop.
 
int netw_accept_pool_wait (NETW_ACCEPT_POOL *pool, int timeout_sec)
 Wait for all accept threads to finish after a stop request.
 

Detailed Description

Overview

The accept pool provides nginx-style parallel connection acceptance: multiple threads call accept() on the same listening socket, each invoking a user callback for every accepted connection.

Server Architecture Modes

There are three common ways to structure a server's accept + handling logic. Each has different performance characteristics depending on the workload:

Single-inline: accept + handle in one thread

One thread does accept() and handles the client inline before accepting the next connection. Both accept and handling are fully serialized.

Single-pool: one accept thread + worker thread pool

One thread calls accept() and dispatches each connection to a worker thread pool for handling. Accept is serialized but handling is parallelized.

Pooled: N accept threads + worker thread pool

Multiple threads call accept() on the same listening socket (nginx-style), each dispatching to a worker thread pool. Both accept and handling are parallelized.

Performance Considerations

On localhost (loopback), accept() is near-instant (nanoseconds). A single accept thread can drain the kernel queue faster than clients can fill it. Adding more accept threads introduces kernel socket lock contention and context switches without benefit — single-pool will often outperform pooled mode in this case.

The pooled accept advantage appears when:

The example programs (ex_accept_pool_server, ex_accept_pool_client, test_accept_pool.sh) demonstrate all three modes with configurable parameters for benchmarking.


Data Structure Documentation

◆ NETW_ACCEPT_POOL

struct NETW_ACCEPT_POOL

Structure of a parallel accept pool.

Examples
ex_accept_pool_server.c.

Definition at line 135 of file n_network_accept_pool.h.

+ Collaboration diagram for NETW_ACCEPT_POOL:
Data Fields
pthread_t * accept_threads array of pthread ids
int accept_timeout accept timeout in milliseconds (passed to netw_accept_from_ex blocking param).

0 = blocking, -1 = non-blocking, >0 = timeout in msec

netw_accept_callback_t callback user callback invoked on each accepted connection
size_t nb_accept_threads number of accept threads
NETWORK * server listening socket (not owned, caller must keep alive)
uint32_t state atomic pool state
NETW_ACCEPT_POOL_STATS stats pool statistics
pthread_mutex_t stats_lock mutex protecting stats
void * user_data opaque user data passed to callback

◆ NETW_ACCEPT_POOL_STATS

struct NETW_ACCEPT_POOL_STATS

Statistics for the accept pool.

Examples
ex_accept_pool_server.c.

Definition at line 121 of file n_network_accept_pool.h.

+ Collaboration diagram for NETW_ACCEPT_POOL_STATS:
Data Fields
size_t active_threads number of accept threads currently running
struct timespec start_time time when pool was started (CLOCK_MONOTONIC)
size_t total_accepted total connections successfully accepted
size_t total_errors total accept errors
size_t total_timeouts total accept timeouts (no connection available)

Macro Definition Documentation

◆ netw_accept_pool_atomic_read_state

#define netw_accept_pool_atomic_read_state (   pool)    __atomic_load_n(&(pool)->state, __ATOMIC_ACQUIRE)

Lock-free atomic read of the accept pool state.

Definition at line 158 of file n_network_accept_pool.h.

◆ netw_accept_pool_atomic_write_state

#define netw_accept_pool_atomic_write_state (   pool,
  val 
)    __atomic_store_n(&(pool)->state, (val), __ATOMIC_RELEASE)

Lock-free atomic write of the accept pool state.

Definition at line 161 of file n_network_accept_pool.h.

◆ NETW_ACCEPT_POOL_IDLE

#define NETW_ACCEPT_POOL_IDLE   0

accept pool state: idle, not yet started

Definition at line 106 of file n_network_accept_pool.h.

◆ NETW_ACCEPT_POOL_RUNNING

#define NETW_ACCEPT_POOL_RUNNING   1

accept pool state: running and accepting connections

Definition at line 108 of file n_network_accept_pool.h.

◆ NETW_ACCEPT_POOL_STOPPED

#define NETW_ACCEPT_POOL_STOPPED   3

accept pool state: fully stopped

Definition at line 112 of file n_network_accept_pool.h.

◆ NETW_ACCEPT_POOL_STOPPING

#define NETW_ACCEPT_POOL_STOPPING   2

accept pool state: stop requested

Definition at line 110 of file n_network_accept_pool.h.

Typedef Documentation

◆ netw_accept_callback_t

typedef void(* netw_accept_callback_t) (NETWORK *accepted, void *user_data)

callback type for accepted connections.

Parameters
acceptedthe newly accepted NETWORK connection (caller takes ownership)
user_dataopaque pointer passed at pool creation

Definition at line 118 of file n_network_accept_pool.h.

Function Documentation

◆ netw_accept_pool_create()

NETW_ACCEPT_POOL * netw_accept_pool_create ( NETWORK server,
size_t  nb_threads,
int  accept_timeout,
netw_accept_callback_t  callback,
void *  user_data 
)

Create a new accept pool.

Parameters
serverlistening NETWORK (must already be listening)
nb_threadsnumber of accept threads
accept_timeouttimeout in msec for accept (0=blocking, -1=nonblocking, >0=timeout ms)
callbackfunction called for each accepted connection
user_dataopaque pointer passed to callback
Returns
new NETW_ACCEPT_POOL or NULL on error

Definition at line 110 of file n_network_accept_pool.c.

References __n_assert, Free, LOG_ERR, Malloc, n_log, netw_accept_pool_atomic_write_state, NETW_ACCEPT_POOL_IDLE, pool, and server.

Referenced by main().

+ Here is the caller graph for this function:

◆ netw_accept_pool_destroy()

int netw_accept_pool_destroy ( NETW_ACCEPT_POOL **  pool)

Destroy an accept pool.

Pool must be stopped first.

Pool must be stopped first.

Parameters
poolpointer to the accept pool pointer (set to NULL)
Returns
TRUE on success, FALSE on error

Definition at line 267 of file n_network_accept_pool.c.

References __n_assert, Free, LOG_WARNING, n_log, netw_accept_pool_atomic_read_state, NETW_ACCEPT_POOL_RUNNING, netw_accept_pool_stop(), NETW_ACCEPT_POOL_STOPPING, netw_accept_pool_wait(), and pool.

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ netw_accept_pool_get_stats()

int netw_accept_pool_get_stats ( NETW_ACCEPT_POOL pool,
NETW_ACCEPT_POOL_STATS stats 
)

Get a snapshot of pool statistics (thread-safe copy)

Get a snapshot of pool statistics (thread-safe copy)

Parameters
poolthe accept pool
statsoutput structure to fill
Returns
TRUE on success, FALSE on error

Definition at line 251 of file n_network_accept_pool.c.

References __n_assert, and pool.

Referenced by main().

+ Here is the caller graph for this function:

◆ netw_accept_pool_start()

int netw_accept_pool_start ( NETW_ACCEPT_POOL pool)

Start the accept pool (launches accept threads)

Parameters
poolthe accept pool to start
Returns
TRUE on success, FALSE on error

Definition at line 155 of file n_network_accept_pool.c.

References __n_assert, LOG_ERR, LOG_NOTICE, n_log, netw_accept_pool_atomic_read_state, netw_accept_pool_atomic_write_state, NETW_ACCEPT_POOL_IDLE, NETW_ACCEPT_POOL_RUNNING, NETW_ACCEPT_POOL_STOPPED, NETW_ACCEPT_POOL_STOPPING, netw_accept_pool_thread_func(), and pool.

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ netw_accept_pool_stop()

int netw_accept_pool_stop ( NETW_ACCEPT_POOL pool)

Request the accept pool to stop.

Non-blocking, threads will finish current accept and exit.

Parameters
poolthe accept pool to stop
Returns
TRUE on success, FALSE on error

Definition at line 195 of file n_network_accept_pool.c.

References __n_assert, LOG_NOTICE, LOG_WARNING, n_log, netw_accept_pool_atomic_read_state, netw_accept_pool_atomic_write_state, NETW_ACCEPT_POOL_RUNNING, NETW_ACCEPT_POOL_STOPPING, and pool.

Referenced by main(), netw_accept_pool_destroy(), and netw_accept_pool_wait().

+ Here is the caller graph for this function:

◆ netw_accept_pool_wait()

int netw_accept_pool_wait ( NETW_ACCEPT_POOL pool,
int  timeout_sec 
)

Wait for all accept threads to finish after a stop request.

Parameters
poolthe accept pool to wait on
timeout_secmaximum seconds to wait (0 = wait forever)
Returns
TRUE if all threads joined, FALSE on timeout or error

Definition at line 221 of file n_network_accept_pool.c.

References __n_assert, LOG_NOTICE, LOG_WARNING, n_log, netw_accept_pool_atomic_read_state, netw_accept_pool_atomic_write_state, NETW_ACCEPT_POOL_IDLE, NETW_ACCEPT_POOL_RUNNING, netw_accept_pool_stop(), NETW_ACCEPT_POOL_STOPPED, and pool.

Referenced by main(), and netw_accept_pool_destroy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: