Jump to content

Recommended Posts

Posted

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.

Posted

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
Posted

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.

Posted

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
Posted

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?
Posted

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.

:D

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
Posted

A small example

#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
Posted (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.

:D

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    ;==>_ReleaseSemaphore
Although I am having a problem releasing the damn semaphore for some reason.

Edit:

Here you can decide how many to allow etc..

Edited 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.

Posted (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    ;==>_ReleaseSemaphore
Although 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 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
Posted

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.

Posted

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
Posted

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.

Posted

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
Posted

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.

  • 2 months later...
Posted

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.

Global $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!

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...