If I have a multi-threaded app, I will need to have a mutex of some sort to ensure that certain data can only be accessed/modified by one thread at a time.
Mostly, this is reasonably straightforward to manage, but there are some cases where it gets a bit tangled. Suppose I have a function that needs the mutex - I can add lock and unlock calls to that, and things will then work as expected:
Code: Select all
Procedure SomeFunction()
; Needs Mutex
LockMutex(m)
; ... does stuff.
UnlockMutex(m)
EndProcedure
Code: Select all
; Ordinary code, no mutex needed.
; SomeFunction() will handle the mutex for itself
SomeFunction()
; Ordinary code, no mutex needed.
Code: Select all
; Needs Mutex
LockMutex(m)
; ... does stuff that needs the mutex
; Needs SomeFunction
SomeFunction()
; ... continues doing stuff that needs the mutex
; Done now
UnlockMutex(m)
Essentially, if the locking doesn't act like a counter, the options as I see it are:
- Leave the lock/unlock in SomeFunction(). Callers of SomeFunction must call UnlockMutex() first if they had locked it. This may be a bad idea if they have work in progress that they need to complete before unlocking.
- Take the lock/unlock out of SomeFunction(). Callers of SomeFunction must call LockMutex() before and UnlockMutex() after if they weren't already doing so. If SomeFunction() is called from a lot of places, this may result in a lot of extra code.
- Add a parameter to SomeFunction to let it know whether it needs to lock the mutex or not.
- Some kind of wrapper functions around lock/unlock, with a threaded variable to act as the counter. This would allow a thread to call WrapLockMutex() multiple times with only the first one really calling LockMutex(). And then, as long as it calls WrapUnlockMutex() the same number of times, it unlocks just once at the end.