Typedefs | |
typedef void *( | mrpc_accept_fn )(void *set_data, struct mrpc_connection *conn, struct sockaddr *from, socklen_t from_len) |
Event callback fired on arrival of a new connection. | |
typedef void( | mrpc_disconnect_fn )(void *conn_data, enum mrpc_disc_reason reason) |
Event callback fired on connection close. | |
typedef void( | mrpc_ioerr_fn )(void *conn_data, char *message) |
Event callback fired on I/O error. | |
Functions | |
int | mrpc_start_dispatch_thread (struct mrpc_conn_set *set) |
Start a dispatcher thread for a connection set. | |
void | mrpc_dispatcher_add (struct mrpc_conn_set *set) |
Notify miniRPC that the current thread will dispatch events for this connection set. | |
void | mrpc_dispatcher_remove (struct mrpc_conn_set *set) |
Notify miniRPC that the current thread will no longer dispatch events for this connection set. | |
int | mrpc_dispatch_loop (struct mrpc_conn_set *set) |
Dispatch events from this thread until the connection set is destroyed. | |
int | mrpc_dispatch (struct mrpc_conn_set *set, int max) |
Dispatch events from this thread and then return. | |
int | mrpc_get_event_fd (struct mrpc_conn_set *set) |
Obtain a file descriptor which will be readable when there are events to process. | |
int | mrpc_stop_events (struct mrpc_connection *conn) |
Disable event processing for a connection. | |
int | mrpc_start_events (struct mrpc_connection *conn) |
Re-enable event processing for a connection. | |
int | mrpc_release_event (void) |
Allow the current event handler to run in parallel with other handlers for the same connection. |
miniRPC handles application callbacks by means of events. When miniRPC wishes to fire a callback, it queues an event to be processed by a dispatcher thread. These dispatcher threads are provided by the application, and are associated with a particular connection set.
miniRPC places few restrictions on the application's arrangement of dispatcher threads. miniRPC provides several alternative interfaces for dispatching; the application can choose the one it needs, or can even alternate between them. An application can have as many dispatchers as it wants.
Because application callbacks execute only in dispatcher threads, the application can decide how long a callback can take to complete. For example, a server providing a compute-intensive procedure call can choose to do its computation directly within the procedure handler, and simply create a large number of dispatcher threads to ensure parallelism. Or, it can return quickly from the procedure handler, finish processing in a dedicated thread, and return the result asynchronously.
By default, miniRPC does not fire multiple events at a time for a given connection, so the application need not handle concurrency within each connection. However, the application can override this behavior if it wishes. Interfaces are also provided to request that miniRPC stop (or resume) dispatching events for a given connection.
Dispatcher threads are subject to the following constraints:
The application may dispatch using one or more of the following mechanisms:
typedef void*( mrpc_accept_fn)(void *set_data, struct mrpc_connection *conn, struct sockaddr *from, socklen_t from_len) |
Event callback fired on arrival of a new connection.
set_data | The cookie associated with the connection set | |
conn | The handle to the newly-created connection | |
from | The address of the remote end of the connection | |
from_len | The length of the from structure |
This function is called when a new connection arrives on a listening socket created with mrpc_listen(). At minimum, the function must set the connection's operations struct using the protocol-specific set_operations function; otherwise, no incoming messages for the connection will be processed.
from
is no longer valid after the callback returns.
typedef void( mrpc_disconnect_fn)(void *conn_data, enum mrpc_disc_reason reason) |
Event callback fired on connection close.
conn_data | The cookie associated with the connection | |
reason | The reason the connection was closed |
If supplied, this callback is fired when a connection is closed for any reason, including when explicitly requested by the application (with mrpc_conn_close()). Once the callback returns, the application will not receive further events on this connection. If the connection's refcount is greater than zero after the disconnection function returns, the connection handle will persist until all references are released.
typedef void( mrpc_ioerr_fn)(void *conn_data, char *message) |
Event callback fired on I/O error.
conn_data | The cookie associated with the connection | |
message | A string describing the error |
If supplied, this callback is fired whenever miniRPC encounters an I/O or XDR error it wishes to report to the application. message
is in a format suitable for logging. message
is no longer valid once the callback returns.
This callback is fired only on unusual error conditions, generally caused by invalid data on the wire. If miniRPC can recover from such an error, it will do so; if not, it will automatically close the connection (and report this via the disconnect callback).
The application need not register an ioerr
callback unless it wishes to log such events. In most cases, the callback function will simply call the appropriate logging function and return. If the application is paranoid about servicing connections which may be in a dubious state, it may wish to close the affected connection (with mrpc_conn_close()) as well.
int mrpc_start_dispatch_thread | ( | struct mrpc_conn_set * | set | ) |
Start a dispatcher thread for a connection set.
set | The connection set |
Start a background thread to dispatch events. This thread will persist until the connection set is destroyed, at which point it will exit. This function can be called more than once; each call will create a new thread. This is the simplest way to start a dispatcher for a connection set.
Unlike with mrpc_dispatch() and mrpc_dispatch_loop(), the caller does not need to register the dispatcher thread with mrpc_dispatcher_add(). The background thread handles this for you.
void mrpc_dispatcher_add | ( | struct mrpc_conn_set * | set | ) |
Notify miniRPC that the current thread will dispatch events for this connection set.
set | The connection set |
Any thread which calls mrpc_dispatch() or mrpc_dispatch_loop() must call mrpc_dispatcher_add() before it starts dispatching for the specified connection set.
void mrpc_dispatcher_remove | ( | struct mrpc_conn_set * | set | ) |
Notify miniRPC that the current thread will no longer dispatch events for this connection set.
set | The connection set |
Any thread which calls mrpc_dispatch() or mrpc_dispatch_loop() must call mrpc_dispatcher_remove() when it decides it will no longer dispatch for the specified connection set.
int mrpc_dispatch_loop | ( | struct mrpc_conn_set * | set | ) |
Dispatch events from this thread until the connection set is destroyed.
set | The connection set |
Start dispatching events for the given connection set, and do not return until the connection set is being destroyed. The thread must call mrpc_dispatcher_add() before calling this function, and mrpc_dispatcher_remove() afterward. This function must not be called from an event handler.
int mrpc_dispatch | ( | struct mrpc_conn_set * | set, | |
int | max | |||
) |
Dispatch events from this thread and then return.
set | The connection set | |
max | The maximum number of events to dispatch, or 0 for no limit |
Dispatch events until there are no more events to process or until max
events have been processed, whichever comes first; if max
is 0, dispatch until there are no more events to process. The calling thread must call mrpc_dispatcher_add() before calling this function for the first time.
If this function returns ENXIO, the connection set is being destroyed. The application must stop calling this function, and must call mrpc_dispatcher_remove() to indicate its intent to do so.
This function must not be called from an event handler.
int mrpc_get_event_fd | ( | struct mrpc_conn_set * | set | ) |
Obtain a file descriptor which will be readable when there are events to process.
set | The connection set |
Returns a file descriptor which can be passed to select()/poll() to determine when the connection set has events to process. This can be used to embed processing of miniRPC events into an application-specific event loop. When the descriptor is readable, the connection set has events to be dispatched; the application can call mrpc_dispatch() to handle them.
The application must not read, write, or close the provided file descriptor. Once mrpc_dispatch() returns ENXIO, indicating that the connection set is being shut down, the application must stop polling on the descriptor.
int mrpc_stop_events | ( | struct mrpc_connection * | conn | ) |
Disable event processing for a connection.
conn | The connection |
Prevent miniRPC from processing further events for the specified connection until mrpc_start_events() is called. This function can be called from an event handler.
The application may call this function more than once against the same connection. Event processing for the connection will not resume until the application makes the corresponding number of calls to mrpc_start_events().
If this function is called from an event handler for the same connection, and the handler has not called mrpc_release_event(), the application is guaranteed that no further events will be fired on the connection once the call returns. Otherwise, there is a window after the function returns in which further events may be fired.
int mrpc_start_events | ( | struct mrpc_connection * | conn | ) |
Re-enable event processing for a connection.
conn | The connection |
Allow miniRPC to resume processing events against a connection for which event processing has been disabled with mrpc_stop_events(). If mrpc_stop_events() has been called more than once, event processing will not resume until mrpc_start_events() has been called a corresponding number of times.
int mrpc_release_event | ( | void | ) |
Allow the current event handler to run in parallel with other handlers for the same connection.
By default, miniRPC ensures that only one event is processed at a time for a given connection. This frees the application from handling concurrency between RPCs on a particular connection. However, in certain cases, the application may be willing to handle these concurrency issues so that a connection can process multiple events in parallel.
This function indicates to miniRPC that the calling event handler should no longer block the handling of additional events on its associated connection. Note that this call is effective only for the current invocation of the calling event handler; it will have no effect on any other event.
Returning from an event handler implicitly calls this function. If called from outside an event handler, this function returns EINVAL and has no other effect.