PreviousNext

RPC Threads and RPC Cancel Semantics

Each RPC occurs in the context of a thread. A thread is a single sequential flow of control with one point of execution at any instant. When an application thread extends across client and server execution contexts via the DCE RPC mechanism, the local execution contexts are joined by an abstraction known as an RPC thread. The RPC thread attempts to extend local thread semantics to the situation in which execution is extended over two or more local contexts. Specifically, the RPC mechanism tries to make RPC cancels look to the application as much like local cancels as possible.

The semantics of cancels across RPCs are slightly different from the semantics across local (procedure) calls. The differences can be summed up as follows:

1. If the cancel state is disabled when an RPC is made, then, regardless of what is done to the cancellation state on the remote procedure, no cancels will be seen by the remote procedure.
This is because a cancel must be noticed in the client-side runtime in order for it to be forwarded to the server. However, if the cancellation state has been set to disabled when an RPC is issued, then since the client-side runtime does not enable cancels, the client-side runtime will never notice if a cancel has been issued against the calling thread; subsequently, the cancel remains pending and unnoticed by the client-side runtime, even if the server side has changed the cancellation state (for instance, to deferred).

Furthermore, since lexical scoping of changes to the cancellation state is enforced by RPC, the cancellation state in effect at the time of the RPC call is restored upon completion of the call. Thus, any state changes made on the server side of the call are lost. Any issued cancels remain pending as the server-side state change is "undone" by the client-side runtime prior to returning to the calling thread. In this instance, if a cancel arrives after the callee returns, the cancel will not be acted upon.
This behavior contrasts with the local procedure call case: if cancel state is disabled when a local procedure call is made, and the callee sets the cancellation state to deferred, then if a cancel arrives and the callee hits a cancellation point, the cancel will be acted upon. Furthermore, if the cancel arrives after the callee returns, the cancel will be acted upon when a cancellation point is arrived at in the caller.

2. If cancelability state is deferred, then cancellation requests will be sent to the server where they will be handled according to the server's setting of the cancelability state for the application thread extension (that is, the call thread) in the server. If ignored at the server, the client side would then effect the cancel upon return from the RPC, so the cancel would not be lost or incorrectly handled. In particular, the timeslice interrupt (context switch) is a cancellation point in DCE threads, so that even if a cancel were ignored by the server side, when the RPC returns, the thread will be at a cancellation point.

3. If cancelability state is asynchronous, then cancellation can happen at any time. In general, this state is not recommended across the scope of an RPC in line with the rule that most routines that do useful work are not asynchronous cancel safe and thus should not be called with asynchronous cancelability state.