<< Previous exercise (3.44) | Index | Next exercise (3.46) >>
Using Louis's code, in exchanging two accounts we will use the same serializer for two times. One in the serialized-exchange function and the other in the dispatch function. According to the implementation of the serializer, if a process has already acquired a mutex and it wants to acquire that mutex again, the busy waiting will never halt.
If just checking `(deposit account amount)`, the behavior is same since `deposit` and `balance-serializer` are all static and can be calculated in advance and reused in the future.
So the problem is in `(account 'deposit)` as xdavidliu says.
---
Notice this problem can be avoided by [reentrant lock (see the reference link)](https://stackoverflow.com/a/26542901/21294350) (I first learnt about this data structure in OSTEP if my memory is right).
A reentrant lock is one where a process can claim the lock multiple times without blocking on itself.
Notice reentrant lock is different from semaphore. See https://github.com/sci-42ver/SICP_SDF/blob/62de34081c604a2e2f063b47a6d70c52c4a58d04/sicp_exercise.md?plain=1#L1777-L1782
The correct implementation of serialized-exchange in the book deliberately leaves the dispatched withdraw and deposit procedures *un*-serialized, so that when the "raw" exchange procedure calls them and then gets wrapped, via serialized-exchange, in the serializers of both accounts involved in the exchange, there will be no conflict.
Louis' proposed change would be disastrous because the dispatched withdraw and deposit procedures called in the "raw" exchange procedure would *already* have serializers, so when serialized-exchange wraps the raw exchange in both serializers *again*, it wouldn't even be possible to perform the required withdraws and deposits, *by definition*, since two procedures can be run concurrently if and only if they have *not* been serialized with the same serializer.