Event Processing
[Protocol-Independent API]


Detailed Description

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:


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.


Typedef Documentation

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.

Parameters:
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
Returns:
The application-specific cookie to be associated with this connection
See also:
mrpc_set_accept_func()
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.

Parameters:
conn_data The cookie associated with the connection
reason The reason the connection was closed
See also:
mrpc_set_disconnect_func(), mrpc_conn_unref()
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.

Parameters:
conn_data The cookie associated with the connection
message A string describing the error
See also:
mrpc_set_ioerr_func()
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.


Function Documentation

int mrpc_start_dispatch_thread ( struct mrpc_conn_set *  set  ) 

Start a dispatcher thread for a connection set.

Parameters:
set The connection set
Returns:
A POSIX error code, or 0 on success
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.

Parameters:
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.

Parameters:
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.

Parameters:
set The connection set
Returns:
ENXIO if the connection set is being destroyed, or a POSIX error code on other error
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.

Parameters:
set The connection set
max The maximum number of events to dispatch, or 0 for no limit
See also:
mrpc_get_event_fd()
Returns:
ENXIO if the connection set is being destroyed, 0 if more events are pending, or EAGAIN if the event queue is empty
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.

Parameters:
set The connection set
Returns:
The file descriptor
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.

Parameters:
conn The connection
Returns:
0 on success, EALREADY if events were already stopped with mrpc_stop_events(), or a POSIX error code on error
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.

Parameters:
conn The connection
Returns:
A POSIX error code, or 0 on success
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.

Returns:
A POSIX error code, or 0 on success
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.


miniRPC 0.3.3
Documentation generated by Doxygen 1.5.6