Endpoint and Startpoint Functions


nexus_endpointattr_init()

int nexus_endpointattr_init(nexus_endpointattr_t *endpointattr)

Initialize the endpoint attributes structure, endpointattr, to the default set of attributes.

Return zero if successful, or non-zero otherwise.


nexus_endpointattr_destroy()

int nexus_endpointattr_destroy(nexus_endpointattr_t *endpointattr)

Destroy the endpoint attributes structure, endpointattr.

Return zero if successful, or non-zero otherwise.


nexus_endpointattr_set_handler_table()

typedef void (*nexus_handler_func_t)(nexus_endpoint_t *endpoint,
                                     nexus_buffer_t *buffer
                                     nexus_bool_t is_non_threaded_handler);
typedef enum _nexus_handler_type_t
{
    NEXUS_HANDLER_TYPE_THREADED,
    NEXUS_HANDLER_TYPE_NON_THREADED
} nexus_handler_type_t;

typedef struct _nexus_handler_t {
    nexus_handler_type_t  type;
    nexus_handler_func_t  func;
} nexus_handler_t;

int nexus_endpointattr_set_handler_table(
                      nexus_endpointattr_t *endpointattr,
                      nexus_handler_t *handler_table,
                      int handler_table_size)

Set the handler table in endpointattr to handler_table, which is an array of nexus_handler_t structures with handler_table_size elements. This function does not copy the handler_table, but instead saves a pointer to it. Therefore, the user must ensure that the handler_table array is valid as long as there are valid endpoints which where initialized using endpointattr. Changing the contents of the handler_table array after it has been set in endpointattr and used for endpoint initialization will effectively modify the handler table of each of those endpoints, as well as endpoints that are subsequently initialized using endpointattr. However, setting the handler table in endpointattr to a completely different handler table array, after endpointattr has been used to initialize an endpoint, does not set the handler table in the endpoint.

A handler is a function that is executed in response to a remote service request. A threaded handler, which is specified by setting the nexus_handler_type_t to NEXUS_HANDLER_TYPE_THREADED in the appropriate handler_table entry, executes in a thread created specificly for it., A non-threaded handler, which is specified by setting the nexus_handler_type_t to NEXUS_HANDLER_TYPE_NON_THREADED in the appropriate handler_table entry, executes in an existing thread, and is restricted in what it can do.

A handler is run in response to a remote service request (RSR). The RSR specifies a startpoint, handler_id, and a buffer. This causes a handler to be invoked, which runs in the context of the endpoint bound to the startpoint. The information contained in handler_table[handler_id] is used to determine which handler function to run, and whether the handler is threaded or non-threaded. The handler is passed a pointer to the endpoint, and a pointer to a buffer containing the same data as that which was sent by the RSR. The buffer is freed automatically on exit from a non-threaded handler, but must be freed explicitly by calling nexus_buffer_free() in a threaded handler.

Return zero if successful, or non-zero otherwise.


nexus_endpointattr_get_handler_table()

int nexus_endpointattr_get_handler_table(
                      nexus_endpointattr_t *endpointattr,
                      nexus_handler_t **handler_table,
                      int *handler_table_size)

Get the handler table in endpointattr and place it into handler_table, and place its size into handler_table_size.

Return zero if successful, or non-zero otherwise.


nexus_endpointattr_set_unknown_handler()

typedef void (*nexus_unknown_handler_func_t)(nexus_endpoint_t *endpoint,
                                             nexus_buffer_t *buffer,
                                             int handler_id)

int nexus_endpointattr_set_unknown_handler(
                      nexus_endpointattr_t *endpointattr,
                      nexus_unknown_handler_func_t *func,
                      nexus_handler_type_t type)

Set the unknown handler function in endpointattr to func with the given type. The unknown handler function is called when an RSR arrives for an endpoint for which:

  1. there is no associated handler table, or
  2. the RSR's handler id is greater than the size of the endpoint's handler table, or
  3. the handler table entry for RSR's handler id has a NULL function.

The unknown handler function is called in the context of the endpoint to which the RSR was sent. It can be invoked either as a threaded or non-threaded handler, depending on the value of type.

Return zero if successful, or non-zero otherwise.


nexus_endpointattr_get_unknown_handler()

int nexus_endpointattr_get_unknown_handler(
                      nexus_endpointattr_t *endpointattr,
                      nexus_unknown_handler_func_t **func,
                      nexus_handler_type_t *type)

Get the unknown handler function from endpointattr, placing the function pointer in *func and the handler type in *type.

Return zero if successful, or non-zero otherwise.


nexus_endpoint_init()

int nexus_endpoint_init(nexus_endpoint_t *endpoint,
                        nexus_endpointattr_t *endpointattr)

Initialize the endpoint, endpoint, using the endpoint attribute structure, endpointattr.

Return zero if successful, or non-zero otherwise.


nexus_endpoint_set_user_pointer()

void nexus_endpoint_set_user_pointer(nexus_endpoint_t *ep,
                                     void *ptr)

Set the user pointer field in the endpoint, ep, to ptr.


nexus_endpoint_get_user_pointer()

void *nexus_endpoint_get_user_pointer(nexus_endpoint_t *ep)

Return the user pointer field in the endpoint, ep.


nexus_endpoint_destroy()

int nexus_endpoint_destroy(nexus_endpoint_t *endpoint)

Return zero if successful, or non-zero otherwise.


nexus_startpoint_bind()

int nexus_startpoint_bind(nexus_startpoint_t *startpoint,
                          nexus_endpoint_t *endpoint)

Bind the startpoint with the endpoint. More than one startpoint can be bound to an endpoint.

The endpoint must be initialed using nexus_endpoint_init() prior to binding a startpoint to it.

The startpoint, dest_sp, should eventually be destroyed by calling
nexus_startpoint_destroy() or nexus_put_startpoint_transfer().

Return zero if successful, or non-zero otherwise.


nexus_startpoint_copy()

int nexus_startpoint_copy(nexus_startpoint_t *dest_sp,
                          nexus_startpoint_t *src_sp)

Copy startpoint src_sp to dest_sp.

The startpoint, dest_sp, should eventually be destroyed by calling
nexus_startpoint_destroy() or nexus_put_startpoint_transfer().

Assignment may also be performed with startpoints (i.e. dest_sp = src_sp). However, only one of dest_sp and src_sp should be subsequently destroyed by calling nexus_startpoint_destroy(), and once one has been destroyed, the other has been implicitly destroyed as well.

This function may be expensive, in that it may require a round trip communication with the context containing the endpoint to which this startpoint is bound.

This function may not be called from a non-threaded handler, due to the round trip communication that it may perform.

Return zero if successful, or non-zero otherwise.


nexus_startpoint_destroy()

int nexus_startpoint_destroy(nexus_startpoint_t *sp)

Destroy the startpoint, sp, and set it to NULL, freeing its associated resources. The result of calling any Nexus function with a startpoint that has been destroyed (or with a copy of a destroyed startpoint) is undefined.

nexus_put_startpoint_transfer() implicitly calls this function.

Any startpoints that are not explicitly destroyed using this function will be destroyed when the context in which they reside is destroyed.

Return zero if successful, or non-zero otherwise.


nexus_startpoint_destroy_and_notify()

int nexus_startpoint_destroy_and_notify(nexus_startpoint_t *sp)

Destroy the startpoint, sp, set it to NULL, and free up any state in the endpoint pointed to by this startpoint.

This function may be expensive, in that it may require a round trip communication with the context containing the endpoint to which this startpoint is bound.

This function may not be called from a non-threaded handler, due to the round trip communication that it may perform.

Return zero if successful, or non-zero otherwise.


nexus_startpoint_set_null()

void nexus_startpoint_set_null(nexus_startpoint_t *sp)

Initialize sp to be a NULL startpoint.

Note that setting a startpoint to NULL is not equivalent to destroying the startpoint. If the startpoint is already bound, you should destroy it and set it to NULL using nexus_startpoint_destroy() or nexus_startpoint_destroy_and_notify(). This function is meant to be used to set a startpoint to an initialized, but unbound state.


nexus_startpoint_is_null()

int nexus_startpoint_is_null(nexus_startpoint_t *startpoint)

Return non-zero if sp is a NULL startpoint, otherwise return zero.


nexus_startpoint_equal_context()

int nexus_startpoint_equal_context(nexus_startpoint_t *sp1,
                                   nexus_startpoint_t *sp2)

Return non-zero if the two startpoints are bound to endpoints that are in the same context, or zero otherwise.


nexus_startpoint_equal()

int nexus_startpoint_equal(nexus_startpoint_t *sp1,
                           nexus_startpoint_t *sp2)

Return non-zero if the two startpoints are bound to the same endpoint, or zero otherwise.


nexus_startpoint_to_current_context()

int nexus_startpoint_to_current_context(nexus_startpoint_t *sp)

Return non-zero if the startpoint is bound to an endpoint that is in the context of the calling thread.


nexus_startpoint_get_endpoint()

int nexus_startpoint_get_endpoint(nexus_startpoint_t *sp,
                                  nexus_endpoint_t **ep)

Set *ep to the endpoint to which the startpoint, sp, is bound. This function assumes that the startpoint and endpoint are in the same context, which can be tested using nexus_startpoint_to_current_context().

Return non-zero on success, or non-zero otherwise.