.TH "qbipcs.h" 3 "Fri Apr 26 2019" "Version 1.0.5" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME qbipcs.h \- Server IPC API\&. .SH SYNOPSIS .br .PP \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br .SS "Data Structures" .in +1c .ti -1c .RI "struct \fBqb_ipcs_stats\fP" .br .ti -1c .RI "struct \fBqb_ipcs_connection_stats\fP" .br .ti -1c .RI "struct \fBqb_ipcs_connection_stats_2\fP" .br .ti -1c .RI "struct \fBqb_ipcs_poll_handlers\fP" .br .ti -1c .RI "struct \fBqb_ipcs_service_handlers\fP" .br .in -1c .SS "Typedefs" .in +1c .ti -1c .RI "typedef struct qb_ipcs_connection \fBqb_ipcs_connection_t\fP" .br .ti -1c .RI "typedef struct qb_ipcs_service \fBqb_ipcs_service_t\fP" .br .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_dispatch_fn_t\fP) (int32_t fd, int32_t revents, void *data)" .br .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_dispatch_add_fn\fP) (enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" .br .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_dispatch_mod_fn\fP) (enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" .br .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_dispatch_del_fn\fP) (int32_t fd)" .br .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_job_add_fn\fP) (enum \fBqb_loop_priority\fP p, void *data, \fBqb_loop_job_dispatch_fn\fP dispatch_fn)" .br .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_connection_accept_fn\fP) (\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)" .br .RI "This callback is to check whether you want to accept a new connection\&. " .ti -1c .RI "typedef void(* \fBqb_ipcs_connection_created_fn\fP) (\fBqb_ipcs_connection_t\fP *c)" .br .RI "This is called after a new connection has been created\&. " .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_connection_closed_fn\fP) (\fBqb_ipcs_connection_t\fP *c)" .br .RI "This is called after a connection has been disconnected\&. " .ti -1c .RI "typedef void(* \fBqb_ipcs_connection_destroyed_fn\fP) (\fBqb_ipcs_connection_t\fP *c)" .br .RI "This is called just before a connection is freed\&. " .ti -1c .RI "typedef int32_t(* \fBqb_ipcs_msg_process_fn\fP) (\fBqb_ipcs_connection_t\fP *c, void *data, size_t size)" .br .RI "This is the message processing calback\&. " .in -1c .SS "Enumerations" .in +1c .ti -1c .RI "enum \fBqb_ipcs_rate_limit\fP { \fBQB_IPCS_RATE_FAST\fP, \fBQB_IPCS_RATE_NORMAL\fP, \fBQB_IPCS_RATE_SLOW\fP, \fBQB_IPCS_RATE_OFF\fP, \fBQB_IPCS_RATE_OFF_2\fP }" .br .in -1c .SS "Functions" .in +1c .ti -1c .RI "\fBqb_ipcs_service_t\fP * \fBqb_ipcs_create\fP (const char *name, int32_t service_id, enum \fBqb_ipc_type\fP type, struct \fBqb_ipcs_service_handlers\fP *handlers)" .br .RI "Create a new IPC server\&. " .ti -1c .RI "void \fBqb_ipcs_ref\fP (\fBqb_ipcs_service_t\fP *s)" .br .RI "Increase the reference counter on the service object\&. " .ti -1c .RI "void \fBqb_ipcs_unref\fP (\fBqb_ipcs_service_t\fP *s)" .br .RI "Decrease the reference counter on the service object\&. " .ti -1c .RI "void \fBqb_ipcs_poll_handlers_set\fP (\fBqb_ipcs_service_t\fP *s, struct \fBqb_ipcs_poll_handlers\fP *handlers)" .br .RI "Set your poll callbacks\&. " .ti -1c .RI "void \fBqb_ipcs_service_context_set\fP (\fBqb_ipcs_service_t\fP *s, void *context)" .br .RI "Associate a 'user' pointer with this service\&. " .ti -1c .RI "void * \fBqb_ipcs_service_context_get\fP (\fBqb_ipcs_service_t\fP *s)" .br .RI "Get the context (set previously) " .ti -1c .RI "int32_t \fBqb_ipcs_run\fP (\fBqb_ipcs_service_t\fP *s)" .br .RI "run the new IPC server\&. " .ti -1c .RI "void \fBqb_ipcs_destroy\fP (\fBqb_ipcs_service_t\fP *s)" .br .RI "Destroy the IPC server\&. " .ti -1c .RI "void \fBqb_ipcs_request_rate_limit\fP (\fBqb_ipcs_service_t\fP *s, enum \fBqb_ipcs_rate_limit\fP rl)" .br .RI "Limit the incoming request rate\&. " .ti -1c .RI "ssize_t \fBqb_ipcs_response_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_t size)" .br .RI "Send a response to a incoming request\&. " .ti -1c .RI "ssize_t \fBqb_ipcs_response_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_t iov_len)" .br .RI "Send a response to a incoming request\&. " .ti -1c .RI "ssize_t \fBqb_ipcs_event_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_t size)" .br .RI "Send an asynchronous event message to the client\&. " .ti -1c .RI "ssize_t \fBqb_ipcs_event_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_t iov_len)" .br .RI "Send an asynchronous event message to the client\&. " .ti -1c .RI "void \fBqb_ipcs_connection_ref\fP (\fBqb_ipcs_connection_t\fP *c)" .br .RI "Increment the connection's reference counter\&. " .ti -1c .RI "void \fBqb_ipcs_connection_unref\fP (\fBqb_ipcs_connection_t\fP *c)" .br .RI "Decrement the connection's reference counter\&. " .ti -1c .RI "void \fBqb_ipcs_disconnect\fP (\fBqb_ipcs_connection_t\fP *c)" .br .RI "Disconnect from this client\&. " .ti -1c .RI "int32_t \fBqb_ipcs_service_id_get\fP (\fBqb_ipcs_connection_t\fP *c)" .br .RI "Get the service id related to this connection's service\&. " .ti -1c .RI "void \fBqb_ipcs_context_set\fP (\fBqb_ipcs_connection_t\fP *c, void *context)" .br .RI "Associate a 'user' pointer with this connection\&. " .ti -1c .RI "void * \fBqb_ipcs_context_get\fP (\fBqb_ipcs_connection_t\fP *c)" .br .RI "Get the context (set previously) " .ti -1c .RI "void * \fBqb_ipcs_connection_service_context_get\fP (\fBqb_ipcs_connection_t\fP *c)" .br .RI "Get the context previously set on the service backing this connection\&. " .ti -1c .RI "int32_t \fBqb_ipcs_connection_stats_get\fP (\fBqb_ipcs_connection_t\fP *c, struct \fBqb_ipcs_connection_stats\fP *stats, int32_t clear_after_read)" .br .RI "Get the connection statistics\&. " .ti -1c .RI "struct \fBqb_ipcs_connection_stats_2\fP * \fBqb_ipcs_connection_stats_get_2\fP (\fBqb_ipcs_connection_t\fP *c, int32_t clear_after_read)" .br .RI "Get (and allocate) the connection statistics\&. " .ti -1c .RI "int32_t \fBqb_ipcs_stats_get\fP (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_t clear_after_read)" .br .RI "Get the service statistics\&. " .ti -1c .RI "\fBqb_ipcs_connection_t\fP * \fBqb_ipcs_connection_first_get\fP (\fBqb_ipcs_service_t\fP *pt)" .br .RI "Get the first connection\&. " .ti -1c .RI "\fBqb_ipcs_connection_t\fP * \fBqb_ipcs_connection_next_get\fP (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)" .br .RI "Get the next connection\&. " .ti -1c .RI "void \fBqb_ipcs_connection_auth_set\fP (\fBqb_ipcs_connection_t\fP *conn, uid_t uid, gid_t gid, mode_t mode)" .br .RI "Set the permissions on and shared memory files so that both processes can read and write to them\&. " .ti -1c .RI "int32_t \fBqb_ipcs_connection_get_buffer_size\fP (\fBqb_ipcs_connection_t\fP *conn)" .br .RI "Retrieve the connection ipc buffer size\&. " .ti -1c .RI "void \fBqb_ipcs_enforce_buffer_size\fP (\fBqb_ipcs_service_t\fP *s, uint32_t max_buf_size)" .br .RI "Enforce the max buffer size clients must use from the server side\&. " .in -1c .SH "Detailed Description" .PP Server IPC API\&. .SH "Typedef Documentation" .PP .SS "typedef int32_t(* qb_ipcs_connection_accept_fn) (\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)" .PP This callback is to check whether you want to accept a new connection\&. The type of checks you should do are authentication, service availability or process resource constraints\&. .PP \fBReturns:\fP .RS 4 0 to accept or -errno to indicate a failure (sent back to the client) .RE .PP \fBNote:\fP .RS 4 If connection state data is allocated as a result of this callback being invoked, that data must be freed in the destroy callback\&. Just because the accept callback returns 0, that does not guarantee the create and closed callback functions will follow\&. .PP you can call \fBqb_ipcs_connection_auth_set()\fP within this function\&. .RE .PP .SS "typedef int32_t(* qb_ipcs_connection_closed_fn) (\fBqb_ipcs_connection_t\fP *c)" .PP This is called after a connection has been disconnected\&. .PP \fBNote:\fP .RS 4 This callback will only be invoked if the connection is successfully created\&. .PP if you return anything but 0 this function will be repeatedly called (until 0 is returned)\&. .RE .PP .SS "typedef void(* qb_ipcs_connection_created_fn) (\fBqb_ipcs_connection_t\fP *c)" .PP This is called after a new connection has been created\&. .PP \fBNote:\fP .RS 4 A client connection is not considered connected until this callback is invoked\&. .RE .PP .SS "typedef void(* qb_ipcs_connection_destroyed_fn) (\fBqb_ipcs_connection_t\fP *c)" .PP This is called just before a connection is freed\&. .SS "typedef struct qb_ipcs_connection \fBqb_ipcs_connection_t\fP" .SS "typedef int32_t(* qb_ipcs_dispatch_add_fn) (enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" .SS "typedef int32_t(* qb_ipcs_dispatch_del_fn) (int32_t fd)" .SS "typedef int32_t(* qb_ipcs_dispatch_fn_t) (int32_t fd, int32_t revents, void *data)" .SS "typedef int32_t(* qb_ipcs_dispatch_mod_fn) (enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" .SS "typedef int32_t(* qb_ipcs_job_add_fn) (enum \fBqb_loop_priority\fP p, void *data, \fBqb_loop_job_dispatch_fn\fP dispatch_fn)" .SS "typedef int32_t(* qb_ipcs_msg_process_fn) (\fBqb_ipcs_connection_t\fP *c, void *data, size_t size)" .PP This is the message processing calback\&. It is called with the message data\&. .SS "typedef struct qb_ipcs_service \fBqb_ipcs_service_t\fP" .SH "Enumeration Type Documentation" .PP .SS "enum \fBqb_ipcs_rate_limit\fP" .PP \fBEnumerator\fP .in +1c .TP \fB\fIQB_IPCS_RATE_FAST \fP\fP .TP \fB\fIQB_IPCS_RATE_NORMAL \fP\fP .TP \fB\fIQB_IPCS_RATE_SLOW \fP\fP .TP \fB\fIQB_IPCS_RATE_OFF \fP\fP .TP \fB\fIQB_IPCS_RATE_OFF_2 \fP\fP .SH "Function Documentation" .PP .SS "void qb_ipcs_connection_auth_set (\fBqb_ipcs_connection_t\fP * conn, uid_t uid, gid_t gid, mode_t mode)" .PP Set the permissions on and shared memory files so that both processes can read and write to them\&. .PP \fBParameters:\fP .RS 4 \fIconn\fP connection instance .br \fIuid\fP the user id to set\&. .br \fIgid\fP the group id to set\&. .br \fImode\fP the mode to set\&. .RE .PP \fBSee also:\fP .RS 4 chmod() chown() .RE .PP \fBNote:\fP .RS 4 this must be called within the \fBqb_ipcs_connection_accept_fn()\fP callback\&. .RE .PP .SS "\fBqb_ipcs_connection_t\fP* qb_ipcs_connection_first_get (\fBqb_ipcs_service_t\fP * pt)" .PP Get the first connection\&. .PP \fBNote:\fP .RS 4 call \fBqb_ipcs_connection_unref()\fP after using the connection\&. .RE .PP \fBParameters:\fP .RS 4 \fIpt\fP service instance .RE .PP \fBReturns:\fP .RS 4 first connection .RE .PP .SS "int32_t qb_ipcs_connection_get_buffer_size (\fBqb_ipcs_connection_t\fP * conn)" .PP Retrieve the connection ipc buffer size\&. This reflects the largest size msg that can be sent or received\&. .PP \fBParameters:\fP .RS 4 \fIconn\fP connection instance .RE .PP \fBReturns:\fP .RS 4 msg size in bytes, negative value on error\&. .RE .PP .SS "\fBqb_ipcs_connection_t\fP* qb_ipcs_connection_next_get (\fBqb_ipcs_service_t\fP * pt, \fBqb_ipcs_connection_t\fP * current)" .PP Get the next connection\&. .PP \fBNote:\fP .RS 4 call \fBqb_ipcs_connection_unref()\fP after using the connection\&. .RE .PP \fBParameters:\fP .RS 4 \fIpt\fP service instance .br \fIcurrent\fP current connection .RE .PP \fBReturns:\fP .RS 4 next connection .RE .PP .SS "void qb_ipcs_connection_ref (\fBqb_ipcs_connection_t\fP * c)" .PP Increment the connection's reference counter\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .RE .PP .SS "void* qb_ipcs_connection_service_context_get (\fBqb_ipcs_connection_t\fP * c)" .PP Get the context previously set on the service backing this connection\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .RE .PP \fBReturns:\fP .RS 4 the context .RE .PP \fBSee also:\fP .RS 4 \fBqb_ipcs_service_context_set\fP .RE .PP .SS "int32_t qb_ipcs_connection_stats_get (\fBqb_ipcs_connection_t\fP * c, struct \fBqb_ipcs_connection_stats\fP * stats, int32_t clear_after_read)" .PP Get the connection statistics\&. .PP \fBDeprecated\fP .RS 4 from v0\&.13\&.0 onwards, use qb_ipcs_connection_stats_get_2 .RE .PP \fBParameters:\fP .RS 4 \fIstats\fP (out) the statistics structure .br \fIclear_after_read\fP clear stats after copying them into stats .br \fIc\fP connection instance .RE .PP \fBReturns:\fP .RS 4 0 == ok; -errno to indicate a failure .RE .PP .SS "struct \fBqb_ipcs_connection_stats_2\fP* qb_ipcs_connection_stats_get_2 (\fBqb_ipcs_connection_t\fP * c, int32_t clear_after_read)" .PP Get (and allocate) the connection statistics\&. .PP \fBParameters:\fP .RS 4 \fIclear_after_read\fP clear stats after copying them into stats .br \fIc\fP connection instance .RE .PP \fBReturn values:\fP .RS 4 \fINULL\fP if no memory or invalid connection .br \fIallocated\fP statistics structure (user must free it)\&. .RE .PP .SS "void qb_ipcs_connection_unref (\fBqb_ipcs_connection_t\fP * c)" .PP Decrement the connection's reference counter\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .RE .PP .SS "void* qb_ipcs_context_get (\fBqb_ipcs_connection_t\fP * c)" .PP Get the context (set previously) .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .RE .PP \fBReturns:\fP .RS 4 the context .RE .PP \fBSee also:\fP .RS 4 \fBqb_ipcs_context_set()\fP .RE .PP .SS "void qb_ipcs_context_set (\fBqb_ipcs_connection_t\fP * c, void * context)" .PP Associate a 'user' pointer with this connection\&. .PP \fBParameters:\fP .RS 4 \fIcontext\fP the point to associate with this connection\&. .br \fIc\fP connection instance .RE .PP \fBSee also:\fP .RS 4 \fBqb_ipcs_context_get()\fP .RE .PP .SS "\fBqb_ipcs_service_t\fP* qb_ipcs_create (const char * name, int32_t service_id, enum \fBqb_ipc_type\fP type, struct \fBqb_ipcs_service_handlers\fP * handlers)" .PP Create a new IPC server\&. .PP \fBParameters:\fP .RS 4 \fIname\fP for clients to connect to\&. .br \fIservice_id\fP an integer to associate with the service .br \fItype\fP transport type\&. .br \fIhandlers\fP callbacks\&. .RE .PP \fBReturns:\fP .RS 4 the new service instance\&. .RE .PP .SS "void qb_ipcs_destroy (\fBqb_ipcs_service_t\fP * s)" .PP Destroy the IPC server\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance to destroy .RE .PP .SS "void qb_ipcs_disconnect (\fBqb_ipcs_connection_t\fP * c)" .PP Disconnect from this client\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .RE .PP .SS "void qb_ipcs_enforce_buffer_size (\fBqb_ipcs_service_t\fP * s, uint32_t max_buf_size)" .PP Enforce the max buffer size clients must use from the server side\&. .PP \fBNote:\fP .RS 4 Setting this will force client connections to use at least max_buf_size bytes as their buffer size\&. If this value is not set on the server, the clients enforce their own buffer sizes\&. .RE .PP \fBParameters:\fP .RS 4 \fIs\fP ipc server instance .br \fImax_buf_size\fP represented in bytes .RE .PP .SS "ssize_t qb_ipcs_event_send (\fBqb_ipcs_connection_t\fP * c, const void * data, size_t size)" .PP Send an asynchronous event message to the client\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .br \fIdata\fP the message to send .br \fIsize\fP the size of the message .RE .PP \fBReturns:\fP .RS 4 size sent or -errno for errors .RE .PP \fBNote:\fP .RS 4 the data must include a \fBqb_ipc_response_header\fP at the top of the message\&. The client will read the size field to determine how much to recv\&. .PP When send returns -EMSGSIZE, this means the msg is too large and will never succeed\&. To determine the max msg size a client can be sent, use \fBqb_ipcs_connection_get_buffer_size()\fP .RE .PP .SS "ssize_t qb_ipcs_event_sendv (\fBqb_ipcs_connection_t\fP * c, const struct iovec * iov, size_t iov_len)" .PP Send an asynchronous event message to the client\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .br \fIiov\fP the iovec struct that points to the message to send .br \fIiov_len\fP the number of iovecs\&. .RE .PP \fBReturns:\fP .RS 4 size sent or -errno for errors .RE .PP \fBNote:\fP .RS 4 the iov[0] must be a \fBqb_ipc_response_header\fP\&. The client will read the size field to determine how much to recv\&. .PP When send returns -EMSGSIZE, this means the msg is too large and will never succeed\&. To determine the max msg size a client can be sent, use \fBqb_ipcs_connection_get_buffer_size()\fP .RE .PP .SS "void qb_ipcs_poll_handlers_set (\fBqb_ipcs_service_t\fP * s, struct \fBqb_ipcs_poll_handlers\fP * handlers)" .PP Set your poll callbacks\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .br \fIhandlers\fP the handlers that you want ipcs to use\&. .RE .PP .SS "void qb_ipcs_ref (\fBqb_ipcs_service_t\fP * s)" .PP Increase the reference counter on the service object\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .RE .PP .SS "void qb_ipcs_request_rate_limit (\fBqb_ipcs_service_t\fP * s, enum \fBqb_ipcs_rate_limit\fP rl)" .PP Limit the incoming request rate\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .br \fIrl\fP the new rate .RE .PP .SS "ssize_t qb_ipcs_response_send (\fBqb_ipcs_connection_t\fP * c, const void * data, size_t size)" .PP Send a response to a incoming request\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .br \fIdata\fP the message to send .br \fIsize\fP the size of the message .RE .PP \fBReturns:\fP .RS 4 size sent or -errno for errors .RE .PP \fBNote:\fP .RS 4 the data must include a \fBqb_ipc_response_header\fP at the top of the message\&. The client will read the size field to determine how much to recv\&. .RE .PP .SS "ssize_t qb_ipcs_response_sendv (\fBqb_ipcs_connection_t\fP * c, const struct iovec * iov, size_t iov_len)" .PP Send a response to a incoming request\&. .PP \fBParameters:\fP .RS 4 \fIc\fP connection instance .br \fIiov\fP the iovec struct that points to the message to send .br \fIiov_len\fP the number of iovecs\&. .RE .PP \fBReturns:\fP .RS 4 size sent or -errno for errors .RE .PP \fBNote:\fP .RS 4 the iov[0] must be a \fBqb_ipc_response_header\fP\&. The client will read the size field to determine how much to recv\&. .PP When send returns -EMSGSIZE, this means the msg is too large and will never succeed\&. To determine the max msg size a client can be sent, use \fBqb_ipcs_connection_get_buffer_size()\fP .RE .PP .SS "int32_t qb_ipcs_run (\fBqb_ipcs_service_t\fP * s)" .PP run the new IPC server\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .RE .PP \fBReturns:\fP .RS 4 0 == ok; -errno to indicate a failure\&. Service is destroyed on failure\&. .RE .PP .SS "void* qb_ipcs_service_context_get (\fBqb_ipcs_service_t\fP * s)" .PP Get the context (set previously) .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .RE .PP \fBReturns:\fP .RS 4 the context .RE .PP \fBSee also:\fP .RS 4 \fBqb_ipcs_service_context_set()\fP .RE .PP .SS "void qb_ipcs_service_context_set (\fBqb_ipcs_service_t\fP * s, void * context)" .PP Associate a 'user' pointer with this service\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .br \fIcontext\fP the pointer to associate with this service\&. .RE .PP \fBSee also:\fP .RS 4 \fBqb_ipcs_service_context_get()\fP .RE .PP .SS "int32_t qb_ipcs_service_id_get (\fBqb_ipcs_connection_t\fP * c)" .PP Get the service id related to this connection's service\&. (as passed into \fBqb_ipcs_create()\fP .PP \fBReturns:\fP .RS 4 service id\&. .RE .PP .SS "int32_t qb_ipcs_stats_get (\fBqb_ipcs_service_t\fP * pt, struct \fBqb_ipcs_stats\fP * stats, int32_t clear_after_read)" .PP Get the service statistics\&. .PP \fBParameters:\fP .RS 4 \fIstats\fP (out) the statistics structure .br \fIclear_after_read\fP clear stats after copying them into stats .br \fIpt\fP service instance .RE .PP \fBReturns:\fP .RS 4 0 == ok; -errno to indicate a failure .RE .PP .SS "void qb_ipcs_unref (\fBqb_ipcs_service_t\fP * s)" .PP Decrease the reference counter on the service object\&. .PP \fBParameters:\fP .RS 4 \fIs\fP service instance .RE .PP .SH "Author" .PP Generated automatically by Doxygen for libqb from the source code\&.