Mutex and co
Posted: Tue Jun 05, 2007 12:28 am
It's 3.94 as I was working on something older, but it still may provide some useful insight into mutexes. Now let's hope *I* got it right in the first place 

Code: Select all
; purebasic survival guide - pb3.94
; mutex_1.pb - 05.06.2007 ejn (blueznl)
; http://www.xs4all.nl/~bluez/datatalk/purebasic.htm
;
; - creation and removal of mutexes
; - CreateMutex_()
; - CloseHandle_()
;
; note: purebasic 4's CreateMutex() command has not the same functionality as the Windows API CreateMutex_() !
;
#MUTEX_ALL_ACCESS = $1F0001
#WAIT_TIMEOUT = $102
#WAIT_ABANDONED = $80
#WAIT_FAILED = $FFFFFFFF
#WAIT_OBJECT_0 = $0
;
; *** opening and closing a mutex
;
; mutexes are unique single objects that can be 'owned' by applications, they are exclusive and can never be owned
; by two different owners at the same time, thus 'mutually exclusive' or 'mutex'
;
; a return value of 0 means something when wrong with the creation of the mutex
;
mutex_name.s = "test"
;
mutex_h = CreateMutex_(0,0,@mutex_name)
If mutex_h = 0
lasterror = GetLastError_()
Debug "not created"
EndIf
;
; a mutex will be destroyed if nobody owns it, and 1. the creator exits, or 2. a closehandle closes it
; as usual the best way is to properly close a mutex if you no longer use it :-)
;
; one way to check for the existence of a mutex is opening it, in which case it returns a handle to the mutex
; if the mutex didn't exist (yet) or was destroyed via CloseHandle_() this will return 0
;
mutex2_h = OpenMutex_(#MUTEX_ALL_ACCESS,0,@mutex_name)
If mutex2_h = 0
Debug "could not open"
Else
CloseHandle_(mutex2_h)
EndIf
;
; trying to create a mutex that already existed will result in creating a copy of the specified mutex
; GetLastError_() provides information on the creation of the mutex, and if it already existed
;
; (this mechanism can be used to create 'single instance' software, where a new instance will exit as it already
; detects another version of itself in memory, by trying to create such a mutex and exiting when it already
; existed)
;
mutex3_h = CreateMutex_(0,0,@mutex_name)
lasterror = GetLastError_()
If lasterror = #ERROR_ALREADY_EXISTS
Debug "already exists"
CloseHandle_(mutex3_h)
EndIf
;
; although windows seems to clean up abandoned mutexes, it's better to clean them up properly
;
CloseHandle_(mutex_h)
;
;
;
; *** mutex ownership
;
; only one instance (program) can 'own' a mutex, ownership can be established upon creation
; (the second parameter when set to '#True' makes the creator an owner)
; other threads / instances would open the existing mutex using OpenMutex_()
;
; mutex4_h = OpenMutex_(#MUTEX_ALL_ACCESS,0,@mutex_name)
;
mutex4_h = CreateMutex_(0,#True,@mutex_name)
;
; this program (the current instance, the code you're reading :-)) can try to get ownership of the mutex
; by calling WaitForSingleObject_() with a proper handle and a timeout parameter
;
; WaitForSingleObject_() will wait the specified nr. of milliseconds before continuing
;
result = WaitForSingleObject_(mutex4_h,50)
Select result
Case #WAIT_FAILED
Debug "failed"
Case #WAIT_ABANDONED
Debug "other process abandoned mutex"
Case #WAIT_TIMEOUT
Debug "other process still owns mutex"
Case #WAIT_OBJECT_0
Debug "success"
EndSelect
;
; 'abandoned' is a special case, it means the mutex was found but the previous owner is gone now, and you
; have now become the owner of the mutex
;
; if you no longer need to own a mutex, releasing is easy
;
ReleaseMutex_(mutex4_h)
;
; using WaitForSingleObject_() and ReleaseObject_() makes it possible to synchronize two applications with each
; other
;
; finally, when we're all done and about to exit the program we close the mutex
;
CloseHandle_(mutex4_h)
;
; a final note (thanks netmaestro!): it's worth noting at this point that despite their similar names,
; the CreateMutex_() API and purebasic 4's native CreateMutex() command are very differen: the CreateMutex()
; command deals with the management of critical section objects rather than mutex objects
;