When a domain invokes a key either explicitly or implicitly, the kernel acts in two phases:

If some lock cannot be acquired the operation will be deferred or fail and then there are then several cases: After the kernel has responded to the invocation the locks are released. Each node or page has a count of the number of times it has been locked in shared mode. It is quite rare for a node to participate in one kernel transaction twice but it was easier to allow than to disallow.

See this note contrasting the function of primitive hardware locks and those of Java.


The “general code” referred to above sounds complicated. Actually it is simpler than the fast code. The general code marshals the message from the domain into an area of the kernel thus matching the conceptual steps. This marshaling is oblivious to the meaning of the message and the kernel object being invoked. The marshaled message includes the keys from the message. The invoker is then unlocked. Enough of the recipient is verified to be in core to receive the response message. The action is then attempted and resulting message placed in a separate kernel area. The message is then delivered to the recipient.

An issue is the semantics of an operation that changes how the recipient will receive the response. The recipient may have been “receptive” before the operation but not after. If this is a security hole then such operations may be disallowed. They once were and still may be.

Except for performance, there would be no need for the fast case which merely interprets the message as it is found in the component parts of the invoking domain.