Solutions to Problems
The main problem with indirect communication is the interference between the read and write actions of the communication partners. Therefore, we first present a basic locking mechanism that guarantees exclusive access to the location used for storing the message. We then give solutions to the problems with unidirectional and bidirectional indirect communication based on this mechanism.
Basic Locking MechanismTo avoid problems with using indirect communication between concurrent functions a mechanism is needed that prevents simultanous access to the location used for storing the messages. A possibility for this is the use of a locking mechanism that operates in concurrency with the communicating functions and that has two actions associated with it, a lock action and an unlock action. A lock action gives exclusive access to a particular location, and an unlock action releases the exclusive access.
Indirect communication with locking mechanism
A read or a write action may only occur after a lock action and must be followed by an unlock action. This locking mechanism is commonly used in software, where it is implemented with two semaphores using Dekker's algorithm.
Although this mechanism may work fine in a well disciplined environment, there still are problems with this mechanism since it does not prevent access to the location for storing the messages without using the mechanism. A solution to this is to use a locking mechanism that encapsulates the location. The encapsulation can be established by using a location that is only locally accessible instead of a location that is globally accessible.
Indirect communication with encapsulated location and locking mechanism
With this mechanism, a read or a write action can only take place when first a lock action has been done by the function that wants to read or write. So for writing a message into the location the sequence of actions lock - write - unlock and for reading a message from the location the sequence lock - read - unlock have to be performed.
Unidirectional Indirect CommunicationIn this section we describe the implementation of a mechanism for unidirectional indirect communication based on the basic locking mechanism from the previous section. We start with a mechanism that implements the basic communication actions, which we extend to a mechanism that fully implements unidirectional indirect communication.
Basic Communication MechanismWhen using the basic locking mechanism writing a message consists of the sequence of actions lock - write - unlock, and reading a message of the sequence lock - read - unlock. From the point of view of the writer and reader of the message these sequences can each be incorporated in a single action. Instead of implementing such actions on the side of the writer and reader, we can implement a mechanisme that provides these actions. That mechanism can at the same time encapsulate the basic locking mechanism to prevent access to it directly.
Indirect communication with encapsulated locking mechanism
When we abstract from the inner working of this mechanism, it is just another concurrent function with associated read and write actions. The form of communication with this function is unidirectional direct communication. Thus we can conclude that unidirectional indirect communication is built up from two unidirectional direct communications, one between the writer and the mechanism and one between the mechanism and the reader.
Status Based CommunicationWith unidirectional indirect communications only a read may be done when a message first has been written. And writing of the next message may only be done when the previous message has been read. The basic communication mechanism from the previous section does not have these constraints. To enforce these constraints, we have to keep track of the status of the basic communication mechanism and only a write or a read based on the current status.
We add a status flag with associated actions set and get in order to see if a message can be written or that a message has to be read. We encapsulate the status flag and the basic communication mechanism to prevent interference by wrapping them in another mechanism. We can then abstract from the innerworking of this mechanism. We are left with a mechanism that can only do a read action when a message has been written and only a write action when there has been no write yet or the message has been read. We provide the mechanism with an action for checking the status from outside the mechanism.
Unidirectional indirect communication with encapsulated status flag
Bidirectional Indirect CommunicationWhen bidriectional indirect communication consist of two unidirectional indirect communications there are no additional problems and we solve them as described above. When bidirectional indirect communication is built using only one location for storing the messages in both directions the same problems arise as with unidirectional indirect communication. There is only one additional problem, and that is the possibility of overwriting a message before it can be read due to interference of the communications in the two directions.
The solution to this problem is similar to the solution described above, but it is more complex since now the two directions of communication have to be taken into account. We have to alter the possible number of states to make sure that a message can only be written when there is no message waiting to be read and that a message can only be read by the one side it is intended for.