Valik Posted May 8, 2008 Posted May 8, 2008 If you elect not to close the script (flag 1) then multiple instances of the mutex will exist. This is an unfortunate side effect of another developer's bright idea to provide an option to break the paradigm the function implements. The handle is intentionally leaked with the understanding that it will automatically be released by the system when the process exits. There's no point in manually storing and releasing something that lives the entire application life-time when the system can do it automatically, even though it looks like bad programming practice. However, this paradigm is busted with the flag of 1 because it allows you to by-pass the check. Thus, a second mutex will exist for as long as the second script is alive. If you run 3 scripts each using flag 1, three copies of the mutex will exist, et cetera. I recommend that unless you are actually trying to implement the singleton pattern into your script, use your own calls to whichever synchronization object you prefer and control it how you see fit. Trying to abuse _Singleton() is not recommended.
Valik Posted May 8, 2008 Posted May 8, 2008 And thanks to this thread, I realize why I used a Semaphore in the first place. With a Semaphore you can control it so that only one instance of the semaphore will ever exist no matter what. But again, this function was changed when it was originally included and differs significantly from what I originally wrote. I hate the standard UDF version and do not use it. Ironic that a function designed to implement a simple pattern was re-written to provide an option to not conform to the pattern it was designed to implement. It frustrates me that others meddle with things they don't comprehend.
Moderators SmOke_N Posted May 8, 2008 Moderators Posted May 8, 2008 And thanks to this thread, I realize why I used a Semaphore in the first place. With a Semaphore you can control it so that only one instance of the semaphore will ever exist no matter what. But again, this function was changed when it was originally included and differs significantly from what I originally wrote. I hate the standard UDF version and do not use it.Ironic that a function designed to implement a simple pattern was re-written to provide an option to not conform to the pattern it was designed to implement. It frustrates me that others meddle with things they don't comprehend.Thus the reason I still use CreateSemaphore . Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
PsaltyDS Posted May 8, 2008 Posted May 8, 2008 And thanks to this thread, I realize why I used a Semaphore in the first place. With a Semaphore you can control it so that only one instance of the semaphore will ever exist no matter what. But again, this function was changed when it was originally included and differs significantly from what I originally wrote. I hate the standard UDF version and do not use it.Ironic that a function designed to implement a simple pattern was re-written to provide an option to not conform to the pattern it was designed to implement. It frustrates me that others meddle with things they don't comprehend.Well, there's was my parents alarm clock when I was 10, the old VCR when I was 14, a 72 Dodge Dart slant-6 when I was 19, and Valik's UDFs today -- all things I took apart and meddled with BECAUSE I didn't comprehend them. It's kind of how I learn. I am fully aware that I didn't IMPROVE any of those things by mucking about with them, but I learned something useful from every one of them.When I stop trying to figure out things I don't comprehend it will be time to put me in the box and order some flowers... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Valik Posted May 8, 2008 Posted May 8, 2008 Well, there's was my parents alarm clock when I was 10, the old VCR when I was 14, a 72 Dodge Dart slant-6 when I was 19, and Valik's UDFs today -- all things I took apart and meddled with BECAUSE I didn't comprehend them. It's kind of how I learn. I am fully aware that I didn't IMPROVE any of those things by mucking about with them, but I learned something useful from every one of them.When I stop trying to figure out things I don't comprehend it will be time to put me in the box and order some flowers... Do you honestly think I was talking about you when I said people shouldn't meddle with things they don't comprehend? Please re-read my post again if you do. Otherwise, mind explaining what your little rant has to do with anything?
PsaltyDS Posted May 8, 2008 Posted May 8, 2008 Do you honestly think I was talking about you when I said people shouldn't meddle with things they don't comprehend? Please re-read my post again if you do. Otherwise, mind explaining what your little rant has to do with anything?Not really. I figured you meant whoever modified your UDF when it was included in the distro.The reply was meant to be humorous, but evidently failed. I'll go review my complete collection of Three Stooges DVDs and try to be funny again tomorrow in another topic. On the slightly more on-topic educational front, I'm busily checking out the CreateSemaphore function per SmOke_N's hint, in an attempt to crack open yet one more thing I don't comprehend... yet. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
aec Posted May 8, 2008 Posted May 8, 2008 A small example expandcollapse popup#include <GuiConstants.au3> Global $b_WantAChair=FALSE $hGUI = GuiCreate("ANYONE for a CHAIR? - (MUTEX syncronization)", 400,80) GuiCtrlCreateLabel('Open a few instances of the script and press the GO button.', 10,10,340,20) GuiCtrlCreateGroup('', 10,30,380,40) $c_lbl_WantAChair = GuiCtrlCreateLabel('', 20,44,286,20) $c_btn_WantAChair = GuiCtrlCreateButton('GO', 332,42,50,20) GuiSetState() While 1 $msg = GuiGetMsg() If $b_WantAChair Then $b_WantAChair = _WantAChair() EndIf Switch $msg Case $GUI_EVENT_CLOSE Exit Case $c_btn_WantAChair $b_WantAChair=TRUE Case Else EndSwitch WEnd Func _WantAChair() GuiCtrlSetData($c_lbl_WantAChair, "Looking for a chair...") Sleep(2000) $hMutex = _GetMutex("FreeChair") If @error=0 Then ; Free chair GuiCtrlSetState($c_btn_WantAChair, $GUI_DISABLE) GuiCtrlSetData($c_lbl_WantAChair, "Here it is!") Sleep(2000) For $i=1 To 20 GuiCtrlSetData($c_lbl_WantAChair, "I'm sitting for " & $i & ' seconds') Sleep(1000) Next GuiCtrlSetData($c_lbl_WantAChair, "That's enough! Time to go.") Sleep(2000) GuiCtrlSetData($c_lbl_WantAChair, "") ; Time to go _ReleaseMutex($hMutex) GuiCtrlSetState($c_btn_WantAChair, $GUI_ENABLE) return FALSE ; Finished Else ; I'm touching the chair but cant use it, so let it go! _ReleaseMutex($hMutex) GuiCtrlSetData($c_lbl_WantAChair, "No free chair.") Sleep(2000) return TRUE EndIf EndFunc Func _GetMutex($sOccurenceName) Local $ERROR_ALREADY_EXISTS = 183, $handle, $lastError $handle = DllCall("kernel32.dll", "int", "CreateMutex", "int", 0, "long", 1, "str", $sOccurenceName) $lastError = DllCall("kernel32.dll", "int", "GetLastError") If $lastError[0] = $ERROR_ALREADY_EXISTS Then Return SetError($lastError[0], $lastError[0], $handle[0]) EndIf Return SetError(0, 0, $handle[0]) EndFunc Func _ReleaseMutex($hMutex) If $hMutex Then $releasemutex = DllCall("kernel32.dll", "int", "ReleaseMutex", "long", $hMutex) If $hMutex Then DllCall("kernel32.dll", "int", "CloseHandle", "long", $hMutex) EndFunc
Moderators SmOke_N Posted May 8, 2008 Moderators Posted May 8, 2008 (edited) Not really. I figured you meant whoever modified your UDF when it was included in the distro. The reply was meant to be humorous, but evidently failed. I'll go review my complete collection of Three Stooges DVDs and try to be funny again tomorrow in another topic. On the slightly more on-topic educational front, I'm busily checking out the CreateSemaphore function per SmOke_N's hint, in an attempt to crack open yet one more thing I don't comprehend... yet. Same concept really as far as the functions go:Global $hSemaphoreGlobal ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning") ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) ConsoleWrite("Semaphore Released: " & (_ReleaseSemaphore($hSemaphoreGlobal) = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) Func _SemaphoreExists($szSemaphoreName) Local $hSemaphore = DllCall("Kernel32.dll", "hwnd", "OpenSemaphore", "int", BitOR(0x1F0001, 0x0002), "int", 1, "str", $szSemaphoreName) If IsArray($hSemaphore) And $hSemaphore[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore[0]) EndIf Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_SemaphoreExists Func _CreateSemaphore($szSemaphoreName, $nAllowMax = 1) Local $hSemaphore = DllCall("Kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", $nAllowMax, "str", $szSemaphoreName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If (IsArray($aGLE) And $aGLE[0] = 183) Then Return 0 Return $hSemaphore[0] EndFunc ;==>_CreateSemaphore Func _ReleaseSemaphore($hSemaphore, $nAllowed = 1) Local $aRM = DllCall("kernel32.dll", "int", "ReleaseSemaphore", "hwnd", $hSemaphore, "long", $nAllowed, "ptr", 0) ;Debug .... Local $aGLE = DllCall("kernel32.dll", "int", "GetLastError") ConsoleWrite("Error Releasing: " & $aGLE[0] & @CRLF) ; If it equals 298 (to many instances? Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore) If (IsArray($aRM) And $aRM[0] > 0) And (IsArray($aCH) And $aCH[0] > 0) Then Return 1 Return 0 EndFunc ;==>_ReleaseSemaphoreAlthough I am having a problem releasing the damn semaphore for some reason. Edit: Here you can decide how many to allow etc.. Edited May 8, 2008 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
PsaltyDS Posted May 8, 2008 Posted May 8, 2008 (edited) Same concept really as far as the functions go:Global $hSemaphoreGlobal ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning") ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) ConsoleWrite("Semaphore Released: " & (_ReleaseSemaphore($hSemaphoreGlobal) = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) Func _SemaphoreExists($szSemaphoreName) Local $hSemaphore = DllCall("Kernel32.dll", "hwnd", "OpenSemaphore", "int", BitOR(0x1F0001, 0x0002), "int", 1, "str", $szSemaphoreName) If IsArray($hSemaphore) And $hSemaphore[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore[0]) EndIf Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_SemaphoreExists Func _CreateSemaphore($szSemaphoreName, $nAllowMax = 1) Local $hSemaphore = DllCall("Kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", $nAllowMax, "str", $szSemaphoreName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If (IsArray($aGLE) And $aGLE[0] = 183) Then Return 0 Return $hSemaphore[0] EndFunc ;==>_CreateSemaphore Func _ReleaseSemaphore($hSemaphore, $nAllowed = 1) Local $aRM = DllCall("kernel32.dll", "int", "ReleaseSemaphore", "hwnd", $hSemaphore, "long", $nAllowed, "ptr", 0) ;Debug .... Local $aGLE = DllCall("kernel32.dll", "int", "GetLastError") ConsoleWrite("Error Releasing: " & $aGLE[0] & @CRLF) ; If it equals 298 (to many instances? Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore) If (IsArray($aRM) And $aRM[0] > 0) And (IsArray($aCH) And $aCH[0] > 0) Then Return 1 Return 0 EndFunc ;==>_ReleaseSemaphoreAlthough I am having a problem releasing the damn semaphore for some reason. Edit: Here you can decide how many to allow etc.. And you get the error for too many instances. That points to exactly the part that confuses me the most (quoting MSDN): The count is increased by a specified amount by calling the ReleaseSemaphore function. This seems backwards. I thought of the count as being how many processes had a handle to that Semaphore. It seemed to make sense that more processes doing OpenSemaphore, for example, would increase the count, and each process that closed, did ReleaseSemaphore, or CloseHandle on it's handle to the Semaphore, would reduce the count. It's not that simple, of course. An interesting option you left off would be providing the pointer to catch lpPreviousCount from the existing Semaphore and report its value in your ConsoleWrite's. P.S. Adding some room in max count made the ReleaseSemaphore not fail: $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning", 5) >Running:(3.2.10.0):C:\Program Files\AutoIt3\autoit3.exe "C:\temp\Test\Test1.au3" Semaphore Exists: False Semaphore Created: 1812 Semaphore Exists: True Error Releasing: 127 Semaphore Released: True Semaphore Exists: False It's still odd to me that ReleaseSemaphore increases the count. Edit: Oh, explanation by Valik already posted below. Missed it while typing. Edited May 8, 2008 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Valik Posted May 8, 2008 Posted May 8, 2008 ReleaseSemaphore() is not how you release the resources for a Semaphore. Like virtually all objects, you use CloseHandle() to release the Semaphore. The function ReleaseSemaphore() does something completely different and reading MSDN will explain what it does.
PsaltyDS Posted May 9, 2008 Posted May 9, 2008 Seems to work like this: Global $hSemaphoreGlobal ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning") ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) ConsoleWrite("Semaphore Closed: " & (_CloseSemaphore($hSemaphoreGlobal) = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) Func _SemaphoreExists($szSemaphoreName) Local $hSemaphore = DllCall("Kernel32.dll", "hwnd", "OpenSemaphore", "int", BitOR(0x1F0001, 0x0002), "int", 1, "str", $szSemaphoreName) If IsArray($hSemaphore) And $hSemaphore[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore[0]) EndIf Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_SemaphoreExists Func _CreateSemaphore($szSemaphoreName, $nAllowMax = 1) Local $hSemaphore = DllCall("Kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", $nAllowMax, "str", $szSemaphoreName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If (IsArray($aGLE) And $aGLE[0] = 183) Then Return 0 Return $hSemaphore[0] EndFunc ;==>_CreateSemaphore Func _CloseSemaphore($hSemaphore) Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore) ;Debug .... Local $aGLE = DllCall("kernel32.dll", "int", "GetLastError") ConsoleWrite("LastError on closing: " & $aGLE[0] & @CRLF) If IsArray($aCH) And $aCH[0] > 0 Then Return 1 Return 0 EndFunc ;==>_ReleaseSemaphore Don't have time to try it with multiple instances right now... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Moderators SmOke_N Posted May 9, 2008 Moderators Posted May 9, 2008 Seems to work like this: Global $hSemaphoreGlobal ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning") ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) ConsoleWrite("Semaphore Closed: " & (_CloseSemaphore($hSemaphoreGlobal) = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) Func _SemaphoreExists($szSemaphoreName) Local $hSemaphore = DllCall("Kernel32.dll", "hwnd", "OpenSemaphore", "int", BitOR(0x1F0001, 0x0002), "int", 1, "str", $szSemaphoreName) If IsArray($hSemaphore) And $hSemaphore[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore[0]) EndIf Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_SemaphoreExists Func _CreateSemaphore($szSemaphoreName, $nAllowMax = 1) Local $hSemaphore = DllCall("Kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", $nAllowMax, "str", $szSemaphoreName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If (IsArray($aGLE) And $aGLE[0] = 183) Then Return 0 Return $hSemaphore[0] EndFunc ;==>_CreateSemaphore Func _CloseSemaphore($hSemaphore) Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore) ;Debug .... Local $aGLE = DllCall("kernel32.dll", "int", "GetLastError") ConsoleWrite("LastError on closing: " & $aGLE[0] & @CRLF) If IsArray($aCH) And $aCH[0] > 0 Then Return 1 Return 0 EndFunc ;==>_ReleaseSemaphore Don't have time to try it with multiple instances right now... I know it works that way, but it wouldn't let me release the semaphore which was erking me a bit. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
Valik Posted May 9, 2008 Posted May 9, 2008 Ron, the Semaphore count is between the 0 and the maximum value you specify at creation time. You specified a maximum value of 1 and an initial value of 1. ReleaseSemaphore() *increases* the count by the amount you specify up to the maximum value you specified at creation time. Since you specified a maximum value of 1 and an initial value of 1, ReleaseSemaphore() can't do anything because the maximum count has been reached.
Moderators SmOke_N Posted May 9, 2008 Moderators Posted May 9, 2008 Ron, the Semaphore count is between the 0 and the maximum value you specify at creation time. You specified a maximum value of 1 and an initial value of 1. ReleaseSemaphore() *increases* the count by the amount you specify up to the maximum value you specified at creation time. Since you specified a maximum value of 1 and an initial value of 1, ReleaseSemaphore() can't do anything because the maximum count has been reached.<ding> thanks Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
Fzz Posted July 16, 2008 Posted July 16, 2008 Not sure what the etiquette is for reviving an old post but this look like exactly what I need but I'm having a problem with it. Sorry if this should be a new post but the code is here so here goes. The last post of the code works great unless two applications think it's their turn to create the semaphore at the same time. Then it appears the semaphore gets "corrupted" and can no longer be created once it has been released. I've added a few lines to simulate what I mean. expandcollapse popupGlobal $hSemaphoreGlobal Global $hSemaphoreGlobal2 ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning") ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal2 = _CreateSemaphore("WDTCodeRunning"); remove these 2 lines and it works fine ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal2 & @CRLF) ConsoleWrite("Semaphore Closed: " & (_CloseSemaphore($hSemaphoreGlobal) = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) $hSemaphoreGlobal = _CreateSemaphore("WDTCodeRunning") ConsoleWrite("Semaphore Created: " & $hSemaphoreGlobal & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) ConsoleWrite("Semaphore Closed: " & (_CloseSemaphore($hSemaphoreGlobal) = 1) & @CRLF) ConsoleWrite("Semaphore Exists: " & (_SemaphoreExists("WDTCodeRunning") = 1) & @CRLF) Func _SemaphoreExists($szSemaphoreName) Local $hSemaphore = DllCall("Kernel32.dll", "hwnd", "OpenSemaphore", "int", BitOR(0x1F0001, 0x0002), "int", 1, "str", $szSemaphoreName) If IsArray($hSemaphore) And $hSemaphore[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore[0]) EndIf Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc;==>_SemaphoreExists Func _CreateSemaphore($szSemaphoreName, $nAllowMax = 1) Local $hSemaphore = DllCall("Kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", $nAllowMax, "str", $szSemaphoreName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If (IsArray($aGLE) And $aGLE[0] = 183) Then Return 0 Return $hSemaphore[0] EndFunc;==>_CreateSemaphore Func _CloseSemaphore($hSemaphore) Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hSemaphore) ;Debug .... Local $aGLE = DllCall("kernel32.dll", "int", "GetLastError") ConsoleWrite("LastError on closing: " & $aGLE[0] & @CRLF) If IsArray($aCH) And $aCH[0] > 0 Then Return 1 Return 0 EndFunc;==>_ReleaseSemaphore I would think that the second global would fail as it does but then it should go on as usual and allow the semaphore to be released and recreated as usual. Thanks!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now