Stream Lock
A stream lock is a specialized mutex lock for C++ I/O streams, built on top of uOwnerLock. Concurrent << or >> from multiple tasks on the same stream produces interleaved, unreadable output. uC++ provides osacquire for output streams and isacquire for input streams to serialize a whole chain of operators as one atomic group.
Why does cout need its own kind of lock?
Because each
<<is a separate function call that can be preempted mid-chain. One task’scout << "abc " << "def "can interleave with another’scout << "uvw " << "xyz "in many garbled orderings. Wrapping a stream in a plain mutex works, but stream locks give a cleaner syntax tailored to the cascade style, and handle it through RAII.
The interleaving problem
Two tasks running:
task1: cout << "abc " << "def " << endl;
task2: cout << "uvw " << "xyz " << endl;can produce any of: abc def / uvw xyz, abc uvw xyz def, abuvwc dexf / yz, and more. Each << is a distinct call; the runtime is free to interleave them across tasks.
Anonymous stream lock (most common)
Wrap the whole cascade in one osacquire:
task1: osacquire( cout ) << "abc " << "def " << endl;
task2: osacquire( cout ) << "uvw " << "xyz " << endl;The temporary osacquire object acquires the lock in its constructor, the cascade runs atomically on the returned reference, and the destructor releases the lock at the end of the statement. Output is constrained to two separate lines in either order.
Named stream lock for multiple statements
When several statements must run as one atomic block, declare the lock as a local:
{
osacquire acq( cout ); // acquire for the whole block
cout << "abc";
osacquire( cout ) << "uvw " << "xyz " << endl; // same lock, uOwnerLock re-enters
cout << "def";
} // released when acq goes out of scopeBecause the underlying lock is multiple-acquisition, the inner anonymous osacquire does not deadlock.
Which release pattern?
RAII: the osacquire destructor releases the lock when the temporary or named object goes out of scope. This is why the anonymous form works so cleanly with a single expression statement.