The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Data Structures | Macros | Typedefs | Functions | Variables
trunk.c File Reference

A management API for bonding multiple connections together. More...

#include <freeradius-devel/server/trunk.h>
#include <freeradius-devel/server/connection.h>
#include <freeradius-devel/server/trigger.h>
#include <freeradius-devel/util/misc.h>
#include <freeradius-devel/util/syserror.h>
#include <freeradius-devel/util/table.h>
#include <freeradius-devel/util/minmax_heap.h>
#include <freeradius-devel/util/stdatomic.h>
+ Include dependency graph for trunk.c:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  fr_trunk_connection_s
 Associates request queues with a connection. More...
 
struct  fr_trunk_request_s
 Wraps a normal request. More...
 
struct  fr_trunk_request_state_log_t
 Trace state machine changes for a particular request. More...
 
struct  fr_trunk_s
 Main trunk management handle. More...
 
struct  fr_trunk_watch_entry_s
 An entry in a trunk watch function list. More...
 

Macros

#define _TRUNK_PRIVATE   1
 
#define CALL_WATCHERS(_trunk, _state)
 Call the state change watch functions. More...
 
#define CONN_BAD_STATE_TRANSITION(_new)
 
#define CONN_REORDER(_tconn)
 Reorder the connections in the active heap. More...
 
#define CONN_STATE_TRANSITION(_new, _log)
 
#define CONN_TRIGGER(_state)
 
#define COUNT_BY_STATE(_state, _list)
 
#define DEQUEUE_ALL(_src_list, _state)
 
#define DO_CONNECTION_ALLOC(_tconn)
 Allocate a new connection. More...
 
#define DO_CONNECTION_NOTIFY(_tconn, _events)
 Change what events the connection should be notified about. More...
 
#define DO_REQUEST_CANCEL(_treq, _reason)
 Call the cancel callback if set. More...
 
#define DO_REQUEST_CANCEL_MUX(_tconn)
 Write one or more cancellation requests to a connection. More...
 
#define DO_REQUEST_COMPLETE(_treq)
 Call the complete callback (if set) More...
 
#define DO_REQUEST_CONN_RELEASE(_treq)
 Call the "conn_release" callback (if set) More...
 
#define DO_REQUEST_DEMUX(_tconn)
 Read one or more requests from a connection. More...
 
#define DO_REQUEST_FAIL(_treq, _prev_state)
 Call the fail callback (if set) More...
 
#define DO_REQUEST_FREE(_treq)
 Call the free callback (if set) More...
 
#define DO_REQUEST_MUX(_tconn)
 Write one or more requests to a connection. More...
 
#define FR_TRUNK_REQUEST_STATE_LOG_MAX   20
 The maximum number of state logs to record per request. More...
 
#define IN_HANDLER(_trunk)   (((_trunk)->in_handler) != NULL)
 
#define IN_REQUEST_CANCEL_MUX(_trunk)   (((_trunk)->funcs.request_cancel_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_cancel_mux))
 
#define IN_REQUEST_DEMUX(_trunk)   (((_trunk)->funcs.request_demux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_demux))
 
#define IN_REQUEST_MUX(_trunk)   (((_trunk)->funcs.request_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_mux))
 
#define IO_FUNC_VERIFY(_func)    fr_fatal_assert_msg(trunk->funcs._func, "CONSISTENCY_CHECK_FAILED %s[%i}: " #_func " was NULL", file, line)
 
#define IS_PROCESSING(_tconn)   ((tconn)->pub.state & FR_TRUNK_CONN_PROCESSING)
 
#define IS_SERVICEABLE(_tconn)   ((_tconn)->pub.state & FR_TRUNK_CONN_SERVICEABLE)
 
#define LOG_PREFIX   trunk->log_prefix
 
#define OVER_MAX_CHECK   if (++count > max) return (count - 1)
 
#define RECONNECT_BY_STATE(_state, _list)
 
#define REQUEST_BAD_STATE_TRANSITION(_new)
 
#define REQUEST_EXTRACT_BACKLOG(_treq)
 Remove the current request from the backlog. More...
 
#define REQUEST_EXTRACT_CANCEL(_treq)   fr_dlist_remove(&tconn->cancel, treq)
 Remove the current request from the cancel list. More...
 
#define REQUEST_EXTRACT_CANCEL_PARTIAL(_treq)
 Remove the current request from the cancel_partial slot. More...
 
#define REQUEST_EXTRACT_CANCEL_SENT(_treq)   fr_dlist_remove(&tconn->cancel_sent, treq)
 Remove the current request from the cancel sent list. More...
 
#define REQUEST_EXTRACT_PARTIAL(_treq)
 Remove the current request from the partial slot. More...
 
#define REQUEST_EXTRACT_PENDING(_treq)
 Remove the current request from the pending list. More...
 
#define REQUEST_EXTRACT_SENT(_treq)   fr_dlist_remove(&tconn->sent, treq)
 Remove the current request from the sent list. More...
 
#define REQUEST_STATE_TRANSITION(_new)
 Record a request state transition and log appropriate output. More...
 
#define REQUEST_TRIGGER(_state)
 
#define TCONN_DLIST_SEARCH(_dlist)
 
#define TCONN_DLIST_VERIFY(_dlist, _state)
 
#define TCONN_MINMAX_HEAP_SEARCH(_heap)
 
#define TCONN_MINMAX_HEAP_VERIFY(_heap, _state)
 
#define TCONN_TREQ_CHECKS(_treq, _state)
 
#define TREQ_DLIST_SEARCH(_dlist)
 
#define TREQ_DLIST_VERIFY(_dlist, _state)
 
#define TREQ_HEAP_SEARCH(_heap)
 
#define TREQ_HEAP_VERIFY(_heap, _state)
 
#define TREQ_OPTION_SEARCH(_option)
 
#define TREQ_OPTION_VERIFY(_option, _state)
 
#define TRUNK_STATE_TRANSITION(_new)
 
#define TRUNK_TCONN_CHECKS(_tconn, _state)
 

Typedefs

typedef struct fr_trunk_connection_s fr_trunk_connection_t
 
typedef struct fr_trunk_request_s fr_trunk_request_t
 
typedef struct fr_trunk_s fr_trunk_t
 
typedef struct fr_trunk_watch_entry_s fr_trunk_watch_entry_t
 An entry in a trunk watch function list. More...
 

Functions

static int _state_log_entry_free (fr_trunk_request_state_log_t *slog)
 Used for sanity checks to ensure all log entries have been freed. More...
 
static int _trunk_connection_free (fr_trunk_connection_t *tconn)
 Free a connection. More...
 
static void _trunk_connection_lifetime_expire (UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
 Trigger a reconnection of the trunk connection. More...
 
static void _trunk_connection_on_closed (UNUSED fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_connection_state_t state, void *uctx)
 Connection failed after it was connected. More...
 
static void _trunk_connection_on_connected (UNUSED fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_connection_state_t state, void *uctx)
 Connection transitioned to the connected state. More...
 
static void _trunk_connection_on_connecting (UNUSED fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_connection_state_t state, void *uctx)
 Connection transitioned to the connecting state. More...
 
static void _trunk_connection_on_failed (fr_connection_t *conn, fr_connection_state_t prev, fr_connection_state_t state, void *uctx)
 Connection failed. More...
 
static void _trunk_connection_on_halted (UNUSED fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_connection_state_t state, void *uctx)
 Connection transitioned to the halted state. More...
 
static void _trunk_connection_on_init (UNUSED fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_connection_state_t state, void *uctx)
 Connection transitioned to the the init state. More...
 
static void _trunk_connection_on_shutdown (UNUSED fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_connection_state_t state, void *uctx)
 Connection transitioned to the shutdown state. More...
 
static int8_t _trunk_connection_order_by_shortest_queue (void const *one, void const *two)
 Order connections by queue depth. More...
 
static int _trunk_free (fr_trunk_t *trunk)
 Free a trunk, gracefully closing all connections. More...
 
static int _trunk_request_free (fr_trunk_request_t *treq)
 Actually free the trunk request. More...
 
static int8_t _trunk_request_prioritise (void const *a, void const *b)
 Compare two protocol requests. More...
 
static void _trunk_timer (fr_event_list_t *el, fr_time_t now, void *uctx)
 Event to periodically call the connection management function. More...
 
fr_trunk_watch_entry_tfr_trunk_add_watch (fr_trunk_t *trunk, fr_trunk_state_t state, fr_trunk_watch_t watch, bool oneshot, void const *uctx)
 Add a watch entry to the trunk state list. More...
 
fr_trunk_tfr_trunk_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, fr_trunk_io_funcs_t const *funcs, fr_trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start)
 Allocate a new collection of connections. More...
 
void fr_trunk_connection_callback_readable (UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
 Standard I/O read function. More...
 
void fr_trunk_connection_callback_writable (UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
 Standard I/O write function. More...
 
uint16_t fr_trunk_connection_count_by_state (fr_trunk_t *trunk, int conn_state)
 Return the count number of connections in the specified states. More...
 
bool fr_trunk_connection_in_state (fr_trunk_connection_t *tconn, int state)
 Returns true if the trunk connection is in one of the specified states. More...
 
int fr_trunk_connection_manage_schedule (fr_trunk_t *trunk)
 Schedule a trunk management event for the next time the event loop is executed. More...
 
void fr_trunk_connection_manage_start (fr_trunk_t *trunk)
 Allow the trunk to open and close connections in response to load. More...
 
void fr_trunk_connection_manage_stop (fr_trunk_t *trunk)
 Stop the trunk from opening and closing connections in response to load. More...
 
int fr_trunk_connection_pop_cancellation (fr_trunk_request_t **treq_out, fr_trunk_connection_t *tconn)
 Pop a cancellation request off a connection's cancellation queue. More...
 
int fr_trunk_connection_pop_request (fr_trunk_request_t **treq_out, fr_trunk_connection_t *tconn)
 Pop a request off a connection's pending queue. More...
 
uint64_t fr_trunk_connection_requests_requeue (fr_trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound)
 Move requests off of a connection and requeue elsewhere. More...
 
bool fr_trunk_connection_search (fr_trunk_connection_t *tconn, void *ptr)
 
void fr_trunk_connection_signal_active (fr_trunk_connection_t *tconn)
 Signal a trunk connection is no longer full. More...
 
void fr_trunk_connection_signal_inactive (fr_trunk_connection_t *tconn)
 Signal a trunk connection cannot accept more requests. More...
 
void fr_trunk_connection_signal_readable (fr_trunk_connection_t *tconn)
 Signal that a trunk connection is readable. More...
 
void fr_trunk_connection_signal_reconnect (fr_trunk_connection_t *tconn, fr_connection_reason_t reason)
 Signal a trunk connection is no longer viable. More...
 
void fr_trunk_connection_signal_writable (fr_trunk_connection_t *tconn)
 Signal that a trunk connection is writable. More...
 
void fr_trunk_connection_verify (char const *file, int line, fr_trunk_connection_t *tconn)
 
int fr_trunk_del_watch (fr_trunk_t *trunk, fr_trunk_state_t state, fr_trunk_watch_t watch)
 Remove a watch function from a trunk state list. More...
 
void fr_trunk_reconnect (fr_trunk_t *trunk, int states, fr_connection_reason_t reason)
 Force the trunk to re-establish its connections. More...
 
fr_trunk_request_tfr_trunk_request_alloc (fr_trunk_t *trunk, request_t *request)
 (Pre-)Allocate a new trunk request More...
 
uint32_t fr_trunk_request_count_by_connection (fr_trunk_connection_t const *tconn, int req_state)
 Return the count number of requests associated with a trunk connection. More...
 
uint64_t fr_trunk_request_count_by_state (fr_trunk_t *trunk, int conn_state, int req_state)
 Return a count of requests on a connection in a specific state. More...
 
fr_trunk_enqueue_t fr_trunk_request_enqueue (fr_trunk_request_t **treq_out, fr_trunk_t *trunk, request_t *request, void *preq, void *rctx)
 Enqueue a request that needs data written to the trunk. More...
 
fr_trunk_enqueue_t fr_trunk_request_enqueue_on_conn (fr_trunk_request_t **treq_out, fr_trunk_connection_t *tconn, request_t *request, void *preq, void *rctx, bool ignore_limits)
 Enqueue additional requests on a specific connection. More...
 
void fr_trunk_request_free (fr_trunk_request_t **treq_to_free)
 If the trunk request is freed then update the target requests. More...
 
fr_trunk_enqueue_t fr_trunk_request_requeue (fr_trunk_request_t *treq)
 Re-enqueue a request on the same connection. More...
 
bool fr_trunk_request_search (fr_trunk_request_t *treq, void *ptr)
 
void fr_trunk_request_signal_cancel (fr_trunk_request_t *treq)
 Cancel a trunk request. More...
 
void fr_trunk_request_signal_cancel_complete (fr_trunk_request_t *treq)
 Signal that a remote server acked our cancellation. More...
 
void fr_trunk_request_signal_cancel_partial (fr_trunk_request_t *treq)
 Signal a partial cancel write. More...
 
void fr_trunk_request_signal_cancel_sent (fr_trunk_request_t *treq)
 Signal that a remote server has been notified of the cancellation. More...
 
void fr_trunk_request_signal_complete (fr_trunk_request_t *treq)
 Signal that a trunk request is complete. More...
 
void fr_trunk_request_signal_fail (fr_trunk_request_t *treq)
 Signal that a trunk request failed. More...
 
void fr_trunk_request_signal_partial (fr_trunk_request_t *treq)
 Signal a partial write. More...
 
void fr_trunk_request_signal_sent (fr_trunk_request_t *treq)
 Signal that the request was written to a connection successfully. More...
 
void fr_trunk_request_state_log (fr_log_t const *log, fr_log_type_t log_type, char const *file, int line, fr_trunk_request_t const *treq)
 
void fr_trunk_request_verify (char const *file, int line, fr_trunk_request_t *treq)
 
bool fr_trunk_search (fr_trunk_t *trunk, void *ptr)
 
int fr_trunk_start (fr_trunk_t *trunk)
 Start the trunk running. More...
 
void fr_trunk_verify (char const *file, int line, fr_trunk_t *trunk)
 Verify a trunk. More...
 
static void trunk_backlog_drain (fr_trunk_t *trunk)
 Drain the backlog of as many requests as possible. More...
 
static void trunk_connection_auto_full (fr_trunk_connection_t *tconn)
 Automatically mark a connection as inactive. More...
 
static void trunk_connection_auto_unfull (fr_trunk_connection_t *tconn)
 Automatically mark a connection as active or reconnect it. More...
 
static void trunk_connection_close_if_empty (fr_trunk_t *trunk, fr_dlist_head_t *head)
 Close connections in a particular connection list if they have no requests associated with them. More...
 
static void trunk_connection_enter_active (fr_trunk_connection_t *tconn)
 Transition a connection back to the active state. More...
 
static void trunk_connection_enter_draining (fr_trunk_connection_t *tconn)
 Transition a connection to the draining state. More...
 
static void trunk_connection_enter_draining_to_free (fr_trunk_connection_t *tconn)
 Transition a connection to the draining-to-reconnect state. More...
 
static void trunk_connection_enter_full (fr_trunk_connection_t *tconn)
 Transition a connection to the full state. More...
 
static void trunk_connection_enter_inactive (fr_trunk_connection_t *tconn)
 Transition a connection to the inactive state. More...
 
static void trunk_connection_enter_inactive_draining (fr_trunk_connection_t *tconn)
 Transition a connection to the inactive-draining state. More...
 
static void trunk_connection_event_update (fr_trunk_connection_t *tconn)
 Update the registrations for I/O events we're interested in. More...
 
static bool trunk_connection_is_full (fr_trunk_connection_t *tconn)
 Return whether a trunk connection should currently be considered full. More...
 
static void trunk_connection_readable (fr_trunk_connection_t *tconn)
 A connection is readable. More...
 
static void trunk_connection_remove (fr_trunk_connection_t *tconn)
 Remove a trunk connection from whichever list it's currently in. More...
 
static uint64_t trunk_connection_requests_dequeue (fr_dlist_head_t *out, fr_trunk_connection_t *tconn, int states, uint64_t max)
 Shift requests in the specified states onto new connections. More...
 
static uint64_t trunk_connection_requests_requeue (fr_trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound)
 Remove requests in specified states from a connection, attempting to distribute them to new connections. More...
 
static int trunk_connection_spawn (fr_trunk_t *trunk, fr_time_t now)
 Attempt to spawn a new connection. More...
 
static void trunk_connection_writable (fr_trunk_connection_t *tconn)
 A connection is writable. More...
 
static void trunk_manage (fr_trunk_t *trunk, fr_time_t now)
 Implements the algorithm we use to manage requests per connection levels. More...
 
static void trunk_rebalance (fr_trunk_t *trunk)
 Rebalance connections across active trunk members when a new connection becomes active. More...
 
static fr_trunk_enqueue_t trunk_request_check_enqueue (fr_trunk_connection_t **tconn_out, fr_trunk_t *trunk, request_t *request)
 Check to see if a trunk request can be enqueued. More...
 
static fr_trunk_enqueue_t trunk_request_enqueue_existing (fr_trunk_request_t *treq)
 Enqueue a request which has never been assigned to a connection or was previously cancelled. More...
 
static void trunk_request_enter_backlog (fr_trunk_request_t *treq, bool new)
 Transition a request to the backlog state, adding it to the backlog of the trunk. More...
 
static void trunk_request_enter_cancel (fr_trunk_request_t *treq, fr_trunk_cancel_reason_t reason)
 Transition a request to the cancel state, placing it in a connection's cancellation list. More...
 
static void trunk_request_enter_cancel_complete (fr_trunk_request_t *treq)
 Cancellation was acked, the request is complete, free it. More...
 
static void trunk_request_enter_cancel_partial (fr_trunk_request_t *treq)
 Transition a request to the cancel_partial state, placing it in a connection's cancel_partial slot. More...
 
static void trunk_request_enter_cancel_sent (fr_trunk_request_t *treq)
 Transition a request to the cancel_sent state, placing it in a connection's cancel_sent list. More...
 
static void trunk_request_enter_complete (fr_trunk_request_t *treq)
 Request completed successfully, inform the API client and free the request. More...
 
static void trunk_request_enter_failed (fr_trunk_request_t *treq)
 Request failed, inform the API client and free the request. More...
 
static void trunk_request_enter_partial (fr_trunk_request_t *treq)
 Transition a request to the partial state, indicating that is has been partially sent. More...
 
static void trunk_request_enter_pending (fr_trunk_request_t *treq, fr_trunk_connection_t *tconn, bool new)
 Transition a request to the pending state, adding it to the backlog of an active connection. More...
 
static void trunk_request_enter_sent (fr_trunk_request_t *treq)
 Transition a request to the sent state, indicating that it's been sent in its entirety. More...
 
static void trunk_request_enter_unassigned (fr_trunk_request_t *treq)
 Transition a request to the unassigned state, in preparation for re-assignment. More...
 
static void trunk_request_remove_from_conn (fr_trunk_request_t *treq)
 Remove a request from all connection lists. More...
 
void trunk_request_state_log_entry_add (char const *function, int line, fr_trunk_request_t *treq, fr_trunk_request_state_t new)
 
static uint64_t trunk_requests_per_connection (uint16_t *conn_count_out, uint32_t *req_count_out, fr_trunk_t *trunk, fr_time_t now, NDEBUG_UNUSED bool verify)
 Update timestamps for when we last had a transition from above target to below target or vice versa. More...
 
static void trunk_watch_call (fr_trunk_t *trunk, fr_dlist_head_t *list, fr_trunk_state_t state)
 Call a list of watch functions associated with a state. More...
 

Variables

static fr_table_num_ordered_t const fr_trunk_cancellation_reasons []
 
static size_t fr_trunk_cancellation_reasons_len = NUM_ELEMENTS(fr_trunk_cancellation_reasons)
 
conf_parser_t const fr_trunk_config []
 Config parser definitions to populate a fr_trunk_conf_t. More...
 
static conf_parser_t const fr_trunk_config_connection []
 
static conf_parser_t const fr_trunk_config_request []
 
static fr_table_num_indexed_bit_pos_t const fr_trunk_conn_trigger_names []
 Map connection states to trigger names. More...
 
static size_t fr_trunk_conn_trigger_names_len = NUM_ELEMENTS(fr_trunk_conn_trigger_names)
 
static fr_table_num_ordered_t const fr_trunk_connection_events []
 
static size_t fr_trunk_connection_events_len = NUM_ELEMENTS(fr_trunk_connection_events)
 
static fr_table_num_ordered_t const fr_trunk_connection_states []
 
static size_t fr_trunk_connection_states_len = NUM_ELEMENTS(fr_trunk_connection_states)
 
static fr_table_num_indexed_bit_pos_t const fr_trunk_req_trigger_names []
 Map request states to trigger names. More...
 
static size_t fr_trunk_req_trigger_names_len = NUM_ELEMENTS(fr_trunk_req_trigger_names)
 
static fr_table_num_ordered_t const fr_trunk_request_states []
 
static size_t fr_trunk_request_states_len = NUM_ELEMENTS(fr_trunk_request_states)
 
static fr_table_num_ordered_t const fr_trunk_states []
 
static size_t fr_trunk_states_len = NUM_ELEMENTS(fr_trunk_states)
 
static atomic_uint_fast64_t request_counter = ATOMIC_VAR_INIT(1)
 

Detailed Description

A management API for bonding multiple connections together.

Id
58449016519ccdcb6716416e983c52d0bb90e864
Id
1508f1c9b8bcf593c8e40a80751978b382337c8e

Definition in file trunk.c.


Data Structure Documentation

◆ fr_trunk_connection_s

struct fr_trunk_connection_s

Associates request queues with a connection.

Trunk connection state machine
Trunk request state machine

Definition at line 127 of file trunk.c.

+ Collaboration diagram for fr_trunk_connection_s:
Data Fields
fr_dlist_head_t cancel Requests in the cancel state.
fr_trunk_request_t * cancel_partial Partially written cancellation request.
fr_dlist_head_t cancel_sent Sent cancellation request.
fr_dlist_t entry Used to track the connection in the connecting, full and failed lists.
fr_trunk_connection_event_t events The current events we expect to be notified on.
fr_heap_index_t heap_id Used to track the connection in the connected heap.
fr_event_timer_t const * lifetime_ev Maximum time this connection can be open.
fr_trunk_request_t * partial Partially written request.
fr_heap_t * pending Requests waiting to be sent.
struct fr_trunk_connection_pub_s pub Public fields in the trunk connection.

This MUST be the first field in this structure.

fr_dlist_head_t sent Sent request.
uint64_t sent_count The number of requests that have been sent using this connection.

◆ fr_trunk_request_s

struct fr_trunk_request_s

Wraps a normal request.

Definition at line 97 of file trunk.c.

+ Collaboration diagram for fr_trunk_request_s:
Data Fields
bool bound_to_conn Fail the request if there's an attempt to re-enqueue it.
fr_trunk_cancel_reason_t cancel_reason Why this request was cancelled.
fr_dlist_t entry Used to track the trunk request in the conn->sent or trunk->backlog request.
fr_heap_index_t heap_id Used to track the request conn->pending heap.
uint64_t id Trunk request ID.
fr_time_t last_freed Last time this request was freed.
fr_dlist_head_t log State change log.
struct fr_trunk_request_pub_s pub Public fields in the trunk request.

This MUST be the first field in this structure.

◆ fr_trunk_request_state_log_t

struct fr_trunk_request_state_log_t

Trace state machine changes for a particular request.

Definition at line 74 of file trunk.c.

+ Collaboration diagram for fr_trunk_request_state_log_t:
Data Fields
fr_dlist_t entry Entry in the linked list.
fr_trunk_request_state_t from What state we transitioned from.
char const * function State change occurred in.
int line Line change occurred on.
fr_dlist_head_t * log_head To allow the log entry to remove itself on free.
fr_trunk_connection_t * tconn The request was associated with.

Pointer may now be invalid, do no de-reference.

uint64_t tconn_id If the treq was associated with a connection the connection ID.
fr_trunk_connection_state_t tconn_state If the treq was associated with a connection the connection state at the time of the state transition.
fr_trunk_request_state_t to What state we transitioned to.

◆ fr_trunk_s

struct fr_trunk_s

Main trunk management handle.

Definition at line 189 of file trunk.c.

+ Collaboration diagram for fr_trunk_s:
Data Fields
fr_minmax_heap_t * active Connections which can service requests.
fr_heap_t * backlog The request backlog.

Requests we couldn't immediately assign to a connection.

fr_dlist_head_t closed Connections that have closed.

Either due to shutdown, reconnection or failure.

fr_trunk_conf_t conf Trunk common configuration.
fr_dlist_head_t connecting Connections which are not yet in the open state.
fr_dlist_head_t draining Connections that will be freed once all their requests are complete, but can be reactivated.
fr_dlist_head_t draining_to_free Connections that will be freed once all their requests are complete.
fr_event_list_t * el Event list used by this trunk and the connection.
fr_dlist_head_t failed Connections that'll be reconnected shortly.
fr_dlist_head_t free_requests Requests in the unassigned state.

Waiting to be enqueued.

bool freeing Trunk is being freed, don't spawn new connections or re-enqueue.
fr_dlist_head_t full Connections which have too many outstanding requests.
fr_trunk_io_funcs_t funcs I/O functions.
void * in_handler Which handler we're inside.
fr_dlist_head_t inactive Connections which have been signalled to be inactive by the API client.
fr_dlist_head_t inactive_draining Connections which have been signalled to be inactive by the API client, which the trunk manager is draining to close.
fr_dlist_head_t init Connections which have not yet started connecting.
uint64_t last_req_per_conn The last request to connection ratio we calculated.
fr_rate_limit_t limit_last_failure_log Rate limit on "Refusing to enqueue requests - No active conns".
fr_rate_limit_t limit_max_requests_alloc_log Rate limit on "Refusing to alloc requests - Limit of * requests reached".
char const * log_prefix What to prepend to messages.
fr_event_timer_t const * manage_ev Periodic connection management event.
bool managing_connections Whether the trunk is allowed to manage (open/close) connections.
fr_trunk_watch_entry_t * next_watcher Watcher about to be run. Used to prevent nested watchers.
struct fr_trunk_pub_s pub Public fields in the trunk connection.

This MUST be the first field in this structure.

bool started Has the trunk been started.
fr_dlist_head_t to_free Connections we're done with and will free on the next call to trunk_manage.

This prevents connections from being freed whilst we're inside callbacks.

void * uctx Uctx data to pass to alloc.
fr_dlist_head_t watch[FR_TRUNK_STATE_MAX] To be called when trunk changes state.

◆ fr_trunk_watch_entry_s

struct fr_trunk_watch_entry_s

An entry in a trunk watch function list.

Definition at line 177 of file trunk.c.

+ Collaboration diagram for fr_trunk_watch_entry_s:
Data Fields
bool enabled Whether the watch entry is enabled.
fr_dlist_t entry List entry.
fr_trunk_watch_t func Function to call when a trunk enters the state this list belongs to.
bool oneshot Remove the function after it's called once.
void * uctx User data to pass to the function.

Macro Definition Documentation

◆ _TRUNK_PRIVATE

#define _TRUNK_PRIVATE   1

Definition at line 36 of file trunk.c.

◆ CALL_WATCHERS

#define CALL_WATCHERS (   _trunk,
  _state 
)
Value:
do { \
if (fr_dlist_empty(&(_trunk)->watch[_state])) break; \
trunk_watch_call((_trunk), &(_trunk)->watch[_state], _state); \
} while(0)
static bool fr_dlist_empty(fr_dlist_head_t const *list_head)
Check whether a list has any items.
Definition: dlist.h:501

Call the state change watch functions.

Definition at line 796 of file trunk.c.

◆ CONN_BAD_STATE_TRANSITION

#define CONN_BAD_STATE_TRANSITION (   _new)
Value:
do { \
if (!fr_cond_assert_msg(0, "[%" PRIu64 "] Trunk connection invalid transition %s -> %s", \
tconn->pub.conn->id, \
fr_table_str_by_value(fr_trunk_connection_states, tconn->pub.state, "<INVALID>"), \
} while (0)
while(1)
Definition: acutest.h:856
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:154
return
Definition: module.c:186
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
static fr_table_num_ordered_t const fr_trunk_connection_states[]
Definition: trunk.c:389

Definition at line 438 of file trunk.c.

◆ CONN_REORDER

#define CONN_REORDER (   _tconn)
Value:
do { \
int _ret; \
if ((fr_minmax_heap_num_elements((_tconn)->pub.trunk->active) == 1)) break; \
if (!fr_cond_assert((_tconn)->pub.state == FR_TRUNK_CONN_ACTIVE)) break; \
_ret = fr_minmax_heap_extract((_tconn)->pub.trunk->active, (_tconn)); \
if (!fr_cond_assert_msg(_ret == 0, "Failed extracting conn from active heap: %s", fr_strerror())) break; \
fr_minmax_heap_insert((_tconn)->pub.trunk->active, (_tconn)); \
} while (0)
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:137
int fr_minmax_heap_insert(fr_minmax_heap_t *hp, void *data)
Definition: minmax_heap.c:424
unsigned int fr_minmax_heap_num_elements(fr_minmax_heap_t *hp)
Return the number of elements in the minmax heap.
Definition: minmax_heap.c:533
int fr_minmax_heap_extract(fr_minmax_heap_t *hp, void *data)
Definition: minmax_heap.c:486
break
Definition: rlm_securid.c:421
if(!subtype_vp) goto fail
@ FR_TRUNK_CONN_ACTIVE
Connection is connected and ready to service requests.
Definition: trunk.h:91
char const * fr_strerror(void)
Get the last library error.
Definition: strerror.c:554

Reorder the connections in the active heap.

fr_heap_extract will also error out if heap_id is bad - no need for assert

Definition at line 757 of file trunk.c.

◆ CONN_STATE_TRANSITION

#define CONN_STATE_TRANSITION (   _new,
  _log 
)
Value:
do { \
_log("[%" PRIu64 "] Trunk connection changed state %s -> %s", \
tconn->pub.conn->id, \
fr_table_str_by_value(fr_trunk_connection_states, tconn->pub.state, "<INVALID>"), \
tconn->pub.state = _new; \
CONN_TRIGGER(_new); \
trunk_requests_per_connection(NULL, NULL, trunk, fr_time(), false); \
} while (0)
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition: state_test.c:8

Definition at line 427 of file trunk.c.

◆ CONN_TRIGGER

#define CONN_TRIGGER (   _state)
Value:
do { \
if (trunk->pub.triggers) { \
"<INVALID>"), true, NULL); \
} \
} while (0)
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
Definition: interpret.c:1768
static fr_table_num_indexed_bit_pos_t const fr_trunk_conn_trigger_names[]
Map connection states to trigger names.
Definition: trunk.c:368

Definition at line 419 of file trunk.c.

◆ COUNT_BY_STATE

#define COUNT_BY_STATE (   _state,
  _list 
)
Value:
do { \
if (conn_state & (_state)) { \
tconn = NULL; \
while ((tconn = fr_dlist_next(&trunk->_list, tconn))) { \
count += fr_trunk_request_count_by_connection(tconn, req_state); \
} \
} \
} while (0)
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
Definition: dlist.h:555
uint32_t fr_trunk_request_count_by_connection(fr_trunk_connection_t const *tconn, int req_state)
Return the count number of requests associated with a trunk connection.
Definition: trunk.c:2767

◆ DEQUEUE_ALL

#define DEQUEUE_ALL (   _src_list,
  _state 
)
Value:
do { \
while ((treq = fr_dlist_head(_src_list))) { \
OVER_MAX_CHECK; \
fr_assert(treq->pub.state == (_state)); \
trunk_request_enter_unassigned(treq); \
fr_dlist_insert_tail(out, treq); \
} } while (0)
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
Definition: dlist.h:486
static size_t char ** out
Definition: value.h:984

◆ DO_CONNECTION_ALLOC

#define DO_CONNECTION_ALLOC (   _tconn)
Value:
do { \
void *_prev = trunk->in_handler; \
DEBUG3("Calling connection_alloc(tconn=%p, el=%p, conf=%p, log_prefix=\"%s\", uctx=%p)", \
(_tconn), \
(_tconn)->pub.trunk->el, \
(_tconn)->pub.trunk->conf.conn_conf, \
trunk->log_prefix, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *) (_tconn)->pub.trunk->funcs.connection_alloc; \
(_tconn)->pub.conn = trunk->funcs.connection_alloc((_tconn), (_tconn)->pub.trunk->el, (_tconn)->pub.trunk->conf.conn_conf, (_tconn)->pub.trunk->log_prefix, trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
if (!(_tconn)->pub.conn) { \
ERROR("Failed creating new connection"); \
talloc_free(tconn); \
return -1; \
} \
} while(0)

Allocate a new connection.

Definition at line 653 of file trunk.c.

◆ DO_CONNECTION_NOTIFY

#define DO_CONNECTION_NOTIFY (   _tconn,
  _events 
)
Value:
do { \
if ((_tconn)->pub.trunk->funcs.connection_notify) { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling connection_notify(tconn=%p, conn=%p, el=%p, events=%s, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->el, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.connection_notify; \
(_tconn)->pub.trunk->funcs.connection_notify((_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->el, (_events), (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} \
} while(0)
#define DEBUG3(_fmt,...)
Definition: log.h:266
static fr_table_num_ordered_t const fr_trunk_connection_events[]
Definition: trunk.c:411

Change what events the connection should be notified about.

Definition at line 675 of file trunk.c.

◆ DO_REQUEST_CANCEL

#define DO_REQUEST_CANCEL (   _treq,
  _reason 
)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_cancel) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_cancel; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_cancel(conn=%p, preq=%p, reason=%s, uctx=%p)", \
(_treq)->pub.tconn->pub.conn, \
(_treq)->pub.preq, \
(_reason), \
"<INVALID>"), \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->funcs.request_cancel((_treq)->pub.tconn->pub.conn, (_treq)->pub.preq, (_reason), (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:528
#define RDEBUG3(fmt,...)
Definition: log.h:343
static fr_table_num_ordered_t const fr_trunk_cancellation_reasons[]
Definition: trunk.c:403

Call the cancel callback if set.

Definition at line 506 of file trunk.c.

◆ DO_REQUEST_CANCEL_MUX

#define DO_REQUEST_CANCEL_MUX (   _tconn)
Value:
do { \
if ((_tconn)->pub.trunk->funcs.request_cancel_mux) { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling request_cancel_mux(tconn=%p, conn=%p, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.request_cancel_mux; \
(_tconn)->pub.trunk->funcs.request_cancel_mux((_tconn)->pub.trunk->el, (_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Write one or more cancellation requests to a connection.

Definition at line 635 of file trunk.c.

◆ DO_REQUEST_COMPLETE

#define DO_REQUEST_COMPLETE (   _treq)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_complete) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_complete(request=%p, preq=%p, rctx=%p, uctx=%p)", \
(_treq)->pub.request, \
(_treq)->pub.preq, \
(_treq)->pub.rctx, \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_complete; \
(_treq)->pub.trunk->funcs.request_complete((_treq)->pub.request, (_treq)->pub.preq, (_treq)->pub.rctx, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Call the complete callback (if set)

Definition at line 545 of file trunk.c.

◆ DO_REQUEST_CONN_RELEASE

#define DO_REQUEST_CONN_RELEASE (   _treq)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_conn_release) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_conn_release; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_conn_release(conn=%p, preq=%p, uctx=%p)", \
(_treq)->pub.tconn->pub.conn, \
(_treq)->pub.preq, \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->funcs.request_conn_release((_treq)->pub.tconn->pub.conn, (_treq)->pub.preq, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Call the "conn_release" callback (if set)

Definition at line 527 of file trunk.c.

◆ DO_REQUEST_DEMUX

#define DO_REQUEST_DEMUX (   _tconn)
Value:
do { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling request_demux(tconn=%p, conn=%p, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.request_demux; \
(_tconn)->pub.trunk->funcs.request_demux((_tconn)->pub.trunk->el, (_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} while(0)

Read one or more requests from a connection.

Definition at line 619 of file trunk.c.

◆ DO_REQUEST_FAIL

#define DO_REQUEST_FAIL (   _treq,
  _prev_state 
)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_fail) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_fail(request=%p, preq=%p, rctx=%p, state=%s uctx=%p)", \
(_treq)->pub.request, \
(_treq)->pub.preq, \
(_treq)->pub.rctx, \
fr_table_str_by_value(fr_trunk_request_states, (_prev_state), "<INVALID>"), \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_fail; \
(_treq)->pub.trunk->funcs.request_fail((_treq)->pub.request, (_treq)->pub.preq, (_treq)->pub.rctx, _prev_state, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)
static fr_table_num_ordered_t const fr_trunk_request_states[]
Definition: trunk.c:348

Call the fail callback (if set)

Definition at line 564 of file trunk.c.

◆ DO_REQUEST_FREE

#define DO_REQUEST_FREE (   _treq)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_free) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_free(request=%p, preq=%p, uctx=%p)", \
(_treq)->pub.request, \
(_treq)->pub.preq, \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_free; \
(_treq)->pub.trunk->funcs.request_free((_treq)->pub.request, (_treq)->pub.preq, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Call the free callback (if set)

Definition at line 584 of file trunk.c.

◆ DO_REQUEST_MUX

#define DO_REQUEST_MUX (   _tconn)
Value:
do { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling request_mux(el=%p, tconn=%p, conn=%p, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn)->pub.trunk->el, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.request_mux; \
(_tconn)->pub.trunk->funcs.request_mux((_tconn)->pub.trunk->el, (_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} while(0)

Write one or more requests to a connection.

Definition at line 602 of file trunk.c.

◆ FR_TRUNK_REQUEST_STATE_LOG_MAX

#define FR_TRUNK_REQUEST_STATE_LOG_MAX   20

The maximum number of state logs to record per request.

Definition at line 69 of file trunk.c.

◆ IN_HANDLER

#define IN_HANDLER (   _trunk)    (((_trunk)->in_handler) != NULL)

Definition at line 692 of file trunk.c.

◆ IN_REQUEST_CANCEL_MUX

#define IN_REQUEST_CANCEL_MUX (   _trunk)    (((_trunk)->funcs.request_cancel_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_cancel_mux))

Definition at line 695 of file trunk.c.

◆ IN_REQUEST_DEMUX

#define IN_REQUEST_DEMUX (   _trunk)    (((_trunk)->funcs.request_demux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_demux))

Definition at line 694 of file trunk.c.

◆ IN_REQUEST_MUX

#define IN_REQUEST_MUX (   _trunk)    (((_trunk)->funcs.request_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_mux))

Definition at line 693 of file trunk.c.

◆ IO_FUNC_VERIFY

#define IO_FUNC_VERIFY (   _func)     fr_fatal_assert_msg(trunk->funcs._func, "CONSISTENCY_CHECK_FAILED %s[%i}: " #_func " was NULL", file, line)

◆ IS_PROCESSING

#define IS_PROCESSING (   _tconn)    ((tconn)->pub.state & FR_TRUNK_CONN_PROCESSING)

Definition at line 698 of file trunk.c.

◆ IS_SERVICEABLE

#define IS_SERVICEABLE (   _tconn)    ((_tconn)->pub.state & FR_TRUNK_CONN_SERVICEABLE)

Definition at line 697 of file trunk.c.

◆ LOG_PREFIX

#define LOG_PREFIX   trunk->log_prefix

Definition at line 27 of file trunk.c.

◆ OVER_MAX_CHECK

#define OVER_MAX_CHECK   if (++count > max) return (count - 1)

◆ RECONNECT_BY_STATE

#define RECONNECT_BY_STATE (   _state,
  _list 
)
Value:
do { \
if (states & (_state)) { \
size_t i; \
for (i = fr_dlist_num_elements(&trunk->_list); i > 0; i--) { \
fr_connection_signal_reconnect(((fr_trunk_connection_t *)fr_dlist_tail(&trunk->_list))->pub.conn, reason); \
} \
} \
} while (0)
static unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
Definition: dlist.h:939
static void * fr_dlist_tail(fr_dlist_head_t const *list_head)
Return the TAIL item of a list or NULL if the list is empty.
Definition: dlist.h:531
Associates request queues with a connection.
Definition: trunk.c:127

◆ REQUEST_BAD_STATE_TRANSITION

#define REQUEST_BAD_STATE_TRANSITION (   _new)
Value:
do { \
fr_trunk_request_state_log(&default_log, L_ERR, __FILE__, __LINE__, treq); \
if (!fr_cond_assert_msg(0, "Trunk request %" PRIu64 " invalid transition %s -> %s", \
treq->id, \
fr_table_str_by_value(fr_trunk_request_states, treq->pub.state, "<INVALID>"), \
} while (0)
fr_log_t default_log
Definition: log.c:290
@ L_ERR
Error message.
Definition: log.h:56

Definition at line 472 of file trunk.c.

◆ REQUEST_EXTRACT_BACKLOG

#define REQUEST_EXTRACT_BACKLOG (   _treq)
Value:
do { \
int _ret; \
_ret = fr_heap_extract(&(_treq)->pub.trunk->backlog, _treq); \
if (!fr_cond_assert_msg(_ret == 0, "Failed extracting conn from backlog heap: %s", fr_strerror())) break; \
} while (0)
int fr_heap_extract(fr_heap_t **hp, void *data)
Remove a node from the heap.
Definition: heap.c:239

Remove the current request from the backlog.

Definition at line 703 of file trunk.c.

◆ REQUEST_EXTRACT_CANCEL

#define REQUEST_EXTRACT_CANCEL (   _treq)    fr_dlist_remove(&tconn->cancel, treq)

Remove the current request from the cancel list.

Definition at line 737 of file trunk.c.

◆ REQUEST_EXTRACT_CANCEL_PARTIAL

#define REQUEST_EXTRACT_CANCEL_PARTIAL (   _treq)
Value:
do { \
fr_assert((_treq)->pub.tconn->cancel_partial == treq); \
tconn->cancel_partial = NULL; \
} while (0)

Remove the current request from the cancel_partial slot.

Definition at line 742 of file trunk.c.

◆ REQUEST_EXTRACT_CANCEL_SENT

#define REQUEST_EXTRACT_CANCEL_SENT (   _treq)    fr_dlist_remove(&tconn->cancel_sent, treq)

Remove the current request from the cancel sent list.

Definition at line 751 of file trunk.c.

◆ REQUEST_EXTRACT_PARTIAL

#define REQUEST_EXTRACT_PARTIAL (   _treq)
Value:
do { \
fr_assert((_treq)->pub.tconn->partial == treq); \
tconn->partial = NULL; \
} while (0)

Remove the current request from the partial slot.

Definition at line 723 of file trunk.c.

◆ REQUEST_EXTRACT_PENDING

#define REQUEST_EXTRACT_PENDING (   _treq)
Value:
do { \
int _ret; \
_ret = fr_heap_extract(&(_treq)->pub.tconn->pending, _treq); \
if (!fr_cond_assert_msg(_ret == 0, "Failed extracting conn from pending heap: %s", fr_strerror())) break; \
} while (0)

Remove the current request from the pending list.

Definition at line 713 of file trunk.c.

◆ REQUEST_EXTRACT_SENT

#define REQUEST_EXTRACT_SENT (   _treq)    fr_dlist_remove(&tconn->sent, treq)

Remove the current request from the sent list.

Definition at line 732 of file trunk.c.

◆ REQUEST_STATE_TRANSITION

#define REQUEST_STATE_TRANSITION (   _new)
Value:
do { \
request_t *request = treq->pub.request; \
ROPTIONAL(RDEBUG3, DEBUG3, "Trunk request %" PRIu64 " changed state %s -> %s", \
treq->id, \
fr_table_str_by_value(fr_trunk_request_states, treq->pub.state, "<INVALID>"), \
trunk_request_state_log_entry_add(__FUNCTION__, __LINE__, treq, _new); \
treq->pub.state = _new; \
REQUEST_TRIGGER(_new); \
} while (0)

Record a request state transition and log appropriate output.

Definition at line 461 of file trunk.c.

◆ REQUEST_TRIGGER

#define REQUEST_TRIGGER (   _state)
Value:
do { \
if (trunk->pub.triggers) { \
"<INVALID>"), true, NULL); \
} \
} while (0)
static fr_table_num_indexed_bit_pos_t const fr_trunk_req_trigger_names[]
Map request states to trigger names.
Definition: trunk.c:331

Definition at line 450 of file trunk.c.

◆ TCONN_DLIST_SEARCH

#define TCONN_DLIST_SEARCH (   _dlist)
Value:
do { \
fr_dlist_foreach(&(trunk->_dlist), fr_trunk_connection_t, tconn) { \
if (ptr == tconn) { \
fr_fprintf(stderr, "fr_trunk_search: tconn %p on " #_dlist "\n", ptr); \
return true; \
} \
if (fr_trunk_connection_search(tconn, ptr)) { \
fr_fprintf(stderr, " in tconn %p on " #_dlist "\n", tconn); \
return true; \
} \
} \
} while (0)
bool fr_trunk_connection_search(fr_trunk_connection_t *tconn, void *ptr)
Definition: trunk.c:5025

◆ TCONN_DLIST_VERIFY

#define TCONN_DLIST_VERIFY (   _dlist,
  _state 
)
Value:
do { \
_fr_dlist_verify(file, line, &(trunk->_dlist)); \
fr_dlist_foreach(&(trunk->_dlist), fr_trunk_connection_t, tconn) { \
fr_trunk_connection_verify(file, line, tconn); \
TRUNK_TCONN_CHECKS(tconn, _state); \
} \
} while (0)
int const char * file
Definition: acutest.h:702
int const char int line
Definition: acutest.h:702

◆ TCONN_MINMAX_HEAP_SEARCH

#define TCONN_MINMAX_HEAP_SEARCH (   _heap)
Value:
do { \
fr_minmax_heap_foreach(trunk->_heap, fr_trunk_connection_t, tconn) { \
if (ptr == tconn) { \
fr_fprintf(stderr, "fr_trunk_search: tconn %p on " #_heap "\n", ptr); \
return true; \
} \
if (fr_trunk_connection_search(tconn, ptr)) { \
fr_fprintf(stderr, " on tconn %p on " #_heap "\n", tconn); \
return true; \
} \
}}\
} while (0)

◆ TCONN_MINMAX_HEAP_VERIFY

#define TCONN_MINMAX_HEAP_VERIFY (   _heap,
  _state 
)
Value:
do {\
fr_minmax_heap_verify(file, line, trunk->_heap); \
fr_minmax_heap_foreach(trunk->_heap, fr_trunk_connection_t, tconn) { \
fr_trunk_connection_verify(file, line, tconn); \
TRUNK_TCONN_CHECKS(tconn, _state); \
}} \
} while (0)

◆ TCONN_TREQ_CHECKS

#define TCONN_TREQ_CHECKS (   _treq,
  _state 
)
Value:
do { \
fr_fatal_assert_msg(tconn == _treq->pub.tconn, \
"CONSISTENCY_CHECK_FAILED %s[%i}: trunk request-tconn mismatch", file, line); \
fr_fatal_assert_msg(tconn->pub.trunk == _treq->pub.trunk, \
"CONSISTENCY_CHECK_FAILED %s[%i}: trunk request-trunk mismatch", file, line); \
fr_fatal_assert_msg(_state == _treq->pub.state, \
"CONSISTENCY_CHECK_FAILED %s[%i}: trunk request-state mismatch", file, line); \
} while (0)

◆ TREQ_DLIST_SEARCH

#define TREQ_DLIST_SEARCH (   _dlist)
Value:
do { \
fr_dlist_foreach(&(tconn->_dlist), fr_trunk_request_t, treq) { \
if (ptr == treq) { \
fr_fprintf(stderr, "fr_trunk_search: treq %p on " #_dlist "\n", ptr); \
return true; \
} \
if (fr_trunk_request_search(treq, ptr)) { \
fr_fprintf(stderr, "fr_trunk_search: preq %p found on " #_dlist, ptr); \
return true; \
} \
} \
} while (0)
bool fr_trunk_request_search(fr_trunk_request_t *treq, void *ptr)
Definition: trunk.c:5083
Wraps a normal request.
Definition: trunk.c:97

◆ TREQ_DLIST_VERIFY

#define TREQ_DLIST_VERIFY (   _dlist,
  _state 
)
Value:
do { \
_fr_dlist_verify(file, line, &(tconn->_dlist)); \
fr_dlist_foreach(&(tconn->_dlist), fr_trunk_request_t, treq) { \
fr_trunk_request_verify(file, line, treq); \
TCONN_TREQ_CHECKS(treq, _state); \
} \
} while (0)

◆ TREQ_HEAP_SEARCH

#define TREQ_HEAP_SEARCH (   _heap)
Value:
do { \
fr_heap_iter_t _iter; \
for (fr_trunk_request_t *treq = fr_heap_iter_init(tconn->_heap, &_iter); \
treq; \
treq = fr_heap_iter_next(tconn->_heap, &_iter)) { \
if (ptr == treq) { \
fr_fprintf(stderr, "fr_trunk_search: treq %p in " #_heap "\n", ptr); \
return true; \
} \
if (fr_trunk_request_search(treq, ptr)) { \
fr_fprintf(stderr, "fr_trunk_search: preq %p found in " #_heap, ptr); \
return true; \
} \
} \
} while (0)
void * fr_heap_iter_init(fr_heap_t *h, fr_heap_iter_t *iter)
Iterate over entries in heap.
Definition: heap.c:351
void * fr_heap_iter_next(fr_heap_t *h, fr_heap_iter_t *iter)
Get the next entry in a heap.
Definition: heap.c:371

◆ TREQ_HEAP_VERIFY

#define TREQ_HEAP_VERIFY (   _heap,
  _state 
)
Value:
do { \
fr_heap_iter_t _iter; \
fr_heap_verify(file, line, tconn->_heap); \
for (fr_trunk_request_t *treq = fr_heap_iter_init(tconn->_heap, &_iter); \
treq; \
treq = fr_heap_iter_next(tconn->_heap, &_iter)) { \
fr_trunk_request_verify(file, line, treq); \
TCONN_TREQ_CHECKS(treq, _state); \
} \
} while (0)

◆ TREQ_OPTION_SEARCH

#define TREQ_OPTION_SEARCH (   _option)
Value:
do { \
if (tconn->_option) { \
if (ptr == tconn->_option) { \
fr_fprintf(stderr, "fr_trunk_search: treq %p is " #_option "\n", ptr); \
return true; \
} \
if (fr_trunk_request_search(tconn->_option, ptr)) { \
fr_fprintf(stderr, "fr_trunk_search: preq %p found in " #_option, ptr); \
return true; \
} \
} \
} while (0)

◆ TREQ_OPTION_VERIFY

#define TREQ_OPTION_VERIFY (   _option,
  _state 
)
Value:
do { \
if (tconn->_option) { \
fr_trunk_request_verify(file, line, tconn->_option); \
TCONN_TREQ_CHECKS(tconn->_option, _state); \
} \
} while (0)

◆ TRUNK_STATE_TRANSITION

#define TRUNK_STATE_TRANSITION (   _new)
Value:
do { \
DEBUG3("Trunk changed state %s -> %s", \
fr_table_str_by_value(fr_trunk_states, trunk->pub.state, "<INVALID>"), \
fr_table_str_by_value(fr_trunk_states, _new, "<INVALID>")); \
CALL_WATCHERS(trunk, _new); \
trunk->pub.state = _new; \
} while (0)
static fr_table_num_ordered_t const fr_trunk_states[]
Definition: trunk.c:382

Definition at line 866 of file trunk.c.

◆ TRUNK_TCONN_CHECKS

#define TRUNK_TCONN_CHECKS (   _tconn,
  _state 
)
Value:
do { \
fr_fatal_assert_msg(trunk == _tconn->pub.trunk, \
"CONSISTENCY_CHECK_FAILED %s[%i}: connection-trunk mismatch", file, line); \
fr_fatal_assert_msg(_state == _tconn->pub.state, \
"CONSISTENCY_CHECK_FAILED %s[%i}: connection-state mismatch", file, line); \
} while (0)

Typedef Documentation

◆ fr_trunk_connection_t

Definition at line 1 of file trunk.c.

◆ fr_trunk_request_t

Definition at line 1 of file trunk.c.

◆ fr_trunk_t

typedef struct fr_trunk_s fr_trunk_t

Definition at line 1 of file trunk.c.

◆ fr_trunk_watch_entry_t

An entry in a trunk watch function list.

Function Documentation

◆ _state_log_entry_free()

static int _state_log_entry_free ( fr_trunk_request_state_log_t slog)
static

Used for sanity checks to ensure all log entries have been freed.

Definition at line 2678 of file trunk.c.

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

◆ _trunk_connection_free()

static int _trunk_connection_free ( fr_trunk_connection_t tconn)
static

Free a connection.

Enforces orderly free order of children of the tconn

Definition at line 3554 of file trunk.c.

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

◆ _trunk_connection_lifetime_expire()

static void _trunk_connection_lifetime_expire ( UNUSED fr_event_list_t el,
UNUSED fr_time_t  now,
void *  uctx 
)
static

Trigger a reconnection of the trunk connection.

Parameters
[in]elEvent list the timer was inserted into.
[in]nowCurrent time.
[in]uctxThe tconn.

Definition at line 3316 of file trunk.c.

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

◆ _trunk_connection_on_closed()

static void _trunk_connection_on_closed ( UNUSED fr_connection_t conn,
UNUSED fr_connection_state_t  prev,
UNUSED fr_connection_state_t  state,
void *  uctx 
)
static

Connection failed after it was connected.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3383 of file trunk.c.

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

◆ _trunk_connection_on_connected()

static void _trunk_connection_on_connected ( UNUSED fr_connection_t conn,
UNUSED fr_connection_state_t  prev,
UNUSED fr_connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the connected state.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3334 of file trunk.c.

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

◆ _trunk_connection_on_connecting()

static void _trunk_connection_on_connecting ( UNUSED fr_connection_t conn,
UNUSED fr_connection_state_t  prev,
UNUSED fr_connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the connecting state.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3238 of file trunk.c.

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

◆ _trunk_connection_on_failed()

static void _trunk_connection_on_failed ( fr_connection_t conn,
fr_connection_state_t  prev,
fr_connection_state_t  state,
void *  uctx 
)
static

Connection failed.

Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3454 of file trunk.c.

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

◆ _trunk_connection_on_halted()

static void _trunk_connection_on_halted ( UNUSED fr_connection_t conn,
UNUSED fr_connection_state_t  prev,
UNUSED fr_connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the halted state.

Remove the connection remove all lists, as it's likely about to be freed.

Setting the trunk back to the init state ensures that if the code is ever refactored and fr_connection_signal_reconnect is used after a connection is halted, then everything is maintained in a valid state.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3506 of file trunk.c.

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

◆ _trunk_connection_on_init()

static void _trunk_connection_on_init ( UNUSED fr_connection_t conn,
UNUSED fr_connection_state_t  prev,
UNUSED fr_connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the the init state.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3203 of file trunk.c.

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

◆ _trunk_connection_on_shutdown()

static void _trunk_connection_on_shutdown ( UNUSED fr_connection_t conn,
UNUSED fr_connection_state_t  prev,
UNUSED fr_connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the shutdown state.

If we're not already in the draining-to-free state, transition there now.

The idea is that if something signalled the connection to shutdown, we need to reflect that by dequeuing any pending requests, not accepting new ones, and waiting for the existing requests to complete.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe fr_trunk_connection_t wrapping the connection.

Definition at line 3282 of file trunk.c.

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

◆ _trunk_connection_order_by_shortest_queue()

static int8_t _trunk_connection_order_by_shortest_queue ( void const *  one,
void const *  two 
)
static

Order connections by queue depth.

Definition at line 4666 of file trunk.c.

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

◆ _trunk_free()

static int _trunk_free ( fr_trunk_t trunk)
static

Free a trunk, gracefully closing all connections.

Definition at line 4683 of file trunk.c.

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

◆ _trunk_request_free()

static int _trunk_request_free ( fr_trunk_request_t treq)
static

Actually free the trunk request.

Definition at line 2336 of file trunk.c.

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

◆ _trunk_request_prioritise()

static int8_t _trunk_request_prioritise ( void const *  a,
void const *  b 
)
static

Compare two protocol requests.

Allows protocol requests to be prioritised with a function specified by the API client. Defaults to by pointer address if no function is specified.

Parameters
[in]atreq to compare to b.
[in]btreq to compare to a.
Returns
  • +1 if a > b.
  • 0 if a == b.
  • -1 if a < b.

Definition at line 919 of file trunk.c.

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

◆ _trunk_timer()

static void _trunk_timer ( fr_event_list_t el,
fr_time_t  now,
void *  uctx 
)
static

Event to periodically call the connection management function.

Parameters
[in]elthis event belongs to.
[in]nowcurrent time.
[in]uctxThe trunk.

Definition at line 4332 of file trunk.c.

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

◆ fr_trunk_add_watch()

fr_trunk_watch_entry_t* fr_trunk_add_watch ( fr_trunk_t trunk,
fr_trunk_state_t  state,
fr_trunk_watch_t  watch,
bool  oneshot,
void const *  uctx 
)

Add a watch entry to the trunk state list.

Parameters
[in]trunkThe trunk to add the watcher to.
[in]stateto watch for.
[in]watchFunction to add.
[in]oneshotShould this watcher only be run once.
[in]uctxContext to pass to function.
Returns
  • NULL if an invalid state is passed.
  • A new watch entry handle on success.

Definition at line 846 of file trunk.c.

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

◆ fr_trunk_alloc()

fr_trunk_t* fr_trunk_alloc ( TALLOC_CTX *  ctx,
fr_event_list_t el,
fr_trunk_io_funcs_t const *  funcs,
fr_trunk_conf_t const *  conf,
char const *  log_prefix,
void const *  uctx,
bool  delay_start 
)

Allocate a new collection of connections.

This function should be called first to allocate a new trunk connection.

After the trunk has been allocated, fr_trunk_request_alloc and fr_trunk_request_enqueue should be used to allocate memory for trunk requests, and pass a preq (protocol request) to the trunk for processing.

The trunk will then asynchronously process the request, writing the result to a specified rctx. See fr_trunk_request_enqueue for more details.

Note
Trunks may not be shared between multiple threads under any circumstances.
Parameters
[in]ctxTo use for any memory allocations. Must be thread local.
[in]elto use for I/O and timer events.
[in]funcsCallback functions.
[in]confCommon user configurable parameters.
[in]log_prefixTo prepend to global messages.
[in]uctxUser data to pass to the alloc function.
[in]delay_startIf true, then we will not spawn any connections until the first request is enqueued.
Returns
  • New trunk handle on success.
  • NULL on error.

Definition at line 4767 of file trunk.c.

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

◆ fr_trunk_connection_callback_readable()

void fr_trunk_connection_callback_readable ( UNUSED fr_event_list_t el,
UNUSED int  fd,
UNUSED int  flags,
void *  uctx 
)

Standard I/O read function.

Underlying FD in now readable, so call the trunk to read any pending requests from this connection.

Parameters
[in]elThe event list signalling.
[in]fdthat's now readable.
[in]flagsdescribing the read event.
[in]uctxThe trunk connection handle (tconn).

Definition at line 3887 of file trunk.c.

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

◆ fr_trunk_connection_callback_writable()

void fr_trunk_connection_callback_writable ( UNUSED fr_event_list_t el,
UNUSED int  fd,
UNUSED int  flags,
void *  uctx 
)

Standard I/O write function.

Underlying FD is now writable, so call the trunk to write any pending requests to this connection.

Parameters
[in]elThe event list signalling.
[in]fdthat's now writable.
[in]flagsdescribing the write event.
[in]uctxThe trunk connection handle (tcon).

Definition at line 3904 of file trunk.c.

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

◆ fr_trunk_connection_count_by_state()

uint16_t fr_trunk_connection_count_by_state ( fr_trunk_t trunk,
int  conn_state 
)

Return the count number of connections in the specified states.

Parameters
[in]trunkto retrieve counts for.
[in]conn_stateOne or more fr_trunk_connection_state_t states or'd together.
Returns
The number of connections in the specified states.

Definition at line 2743 of file trunk.c.

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

◆ fr_trunk_connection_in_state()

bool fr_trunk_connection_in_state ( fr_trunk_connection_t tconn,
int  state 
)

Returns true if the trunk connection is in one of the specified states.

Parameters
[in]tconnTo check state for.
[in]stateto check
Returns
  • True if trunk connection is in a particular state.
  • False if trunk connection is not in a particular state.

Definition at line 3920 of file trunk.c.

◆ fr_trunk_connection_manage_schedule()

int fr_trunk_connection_manage_schedule ( fr_trunk_t trunk)

Schedule a trunk management event for the next time the event loop is executed.

Definition at line 4651 of file trunk.c.

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

◆ fr_trunk_connection_manage_start()

void fr_trunk_connection_manage_start ( fr_trunk_t trunk)

Allow the trunk to open and close connections in response to load.

Definition at line 4630 of file trunk.c.

◆ fr_trunk_connection_manage_stop()

void fr_trunk_connection_manage_stop ( fr_trunk_t trunk)

Stop the trunk from opening and closing connections in response to load.

Definition at line 4641 of file trunk.c.

◆ fr_trunk_connection_pop_cancellation()

int fr_trunk_connection_pop_cancellation ( fr_trunk_request_t **  treq_out,
fr_trunk_connection_t tconn 
)

Pop a cancellation request off a connection's cancellation queue.

The request we return is advanced by the request moving out of the cancel state and into the cancel_sent or cancel_complete state.

One of these signalling functions must be called after the request has been popped:

Parameters
[out]treq_outto process
[in]tconnConnection to drain cancellation request from.
Returns
  • 1 if no more requests.
  • 0 if a new request was written to treq_out.
  • -1 if the connection was previously freed. Caller MUST NOT touch any memory or requests associated with the connection.
  • -2 if called outside of the cancel muxer.

Definition at line 3708 of file trunk.c.

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

◆ fr_trunk_connection_pop_request()

int fr_trunk_connection_pop_request ( fr_trunk_request_t **  treq_out,
fr_trunk_connection_t tconn 
)

Pop a request off a connection's pending queue.

The request we return is advanced by the request moving out of the partial or pending states, when the mux function signals us.

If the same request is returned again and again, it means the muxer isn't actually doing anything with the request we returned, and it's and error in the muxer code.

One of these signalling functions must be used after the request has been popped:

  • fr_trunk_request_signal_complete The request was completed. Either we got a synchronous response, or we knew the response without contacting an external server (cache).
  • fr_trunk_request_signal_fail Failed muxing the request due to a permanent issue, i.e. an invalid request.
  • fr_trunk_request_signal_partial Wrote part of a request. This request will be returned on the next call to this function so that the request_mux function can finish writing it. Only useful for stream type connections. Datagram type connections cannot have partial writes.
  • fr_trunk_request_signal_sent Successfully sent a request.
Parameters
[out]treq_outto process
[in]tconnto pop a request from.
Returns
  • 1 if no more requests.
  • 0 if a new request was written to treq_out.
  • -1 if the connection was previously freed. Caller MUST NOT touch any memory or requests associated with the connection.
  • -2 if called outside of the muxer.

Definition at line 3756 of file trunk.c.

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

◆ fr_trunk_connection_requests_requeue()

uint64_t fr_trunk_connection_requests_requeue ( fr_trunk_connection_t tconn,
int  states,
uint64_t  max,
bool  fail_bound 
)

Move requests off of a connection and requeue elsewhere.

Note
We don't re-queue on draining or draining to free, as requests should have already been moved off of the connection. It's also dangerous as the trunk management code main clean up a connection in this state when it's run on re-queue, and then the caller may try and access a now freed connection.
Parameters
[in]tconnto move requests off of.
[in]statesOnly move requests in this state.
[in]maxThe maximum number of requests to dequeue. 0 for unlimited.
[in]fail_boundIf true causes any requests bound to the connection to fail. If false bound requests will not be moved.
Returns
The number of requests requeued.

Definition at line 1933 of file trunk.c.

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

◆ fr_trunk_connection_search()

bool fr_trunk_connection_search ( fr_trunk_connection_t tconn,
void *  ptr 
)

Definition at line 5025 of file trunk.c.

◆ fr_trunk_connection_signal_active()

void fr_trunk_connection_signal_active ( fr_trunk_connection_t tconn)

Signal a trunk connection is no longer full.

Parameters
[in]tconnto signal.

Definition at line 3833 of file trunk.c.

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

◆ fr_trunk_connection_signal_inactive()

void fr_trunk_connection_signal_inactive ( fr_trunk_connection_t tconn)

Signal a trunk connection cannot accept more requests.

Parameters
[in]tconnto signal.

Definition at line 3810 of file trunk.c.

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

◆ fr_trunk_connection_signal_readable()

void fr_trunk_connection_signal_readable ( fr_trunk_connection_t tconn)

Signal that a trunk connection is readable.

Should be called from the 'read' I/O handler to signal that requests should be dequeued.

Parameters
[in]tconnto signal.

Definition at line 3794 of file trunk.c.

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

◆ fr_trunk_connection_signal_reconnect()

void fr_trunk_connection_signal_reconnect ( fr_trunk_connection_t tconn,
fr_connection_reason_t  reason 
)

Signal a trunk connection is no longer viable.

Parameters
[in]tconnto signal.
[in]reasonthe connection is being reconnected.

Definition at line 3872 of file trunk.c.

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

◆ fr_trunk_connection_signal_writable()

void fr_trunk_connection_signal_writable ( fr_trunk_connection_t tconn)

Signal that a trunk connection is writable.

Should be called from the 'write' I/O handler to signal that requests can be enqueued.

Parameters
[in]tconnto signal.

Definition at line 3776 of file trunk.c.

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

◆ fr_trunk_connection_verify()

void fr_trunk_connection_verify ( char const *  file,
int  line,
fr_trunk_connection_t tconn 
)

Definition at line 4909 of file trunk.c.

◆ fr_trunk_del_watch()

int fr_trunk_del_watch ( fr_trunk_t trunk,
fr_trunk_state_t  state,
fr_trunk_watch_t  watch 
)

Remove a watch function from a trunk state list.

Parameters
[in]trunkThe trunk to remove the watcher from.
[in]stateto remove the watch from.
[in]watchFunction to remove.
Returns
  • 0 if the function was removed successfully.
  • -1 if the function wasn't present in the watch list.
  • -2 if an invalid state was passed.

Definition at line 812 of file trunk.c.

+ Here is the call graph for this function:

◆ fr_trunk_reconnect()

void fr_trunk_reconnect ( fr_trunk_t trunk,
int  states,
fr_connection_reason_t  reason 
)

Force the trunk to re-establish its connections.

Parameters
[in]trunkto signal.
[in]statesOne or more states or'd together.
[in]reasonWhy the connections are being signalled to reconnect.

Definition at line 4557 of file trunk.c.

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

◆ fr_trunk_request_alloc()

fr_trunk_request_t* fr_trunk_request_alloc ( fr_trunk_t trunk,
request_t request 
)

(Pre-)Allocate a new trunk request

If trunk->conf.req_pool_headers or trunk->conf.req_pool_size are not zero then the request will be a talloc pool, which can be used to hold the preq.

Note
Do not use MEM to check the result of this allocated as it may fail for non-fatal reasons.
Parameters
[in]trunkto add request to.
[in]requestto wrap in a trunk request (treq).
Returns
  • A newly allocated request.
  • NULL if too many requests are allocated.

Definition at line 2369 of file trunk.c.

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

◆ fr_trunk_request_count_by_connection()

uint32_t fr_trunk_request_count_by_connection ( fr_trunk_connection_t const *  tconn,
int  req_state 
)

Return the count number of requests associated with a trunk connection.

Parameters
[in]tconnto return request count for.
[in]req_stateOne or more request states or'd together.
Returns
The number of requests in the specified states, associated with a tconn.

Definition at line 2767 of file trunk.c.

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

◆ fr_trunk_request_count_by_state()

uint64_t fr_trunk_request_count_by_state ( fr_trunk_t trunk,
int  conn_state,
int  req_state 
)

Return a count of requests on a connection in a specific state.

Parameters
[in]trunkto retrieve counts for.
[in]conn_stateOne or more connection states or'd together.
[in]req_stateOne or more request states or'd together.
Returns
The number of requests in a particular state, on connection in a particular state.

Definition at line 4354 of file trunk.c.

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

◆ fr_trunk_request_enqueue()

fr_trunk_enqueue_t fr_trunk_request_enqueue ( fr_trunk_request_t **  treq_out,
fr_trunk_t trunk,
request_t request,
void *  preq,
void *  rctx 
)

Enqueue a request that needs data written to the trunk.

When a request_t * needs to make an asynchronous request to an external datastore it should call this function, specifying a preq (protocol request) containing the data necessary to request information from the external datastore, and an rctx (resume ctx) used to hold the decoded response and/or any error codes.

After a treq is successfully enqueued it will either be assigned immediately to the pending queue of a connection, or if no connections are available, (depending on the trunk configuration) the treq will be placed in the trunk's global backlog.

After receiving a positive return code from this function the caller should immediately yield, to allow the various timers and I/O handlers that drive tconn (trunk connection) and treq state changes to be called.

When a tconn becomes writable (or the trunk is configured to be always writable) the fr_trunk_request_mux_t callback will be called to dequeue, encode and send any pending requests for that tconn. The fr_trunk_request_mux_t callback is also responsible for tracking the outbound requests to allow the fr_trunk_request_demux_t callback to match inbound responses with the original treq. Once the fr_trunk_request_mux_t callback is done processing the treq it signals what state the treq should enter next using one of the fr_trunk_request_signal_* functions.

When a tconn becomes readable the user specified fr_trunk_request_demux_t callback is called to process any responses, match them with the original treq. and signal what state they should enter next using one of the fr_trunk_request_signal_* functions.

Parameters
[in,out]treq_outA trunk request handle. If the memory pointed to is NULL, a new treq will be allocated. Otherwise treq should point to memory allocated with fr_trunk_request_alloc.
[in]trunkto enqueue request on.
[in]requestto enqueue.
[in]preqProtocol request to write out. Will be freed when treq is freed. Should ideally be parented by the treq if possible. Use fr_trunk_request_alloc for pre-allocation of the treq.
[in]rctxThe resume context to write any result to.
Returns
  • FR_TRUNK_ENQUEUE_OK.
  • FR_TRUNK_ENQUEUE_IN_BACKLOG.
  • FR_TRUNK_ENQUEUE_NO_CAPACITY.
  • FR_TRUNK_ENQUEUE_DST_UNAVAILABLE
  • FR_TRUNK_ENQUEUE_FAIL

Definition at line 2481 of file trunk.c.

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

◆ fr_trunk_request_enqueue_on_conn()

fr_trunk_enqueue_t fr_trunk_request_enqueue_on_conn ( fr_trunk_request_t **  treq_out,
fr_trunk_connection_t tconn,
request_t request,
void *  preq,
void *  rctx,
bool  ignore_limits 
)

Enqueue additional requests on a specific connection.

This may be used to create a series of requests on a single connection, or to generate in-band status checks.

Note
If conf->always_writable, then the muxer will be called immediately. The caller must be able to handle multiple calls to its muxer gracefully.
Parameters
[in,out]treq_outA trunk request handle. If the memory pointed to is NULL, a new treq will be allocated. Otherwise treq should point to memory allocated with fr_trunk_request_alloc.
[in]tconnto enqueue request on.
[in]requestto enqueue.
[in]preqProtocol request to write out. Will be freed when treq is freed. Should ideally be parented by the treq if possible. Use fr_trunk_request_alloc for pre-allocation of the treq.
[in]rctxThe resume context to write any result to.
[in]ignore_limitsIgnore max_req_per_conn. Useful to force status checks through even if the connection is at capacity. Will also allow enqueuing on "inactive", "draining", "draining-to-free" connections.
Returns
  • FR_TRUNK_ENQUEUE_OK.
  • FR_TRUNK_ENQUEUE_NO_CAPACITY - At max_req_per_conn_limit
  • FR_TRUNK_ENQUEUE_DST_UNAVAILABLE - Connection cannot service requests.

Definition at line 2629 of file trunk.c.

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

◆ fr_trunk_request_free()

void fr_trunk_request_free ( fr_trunk_request_t **  treq_to_free)

If the trunk request is freed then update the target requests.

gperftools showed calling the request free function directly was slightly faster than using talloc_free.

Parameters
[in]treq_to_freerequest.

Definition at line 2217 of file trunk.c.

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

◆ fr_trunk_request_requeue()

fr_trunk_enqueue_t fr_trunk_request_requeue ( fr_trunk_request_t treq)

Re-enqueue a request on the same connection.

If the treq has been sent, we assume that we're being signalled to requeue because something outside of the trunk API has determined that a retransmission is required. The easiest way to perform that retransmission is to clean up any tracking information for the request, and the requeue it for transmission.

IF re-queueing fails, the request will enter the fail state. It should not be accessed if this occurs.

Parameters
[in]treqto requeue (retransmit).
Returns
  • FR_TRUNK_ENQUEUE_OK.
  • FR_TRUNK_ENQUEUE_DST_UNAVAILABLE - Connection cannot service requests.
  • FR_TRUNK_ENQUEUE_FAIL - Request isn't in a valid state to be reassigned.

Definition at line 2568 of file trunk.c.

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

◆ fr_trunk_request_search()

bool fr_trunk_request_search ( fr_trunk_request_t treq,
void *  ptr 
)

Definition at line 5083 of file trunk.c.

◆ fr_trunk_request_signal_cancel()

void fr_trunk_request_signal_cancel ( fr_trunk_request_t treq)

Cancel a trunk request.

treq can be in any state, but requests to cancel if the treq is not in the FR_TRUNK_REQUEST_STATE_PARTIAL or FR_TRUNK_REQUEST_STATE_SENT state will be ignored.

The complete or failed callbacks will not be called here, as it's assumed the request_t * is now inviable as it's being cancelled.

The free function however, is called, and that should be used to perform necessary cleanup.

Parameters
[in]treqto signal state change for.

Definition at line 2047 of file trunk.c.

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

◆ fr_trunk_request_signal_cancel_complete()

void fr_trunk_request_signal_cancel_complete ( fr_trunk_request_t treq)

Signal that a remote server acked our cancellation.

Called from request_demux to indicate that it got an ack for the cancellation.

Parameters
[in]treqto signal state change for.

Definition at line 2179 of file trunk.c.

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

◆ fr_trunk_request_signal_cancel_partial()

void fr_trunk_request_signal_cancel_partial ( fr_trunk_request_t treq)

Signal a partial cancel write.

Where there's high load, and the outbound write buffer is full

Parameters
[in]treqto signal state change for.

Definition at line 2131 of file trunk.c.

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

◆ fr_trunk_request_signal_cancel_sent()

void fr_trunk_request_signal_cancel_sent ( fr_trunk_request_t treq)

Signal that a remote server has been notified of the cancellation.

Called from request_cancel_mux to indicate that the datastore has been informed that the response is no longer needed.

Parameters
[in]treqto signal state change for.

Definition at line 2155 of file trunk.c.

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

◆ fr_trunk_request_signal_complete()

void fr_trunk_request_signal_complete ( fr_trunk_request_t treq)

Signal that a trunk request is complete.

The API client will be informed that the request is now complete.

Definition at line 1995 of file trunk.c.

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

◆ fr_trunk_request_signal_fail()

void fr_trunk_request_signal_fail ( fr_trunk_request_t treq)

Signal that a trunk request failed.

The API client will be informed that the request has failed.

Definition at line 2027 of file trunk.c.

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

◆ fr_trunk_request_signal_partial()

void fr_trunk_request_signal_partial ( fr_trunk_request_t treq)

Signal a partial write.

Where there's high load, and the outbound write buffer is full

Parameters
[in]treqto signal state change for.

Definition at line 1952 of file trunk.c.

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

◆ fr_trunk_request_signal_sent()

void fr_trunk_request_signal_sent ( fr_trunk_request_t treq)

Signal that the request was written to a connection successfully.

Parameters
[in]treqto signal state change for.

Definition at line 1973 of file trunk.c.

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

◆ fr_trunk_request_state_log()

void fr_trunk_request_state_log ( fr_log_t const *  log,
fr_log_type_t  log_type,
char const *  file,
int  line,
fr_trunk_request_t const *  treq 
)

Definition at line 2716 of file trunk.c.

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

◆ fr_trunk_request_verify()

void fr_trunk_request_verify ( char const *  file,
int  line,
fr_trunk_request_t treq 
)

Definition at line 4969 of file trunk.c.

+ Here is the call graph for this function:

◆ fr_trunk_search()

bool fr_trunk_search ( fr_trunk_t trunk,
void *  ptr 
)

Definition at line 4980 of file trunk.c.

◆ fr_trunk_start()

int fr_trunk_start ( fr_trunk_t trunk)

Start the trunk running.

Definition at line 4596 of file trunk.c.

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

◆ fr_trunk_verify()

void fr_trunk_verify ( char const *  file,
int  line,
fr_trunk_t trunk 
)

Verify a trunk.

A trunk has some number of connections, which each have some number of requests. The connections and requests are in differing kinds of containers depending on their state and how they are used, and may have fields that can only be validated by comparison with a parent. We had planned on passing a "context" down with the ancestral values, but that breaks the foo_verify() API. Each foo_verify() will only verify the foo's children.

Definition at line 4848 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_backlog_drain()

static void trunk_backlog_drain ( fr_trunk_t trunk)
static

Drain the backlog of as many requests as possible.

Parameters
[in]trunkTo drain backlog requests for.

Definition at line 4502 of file trunk.c.

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

◆ trunk_connection_auto_full()

static void trunk_connection_auto_full ( fr_trunk_connection_t tconn)
inlinestatic

Automatically mark a connection as inactive.

Parameters
[in]tconnto potentially mark as inactive.

Definition at line 2785 of file trunk.c.

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

◆ trunk_connection_auto_unfull()

static void trunk_connection_auto_unfull ( fr_trunk_connection_t tconn)
inlinestatic

Automatically mark a connection as active or reconnect it.

Parameters
[in]tconnto potentially mark as active or reconnect.

Definition at line 2826 of file trunk.c.

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

◆ trunk_connection_close_if_empty()

static void trunk_connection_close_if_empty ( fr_trunk_t trunk,
fr_dlist_head_t head 
)
static

Close connections in a particular connection list if they have no requests associated with them.

Parameters
[in]trunkcontaining connections we want to close.
[in]headof list of connections to examine.

Definition at line 3930 of file trunk.c.

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

◆ trunk_connection_enter_active()

static void trunk_connection_enter_active ( fr_trunk_connection_t tconn)
static

Transition a connection back to the active state.

This should only be called on a connection which is in the full state, inactive state, draining state or connecting state.

Definition at line 3133 of file trunk.c.

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

◆ trunk_connection_enter_draining()

static void trunk_connection_enter_draining ( fr_trunk_connection_t tconn)
static

Transition a connection to the draining state.

Removes the connection from the active heap so it won't be assigned any new connections.

Definition at line 3067 of file trunk.c.

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

◆ trunk_connection_enter_draining_to_free()

static void trunk_connection_enter_draining_to_free ( fr_trunk_connection_t tconn)
static

Transition a connection to the draining-to-reconnect state.

Removes the connection from the active heap so it won't be assigned any new connections.

Definition at line 3099 of file trunk.c.

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

◆ trunk_connection_enter_full()

static void trunk_connection_enter_full ( fr_trunk_connection_t tconn)
static

Transition a connection to the full state.

Called whenever a trunk connection is at the maximum number of requests. Removes the connection from the connected heap, and places it in the full list.

Definition at line 2992 of file trunk.c.

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

◆ trunk_connection_enter_inactive()

static void trunk_connection_enter_inactive ( fr_trunk_connection_t tconn)
static

Transition a connection to the inactive state.

Called whenever the API client wants to stop new requests being enqueued on a trunk connection.

Definition at line 3014 of file trunk.c.

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

◆ trunk_connection_enter_inactive_draining()

static void trunk_connection_enter_inactive_draining ( fr_trunk_connection_t tconn)
static

Transition a connection to the inactive-draining state.

Called whenever the trunk manager wants to drain an inactive connection of its requests.

Definition at line 3037 of file trunk.c.

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

◆ trunk_connection_event_update()

static void trunk_connection_event_update ( fr_trunk_connection_t tconn)
static

Update the registrations for I/O events we're interested in.

Definition at line 2872 of file trunk.c.

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

◆ trunk_connection_is_full()

static bool trunk_connection_is_full ( fr_trunk_connection_t tconn)
inlinestatic

Return whether a trunk connection should currently be considered full.

Parameters
[in]tconnto check.
Returns
  • true if the connection is full.
  • false if the connection is not full.

Definition at line 2808 of file trunk.c.

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

◆ trunk_connection_readable()

static void trunk_connection_readable ( fr_trunk_connection_t tconn)
inlinestatic

A connection is readable.

Call the request_demux function to read pending requests

Definition at line 2839 of file trunk.c.

+ Here is the caller graph for this function:

◆ trunk_connection_remove()

static void trunk_connection_remove ( fr_trunk_connection_t tconn)
static

Remove a trunk connection from whichever list it's currently in.

Parameters
[in]tconnto remove.

Definition at line 2936 of file trunk.c.

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

◆ trunk_connection_requests_dequeue()

static uint64_t trunk_connection_requests_dequeue ( fr_dlist_head_t out,
fr_trunk_connection_t tconn,
int  states,
uint64_t  max 
)
static

Shift requests in the specified states onto new connections.

This function will blindly dequeue any requests in the specified state and get them back to the unassigned state, cancelling any sent or partially sent requests.

This function does not check that dequeuing a request in a particular state is a sane or sensible thing to do, that's up to the caller!

Parameters
[out]outA list to insert the newly dequeued and unassigned requests into.
[in]tconnto dequeue requests from.
[in]statesDequeue request in these states.
[in]maxThe maximum number of requests to dequeue. 0 for unlimited.

Definition at line 1659 of file trunk.c.

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

◆ trunk_connection_requests_requeue()

static uint64_t trunk_connection_requests_requeue ( fr_trunk_connection_t tconn,
int  states,
uint64_t  max,
bool  fail_bound 
)
static

Remove requests in specified states from a connection, attempting to distribute them to new connections.

Parameters
[in]tconnTo remove requests from.
[in]statesOne or more states or'd together.
[in]maxThe maximum number of requests to dequeue. 0 for unlimited.
[in]fail_boundIf true causes any requests bound to the connection to fail. If false bound requests will not be moved.
Returns
the number of requests re-queued.

Definition at line 1770 of file trunk.c.

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

◆ trunk_connection_spawn()

static int trunk_connection_spawn ( fr_trunk_t trunk,
fr_time_t  now 
)
static

Attempt to spawn a new connection.

Calls the API client's alloc() callback to create a new fr_connection_t, then inserts the connection into the 'connecting' list.

Parameters
[in]trunkto spawn connection in.
[in]nowThe current time.

Definition at line 3622 of file trunk.c.

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

◆ trunk_connection_writable()

static void trunk_connection_writable ( fr_trunk_connection_t tconn)
inlinestatic

A connection is writable.

Call the request_mux function to write pending requests

Definition at line 2849 of file trunk.c.

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

◆ trunk_manage()

static void trunk_manage ( fr_trunk_t trunk,
fr_time_t  now 
)
static

Implements the algorithm we use to manage requests per connection levels.

This is executed periodically using a timer event, and opens/closes connections.

The aim is to try and keep the request per connection level in a sweet spot, where there's enough outstanding work for the connection/pipelining to work efficiently, but not so much so that we encounter increased latency.

In the request enqueue and dequeue functions we record every time the average number of requests per connection goes above the target count and record every time the average number of requests per connection goes below the target count.

This may sound expensive, but in all cases we're just summing counters. CPU time required does not increase with additional requests, only with large numbers of connections.

If we do encounter scaling issues, we can always maintain the counters as aggregates as an optimisation later.

If when the management function runs, the trunk was above the target most recently, we:

  • Return if we've been in this state for a shorter period than 'open_delay'.
  • Return if we're at max.
  • Return if opening a new connection will take us below the load target.
  • Return if we last opened a connection within 'open_delay'.
  • Otherwise we attempt to open a new connection.

If the trunk we below the target most recently, we:

  • Return if we've been in this state for a shorter period than 'close_delay'.
  • Return if we're at min.
  • Return if we have no connections.
  • Close a connection if min is 0, and we have no outstanding requests. Then return.
  • Return if closing a new connection will take us above the load target.
  • Return if we last closed a connection within 'closed_delay'.
  • Otherwise we move a connection to draining state.

Definition at line 4036 of file trunk.c.

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

◆ trunk_rebalance()

static void trunk_rebalance ( fr_trunk_t trunk)
static

Rebalance connections across active trunk members when a new connection becomes active.

We don't have any visibility into the connection prioritisation algorithm it's essentially a black box.

We can however determine when the correct level of requests per connection has been reached, by dequeuing and requeing requests up until the point where the connection that just had a request dequeued, receives the same request back.

Parameters
[in]trunkThe trunk to rebalance.

Definition at line 3972 of file trunk.c.

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

◆ trunk_request_check_enqueue()

static fr_trunk_enqueue_t trunk_request_check_enqueue ( fr_trunk_connection_t **  tconn_out,
fr_trunk_t trunk,
request_t request 
)
static

Check to see if a trunk request can be enqueued.

Parameters
[out]tconn_outConnection the request may be enqueued on.
[in]trunkTo enqueue requests on.
[in]requestassociated with the treq (if any).
Returns
  • FR_TRUNK_ENQUEUE_OK caller should enqueue request on provided tconn.
  • FR_TRUNK_ENQUEUE_IN_BACKLOG Request should be queued in the backlog.
  • FR_TRUNK_ENQUEUE_NO_CAPACITY Unable to enqueue request as we have no spare connections or backlog space.
  • FR_TRUNK_ENQUEUE_DST_UNAVAILABLE Can't enqueue because the destination is unreachable.

Definition at line 1525 of file trunk.c.

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

◆ trunk_request_enqueue_existing()

static fr_trunk_enqueue_t trunk_request_enqueue_existing ( fr_trunk_request_t treq)
static

Enqueue a request which has never been assigned to a connection or was previously cancelled.

Parameters
[in]treqto re enqueue. Must have been removed from its existing connection with trunk_connection_requests_dequeue.
Returns
  • FR_TRUNK_ENQUEUE_OK Request was re-enqueued.
  • FR_TRUNK_ENQUEUE_NO_CAPACITY Request enqueueing failed because we're at capacity.
  • FR_TRUNK_ENQUEUE_DST_UNAVAILABLE Enqueuing failed for some reason. Usually because the connection to the resource is down.

Definition at line 1602 of file trunk.c.

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

◆ trunk_request_enter_backlog()

static void trunk_request_enter_backlog ( fr_trunk_request_t treq,
bool  new 
)
static

Transition a request to the backlog state, adding it to the backlog of the trunk.

Note
treq->tconn and treq may be inviable after calling if treq->conn and fr_connection_signals_pause are not used. This is due to call to trunk_manage.
Parameters
[in]treqto trigger a state change for.
[in]newWhether this is a new request.

Definition at line 1068 of file trunk.c.

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

◆ trunk_request_enter_cancel()

static void trunk_request_enter_cancel ( fr_trunk_request_t treq,
fr_trunk_cancel_reason_t  reason 
)
static

Transition a request to the cancel state, placing it in a connection's cancellation list.

If a request_cancel_send callback is provided, that callback will be called periodically for requests which were cancelled due to a signal.

The request_cancel_send callback will dequeue cancelled requests and inform a remote server that the result is no longer required.

A request must enter this state before being added to the backlog of another connection if it's been sent or partially sent.

Note
treq->tconn and treq may be inviable after calling if treq->conn and fr_connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.
[in]reasonWhy the request was cancelled. Should be one of:
  • FR_TRUNK_CANCEL_REASON_SIGNAL request cancelled because of a signal from the interpreter.
  • FR_TRUNK_CANCEL_REASON_MOVE request cancelled because the connection failed and it needs to be assigned to a new connection.
  • FR_TRUNK_CANCEL_REASON_REQUEUE request cancelled as it needs to be resent on the same connection.

Definition at line 1301 of file trunk.c.

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

◆ trunk_request_enter_cancel_complete()

static void trunk_request_enter_cancel_complete ( fr_trunk_request_t treq)
static

Cancellation was acked, the request is complete, free it.

The API client will not be informed, as the original request_t * will likely have been freed by this point.

Note
treq will be inviable after a call to this function. treq->tconn may be inviable after calling if treq->conn and fr_connection_signals_pause is not used. This is due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto mark as complete.

Definition at line 1428 of file trunk.c.

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

◆ trunk_request_enter_cancel_partial()

static void trunk_request_enter_cancel_partial ( fr_trunk_request_t treq)
static

Transition a request to the cancel_partial state, placing it in a connection's cancel_partial slot.

The request_demux function is then responsible for signalling that the cancel request is complete when the remote server acknowledges the cancellation request.

Parameters
[in]treqto trigger a state change for.

Definition at line 1348 of file trunk.c.

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

◆ trunk_request_enter_cancel_sent()

static void trunk_request_enter_cancel_sent ( fr_trunk_request_t treq)
static

Transition a request to the cancel_sent state, placing it in a connection's cancel_sent list.

The request_demux function is then responsible for signalling that the cancel request is complete when the remote server acknowledges the cancellation request.

Note
treq->tconn and treq may be inviable after calling if treq->conn and fr_connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.

Definition at line 1383 of file trunk.c.

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

◆ trunk_request_enter_complete()

static void trunk_request_enter_complete ( fr_trunk_request_t treq)
static

Request completed successfully, inform the API client and free the request.

Note
treq will be inviable after a call to this function. treq->tconn may also be inviable due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto mark as complete.

Definition at line 1459 of file trunk.c.

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

◆ trunk_request_enter_failed()

static void trunk_request_enter_failed ( fr_trunk_request_t treq)
static

Request failed, inform the API client and free the request.

Note
treq will be inviable after a call to this function. treq->tconn may also be inviable due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto mark as failed.

Definition at line 1489 of file trunk.c.

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

◆ trunk_request_enter_partial()

static void trunk_request_enter_partial ( fr_trunk_request_t treq)
static

Transition a request to the partial state, indicating that is has been partially sent.

Parameters
[in]treqto trigger a state change for.

Definition at line 1201 of file trunk.c.

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

◆ trunk_request_enter_pending()

static void trunk_request_enter_pending ( fr_trunk_request_t treq,
fr_trunk_connection_t tconn,
bool  new 
)
static

Transition a request to the pending state, adding it to the backlog of an active connection.

All trunk requests being added to a connection get passed to this function. All trunk requests being removed from a connection get passed to trunk_request_remove_from_conn.

Note
treq->tconn and treq may be inviable after calling if treq->conn and fr_connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.
[in]tconnto enqueue the request on.
[in]newWhether this is a new request.

Definition at line 1130 of file trunk.c.

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

◆ trunk_request_enter_sent()

static void trunk_request_enter_sent ( fr_trunk_request_t treq)
static

Transition a request to the sent state, indicating that it's been sent in its entirety.

Note
treq->tconn and treq may be inviable after calling if treq->conn and fr_connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.

Definition at line 1231 of file trunk.c.

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

◆ trunk_request_enter_unassigned()

static void trunk_request_enter_unassigned ( fr_trunk_request_t treq)
static

Transition a request to the unassigned state, in preparation for re-assignment.

Note
treq->tconn may be inviable after calling if treq->conn and fr_connection_signals_pause are not used. This is due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto trigger a state change for.

Definition at line 1033 of file trunk.c.

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

◆ trunk_request_remove_from_conn()

static void trunk_request_remove_from_conn ( fr_trunk_request_t treq)
static

Remove a request from all connection lists.

A common function used by init, fail, complete state functions to disassociate a request from a connection in preparation for freeing or reassignment.

Despite its unassuming name, this function is the place to put calls to functions which need to be called when the number of requests associated with a connection changes.

Trunk requests will always be passed to this function before they're removed from a connection, even if the requests are being freed.

Parameters
[in]treqto trigger a state change for.

Definition at line 943 of file trunk.c.

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

◆ trunk_request_state_log_entry_add()

void trunk_request_state_log_entry_add ( char const *  function,
int  line,
fr_trunk_request_t treq,
fr_trunk_request_state_t  new 
)

Definition at line 2685 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_requests_per_connection()

static uint64_t trunk_requests_per_connection ( uint16_t conn_count_out,
uint32_t req_count_out,
fr_trunk_t trunk,
fr_time_t  now,
NDEBUG_UNUSED bool  verify 
)
static

Update timestamps for when we last had a transition from above target to below target or vice versa.

Should be called on every time a connection or request is allocated or freed.

Parameters
[out]conn_count_outHow many connections we considered.
[out]req_count_outHow many requests we considered.
[in]trunkto operate on.
[in]nowThe current time.
[in]verifyif true (and this is a debug build), then assert if req_per_conn has changed.
Returns
  • 0 if the average couldn't be calculated (no requests or no connections).
  • The average number of requests per connection.

Definition at line 4403 of file trunk.c.

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

◆ trunk_watch_call()

static void trunk_watch_call ( fr_trunk_t trunk,
fr_dlist_head_t list,
fr_trunk_state_t  state 
)
inlinestatic

Call a list of watch functions associated with a state.

Definition at line 770 of file trunk.c.

+ Here is the call graph for this function:

Variable Documentation

◆ fr_trunk_cancellation_reasons

fr_table_num_ordered_t const fr_trunk_cancellation_reasons[]
static
Initial value:
= {
{ L("FR_TRUNK_CANCEL_REASON_NONE"), FR_TRUNK_CANCEL_REASON_NONE },
{ L("FR_TRUNK_CANCEL_REASON_SIGNAL"), FR_TRUNK_CANCEL_REASON_SIGNAL },
{ L("FR_TRUNK_CANCEL_REASON_MOVE"), FR_TRUNK_CANCEL_REASON_MOVE },
{ L("FR_TRUNK_CANCEL_REASON_REQUEUE"), FR_TRUNK_CANCEL_REASON_REQUEUE }
}
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
@ FR_TRUNK_CANCEL_REASON_SIGNAL
Request cancelled due to a signal.
Definition: trunk.h:57
@ FR_TRUNK_CANCEL_REASON_MOVE
Request cancelled because it's being moved.
Definition: trunk.h:58
@ FR_TRUNK_CANCEL_REASON_REQUEUE
A previously sent request is being requeued.
Definition: trunk.h:59
@ FR_TRUNK_CANCEL_REASON_NONE
Request has not been cancelled.
Definition: trunk.h:56

Definition at line 403 of file trunk.c.

◆ fr_trunk_cancellation_reasons_len

size_t fr_trunk_cancellation_reasons_len = NUM_ELEMENTS(fr_trunk_cancellation_reasons)
static

Definition at line 409 of file trunk.c.

◆ fr_trunk_config

conf_parser_t const fr_trunk_config[]
Initial value:
= {
{ FR_CONF_OFFSET("start", fr_trunk_conf_t, start), .dflt = "5" },
{ FR_CONF_OFFSET("min", fr_trunk_conf_t, min), .dflt = "1" },
{ FR_CONF_OFFSET("max", fr_trunk_conf_t, max), .dflt = "5" },
{ FR_CONF_OFFSET("connecting", fr_trunk_conf_t, connecting), .dflt = "2" },
{ FR_CONF_OFFSET("uses", fr_trunk_conf_t, max_uses), .dflt = "0" },
{ FR_CONF_OFFSET("lifetime", fr_trunk_conf_t, lifetime), .dflt = "0" },
{ FR_CONF_OFFSET("open_delay", fr_trunk_conf_t, open_delay), .dflt = "0.2" },
{ FR_CONF_OFFSET("close_delay", fr_trunk_conf_t, close_delay), .dflt = "10.0" },
{ FR_CONF_OFFSET("manage_interval", fr_trunk_conf_t, manage_interval), .dflt = "0.2" },
{ FR_CONF_OFFSET_SUBSECTION("connection", 0, fr_trunk_conf_t, conn_conf, fr_trunk_config_connection), .subcs_size = sizeof(fr_trunk_config_connection) },
{ FR_CONF_POINTER("request", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) fr_trunk_config_request },
}
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition: cf_parse.h:310
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition: cf_parse.h:297
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition: cf_parse.h:400
static size_t min(size_t x, size_t y)
Definition: sbuff.c:135
static conf_parser_t const fr_trunk_config_request[]
Definition: trunk.c:290
static conf_parser_t const fr_trunk_config_connection[]
Definition: trunk.c:298
Common configuration parameters for a trunk.
Definition: trunk.h:213

Config parser definitions to populate a fr_trunk_conf_t.

Definition at line 306 of file trunk.c.

◆ fr_trunk_config_connection

conf_parser_t const fr_trunk_config_connection[]
static
Initial value:
= {
{ FR_CONF_OFFSET("connect_timeout", fr_connection_conf_t, connection_timeout), .dflt = "3.0" },
{ FR_CONF_OFFSET("reconnect_delay", fr_connection_conf_t, reconnection_delay), .dflt = "1" },
}

Definition at line 298 of file trunk.c.

◆ fr_trunk_config_request

conf_parser_t const fr_trunk_config_request[]
static
Initial value:
= {
{ FR_CONF_OFFSET("per_connection_max", fr_trunk_conf_t, max_req_per_conn), .dflt = "2000" },
{ FR_CONF_OFFSET("per_connection_target", fr_trunk_conf_t, target_req_per_conn), .dflt = "1000" },
{ FR_CONF_OFFSET("free_delay", fr_trunk_conf_t, req_cleanup_delay), .dflt = "10.0" },
}

Definition at line 290 of file trunk.c.

◆ fr_trunk_conn_trigger_names

fr_table_num_indexed_bit_pos_t const fr_trunk_conn_trigger_names[]
static
Initial value:
= {
{ L("pool.connection_halted"), FR_TRUNK_CONN_HALTED },
{ L("pool.connection_init"), FR_TRUNK_CONN_INIT },
{ L("pool.connection_connecting"), FR_TRUNK_CONN_CONNECTING },
{ L("pool.connection_active"), FR_TRUNK_CONN_ACTIVE },
{ L("pool.connection_closed"), FR_TRUNK_CONN_CLOSED },
{ L("pool.connection_full"), FR_TRUNK_CONN_FULL },
{ L("pool.connection_inactive"), FR_TRUNK_CONN_INACTIVE },
{ L("pool.connection_inactive_draining"), FR_TRUNK_CONN_INACTIVE_DRAINING },
{ L("pool.connection_draining"), FR_TRUNK_CONN_DRAINING },
{ L("pool.connection_draining_to_free"), FR_TRUNK_CONN_DRAINING_TO_FREE }
}
@ FR_TRUNK_CONN_INACTIVE
Connection is inactive and can't accept any more requests.
Definition: trunk.h:96
@ FR_TRUNK_CONN_CLOSED
Connection was closed, either explicitly or due to failure.
Definition: trunk.h:94
@ FR_TRUNK_CONN_HALTED
Halted, ready to be freed.
Definition: trunk.h:88
@ FR_TRUNK_CONN_FULL
Connection is full and can't accept any more requests.
Definition: trunk.h:95
@ FR_TRUNK_CONN_CONNECTING
Connection is connecting.
Definition: trunk.h:90
@ FR_TRUNK_CONN_DRAINING_TO_FREE
Connection will be closed once it has no more outstanding requests.
Definition: trunk.h:103
@ FR_TRUNK_CONN_INACTIVE_DRAINING
Connection is inactive, can't accept any more requests, and will be closed once it has no more outsta...
Definition: trunk.h:97
@ FR_TRUNK_CONN_DRAINING
Connection will be closed once it has no more outstanding requests, if it's not reactivated.
Definition: trunk.h:101
@ FR_TRUNK_CONN_INIT
In the initial state.
Definition: trunk.h:89

Map connection states to trigger names.

Must stay in the same order as fr_trunk_connection_state_t

Definition at line 368 of file trunk.c.

◆ fr_trunk_conn_trigger_names_len

size_t fr_trunk_conn_trigger_names_len = NUM_ELEMENTS(fr_trunk_conn_trigger_names)
static

Definition at line 380 of file trunk.c.

◆ fr_trunk_connection_events

fr_table_num_ordered_t const fr_trunk_connection_events[]
static
Initial value:
= {
{ L("FR_TRUNK_CONN_EVENT_NONE"), FR_TRUNK_CONN_EVENT_NONE },
{ L("FR_TRUNK_CONN_EVENT_READ"), FR_TRUNK_CONN_EVENT_READ },
{ L("FR_TRUNK_CONN_EVENT_WRITE"), FR_TRUNK_CONN_EVENT_WRITE },
{ L("FR_TRUNK_CONN_EVENT_BOTH"), FR_TRUNK_CONN_EVENT_BOTH },
}
@ FR_TRUNK_CONN_EVENT_NONE
Don't notify the trunk on connection state changes.
Definition: trunk.h:73
@ FR_TRUNK_CONN_EVENT_WRITE
Trunk should be notified if a connection is writable.
Definition: trunk.h:77
@ FR_TRUNK_CONN_EVENT_READ
Trunk should be notified if a connection is readable.
Definition: trunk.h:75
@ FR_TRUNK_CONN_EVENT_BOTH
Trunk should be notified if a connection is readable or writable.
Definition: trunk.h:79

Definition at line 411 of file trunk.c.

◆ fr_trunk_connection_events_len

size_t fr_trunk_connection_events_len = NUM_ELEMENTS(fr_trunk_connection_events)
static

Definition at line 417 of file trunk.c.

◆ fr_trunk_connection_states

fr_table_num_ordered_t const fr_trunk_connection_states[]
static
Initial value:
= {
{ L("INIT"), FR_TRUNK_CONN_INIT },
{ L("HALTED"), FR_TRUNK_CONN_HALTED },
{ L("CONNECTING"), FR_TRUNK_CONN_CONNECTING },
{ L("ACTIVE"), FR_TRUNK_CONN_ACTIVE },
{ L("CLOSED"), FR_TRUNK_CONN_CLOSED },
{ L("FULL"), FR_TRUNK_CONN_FULL },
{ L("INACTIVE"), FR_TRUNK_CONN_INACTIVE },
{ L("INACTIVE-DRAINING"), FR_TRUNK_CONN_INACTIVE_DRAINING },
{ L("DRAINING"), FR_TRUNK_CONN_DRAINING },
{ L("DRAINING-TO-FREE"), FR_TRUNK_CONN_DRAINING_TO_FREE }
}

Definition at line 389 of file trunk.c.

◆ fr_trunk_connection_states_len

size_t fr_trunk_connection_states_len = NUM_ELEMENTS(fr_trunk_connection_states)
static

Definition at line 401 of file trunk.c.

◆ fr_trunk_req_trigger_names

fr_table_num_indexed_bit_pos_t const fr_trunk_req_trigger_names[]
static
Initial value:
= {
{ L("pool.request_init"), FR_TRUNK_REQUEST_STATE_INIT },
{ L("pool.request_unassigned"), FR_TRUNK_REQUEST_STATE_UNASSIGNED },
{ L("pool.request_backlog"), FR_TRUNK_REQUEST_STATE_BACKLOG },
{ L("pool.request_pending"), FR_TRUNK_REQUEST_STATE_PENDING },
{ L("pool.request_partial"), FR_TRUNK_REQUEST_STATE_PARTIAL },
{ L("pool.request_sent"), FR_TRUNK_REQUEST_STATE_SENT },
{ L("pool.request_complete"), FR_TRUNK_REQUEST_STATE_COMPLETE },
{ L("pool.request_state_failed"), FR_TRUNK_REQUEST_STATE_FAILED },
{ L("pool.request_state_cancel"), FR_TRUNK_REQUEST_STATE_CANCEL },
{ L("pool.request_state_cancel_sent"), FR_TRUNK_REQUEST_STATE_CANCEL_SENT },
{ L("pool.request_state_cancel_partial"), FR_TRUNK_REQUEST_STATE_CANCEL_PARTIAL },
{ L("pool.request_state_cancel_complete"), FR_TRUNK_REQUEST_STATE_CANCEL_COMPLETE }
}
@ FR_TRUNK_REQUEST_STATE_BACKLOG
In the backlog.
Definition: trunk.h:167
@ FR_TRUNK_REQUEST_STATE_CANCEL
A request on a particular socket was cancel.
Definition: trunk.h:175
@ FR_TRUNK_REQUEST_STATE_SENT
Was written to a socket. Waiting for a response.
Definition: trunk.h:172
@ FR_TRUNK_REQUEST_STATE_PENDING
In the queue of a connection and is pending writing.
Definition: trunk.h:168
@ FR_TRUNK_REQUEST_STATE_UNASSIGNED
Transition state - Request currently not assigned to any connection.
Definition: trunk.h:165
@ FR_TRUNK_REQUEST_STATE_CANCEL_SENT
We've informed the remote server that the request has been cancelled.
Definition: trunk.h:176
@ FR_TRUNK_REQUEST_STATE_FAILED
The request failed.
Definition: trunk.h:174
@ FR_TRUNK_REQUEST_STATE_CANCEL_COMPLETE
Remote server has acknowledged our cancellation.
Definition: trunk.h:179
@ FR_TRUNK_REQUEST_STATE_CANCEL_PARTIAL
We partially wrote a cancellation request.
Definition: trunk.h:178
@ FR_TRUNK_REQUEST_STATE_PARTIAL
Some of the request was written to the socket, more of it should be written later.
Definition: trunk.h:170
@ FR_TRUNK_REQUEST_STATE_INIT
Initial state.
Definition: trunk.h:162
@ FR_TRUNK_REQUEST_STATE_COMPLETE
The request is complete.
Definition: trunk.h:173

Map request states to trigger names.

Must stay in the same order as fr_trunk_connection_state_t

Definition at line 331 of file trunk.c.

◆ fr_trunk_req_trigger_names_len

size_t fr_trunk_req_trigger_names_len = NUM_ELEMENTS(fr_trunk_req_trigger_names)
static

Definition at line 345 of file trunk.c.

◆ fr_trunk_request_states

fr_table_num_ordered_t const fr_trunk_request_states[]
static
Initial value:

Definition at line 348 of file trunk.c.

◆ fr_trunk_request_states_len

size_t fr_trunk_request_states_len = NUM_ELEMENTS(fr_trunk_request_states)
static

Definition at line 362 of file trunk.c.

◆ fr_trunk_states

fr_table_num_ordered_t const fr_trunk_states[]
static
Initial value:
= {
{ L("IDLE"), FR_TRUNK_STATE_IDLE },
{ L("ACTIVE"), FR_TRUNK_STATE_ACTIVE },
{ L("PENDING"), FR_TRUNK_STATE_PENDING }
}
@ FR_TRUNK_STATE_IDLE
Trunk has no connections.
Definition: trunk.h:63
@ FR_TRUNK_STATE_ACTIVE
Trunk has active connections.
Definition: trunk.h:64
@ FR_TRUNK_STATE_PENDING
Trunk has connections, but none are active.
Definition: trunk.h:65

Definition at line 382 of file trunk.c.

◆ fr_trunk_states_len

size_t fr_trunk_states_len = NUM_ELEMENTS(fr_trunk_states)
static

Definition at line 387 of file trunk.c.

◆ request_counter

atomic_uint_fast64_t request_counter = ATOMIC_VAR_INIT(1)
static

Definition at line 52 of file trunk.c.