Mircea Baja - 7 June 2025 # Structured concurency
detached
wait_any
--- # Structured programming
sequential
goto
if
loop
function call
[Nathaniel J. Smith: Notes on structured concurrency, or: Go statement considered harmful](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/) - `goto` corresponds to low level assembly `jump` instructions - ends in spagetti code: graphs that do not obviously reduce to sequential (i.e. linear) - replaced with constructs that reduce to sequential - in modern languages even `goto` is tamed (only jumps within the same function) - but kept for the three cases where it's needed once every 20 years or so --- # Low level concurrency APIs ```cpp int WSAAPI WSARecv( [in] SOCKET s, [in, out] LPWSABUF lpBuffers, [in] DWORD dwBufferCount, [out] LPDWORD lpNumberOfBytesRecvd, [in, out] LPDWORD lpFlags, [in] LPWSAOVERLAPPED lpOverlapped, [in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); ``` - Can be called with a pointer to the completion routine (a callback) - Until that routine is called (or cancelled) the socket, buffer, overlapped structure (often a derived type holding more data) - need to be kept alive - they might be accessed during or after the call to `WSARecv` --- # Unstructured concurrency
goto
detached
[Nathaniel J. Smith: Notes on structured concurrency, or: Go statement considered harmful](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/) Low level C APIs expose a detached behaviour which on one side is necessary, like `jump` statements in assembly, but we want that wrapped in structured concurrency primitives that are easier to use correctly. Easy to say, but what are some examples of structured concurrency primitives? --- # An example: wait_any
wait_any
- we started three tasks - the second completed first - the other two are cancelled - continues when all three are completed (cancelled or otherwise) - returns the value of winner (second task in this case) --- - continuation - chains - sane principles - a child coroutine does not outlives its parent - a coroutine runs uninterrupted until a co_await - discuss issue with reference parameters, lambda captures, pointers, string_views - the generator problems with scope - discuss the issue of detach/fire and forget - sharing data e.g. by value - lifetime - discuss bad advice that uses detached models - https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rcoro-capture - more bad advice https://devblogs.microsoft.com/oldnewthing/20211103-00/?p=105870 - though they really like detached in embedded environments, explain why - error propagation - sync start a chain - wait_any, wait_all - wait_for - stop_when (e.g. on user interrupt instead of timer) - nursery --- # Questions?