OSF DCE Application Development Guide--Core Components

Topics in RPC Application Development
error_status_t status) /* status we want to print the message for. */
{
dce_error_string_t error_string;
int print_status;
dce_error_inq_text(status, error_string, &print_status);
fprintf(stderr," Manager: %s: %s0, caller, error_string);
}
The sample implementation of the store interface is obviously too limited for any
practical use, but it does demonstrate the application of context handles in a
straightforward way. A context handle returned by the store_open() routine is opaque
to the client. To the server, it is a pointer to the server’s representation of a storage unit.
In this case, it points to a structure that keeps track of the client’s current location within
a specific piece of server-maintained storage.
Aside from deallocating the actual storage, the store_close() routine sets the context
handle to NULL. The NULL value indicates to the server stub that the context is no
longer active, and the stub, in turn, tells the RPC runtime not to maintain the context.
For example, after the store_close( ) routine has been invoked, the rundown routine will
not be invoked if communication ends between client and server. The context rundown
routine takes care of closing the client’s storage in case of a communication failure while
the context is active.
The global array of store_hdr structures that keeps track of allocated storage, obviously
servers no practical purpose in the example. (Presumably the operating system is already
doing this!) However, it does provide a demonstration of the fact that global server
manager data is shared data in the implicitly multithreaded server environment. The
routines that manipulate this shared data may be called simultaneously by multiple
server threads (in response to multiple simultaneous client calls); therefore, locking must
be provided, in this case on the refcount field. The sample also demonstrates how the
pthread_once() facility can be used to provide one-time initialization of the shared data
on the first store_open() call.
As an exercise, the storage interface can easily be made more interesting by providing
multiple clients simultaneous access to a given storage area. To implement this, the
application could add a store_name parameter to the store_open( ) routine and replace
the refcount field with counts of readers and writers. The division of the storage
management between the store_hdr and the store_spec data structures is intended to
facilitate this; the store_hdr holds shared state relating to each store, while the
store_spec holds each thread’s private state.
16.3.3 Context Rundown
Context handles typically point to some state maintained by a server instance for a client
over a series of RPC operations. If the series of operations fails to complete because
communication is lost between client and server, the server will probably have to take
some kind of recovery action such as restoring data to a consistent state and freeing
resources.
124245 Tandem Computers Incorporated 16 21