News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Mutex Problem

Started by asmftw, November 03, 2007, 04:16:21 PM

Previous topic - Next topic

asmftw

Hello, I have to processes in memory. The first one starts and creates a mutex. Then the second does a loop every 15 seconds trying to create the same mutex or else it does not start its main functions, so only one of the processes can be running at once. The problem is that when i exit the first process, the second process still thinks the mutex still exists. So basically, when I close an app the improper way, the mutex is not destroyed.

Ehtyar

You should be using a wait function to suspend the operations of the second application. The mutex will be signaled when the first application releases ownership (after claling ReleaseMutex or terminating).

Ehtyar.

asmftw

that's not what i want to do. When the app crashes, i want the mutex to be destroyed with it, which is not what is currently happening.

Mark Jones

Round-about solution: create a third, supervisory thread, which monitors the other threads and terminates duplicates of process A or B?
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

donkey

Well, Windows does take care of this problem quite effectively. You can use OpenMutex to obtain a handle, if the return value from GetLastError is WAIT_ABANDONED then the owner process has terminated without releasing the mutex and you can take it from there, if the error is ERROR_FILE_NOT_FOUND then the mutex does not exist. Once the new process has received a WAIT_ABANDONED error it assumes ownership of the mutex and can destroy it if needed. At least that's how I understand it, can't say I have had the problem though.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

asmftw

hmm donkey that sounds like a good idea but it still doesn't work for some reason. OpenMutex just returns a random hex value that increases each time. I added a getlasterror call right after it and it returns ERROR_ALREADY_EXISTS :/

Here's my code:
WaitForMutexToLeave:

; Make sure only one copy runs.
    invoke CreateMutexA,0,0,ADDR MutexString   ; try to create the mutex
    test eax,eax                               ; No copies running yet?
    jz BeginProc                               ; Start the process

    invoke OpenMutexA,\
      01F0001h,\                               ; (MUTEX_ALL_ACCES)
      TRUE,\                                   ; Do inherit
      ADDR MutexString                         ; Mutex String

    invoke GetLastError
    cmp eax,WAIT_ABANDONED                     ; Is the other process dead?
    jz BeginProc                               ; If yes, start the process

    invoke Sleep,100
    jmp WaitForMutexToLeave

BeginProc:

...


I have no clue why it wont work, it seems perfectly logical :/

donkey

Hi,

You should use SetLastError after the CreateMutex in order to determine if there is an actual error when OpenMutex is executed otherwise you simply get the error from CreateMutex. However, I think I may have misunderstood the explanation since it is a problem I never deal with, as in the first response you should be using one of the wait functions, it is those functions that return the WAIT_ABANDONED error code. So your code would look something like this...

WaitForMutexToLeave:

; Make sure only one copy runs.
    invoke CreateMutexA,0,0,ADDR MutexString   ; try to create the mutex
    test eax,eax                               ; No copies running yet?
    jz BeginProc                               ; Start the process


    invoke OpenMutexA,\
      01F0001h,\                               ; (MUTEX_ALL_ACCES)
      TRUE,\                                   ; Do inherit
      ADDR MutexString                         ; Mutex String

    invoke WaitForSingleObject, eax, -1

    invoke GetLastError
    cmp eax,WAIT_ABANDONED                     ; Is the other process dead?
    jnz WaitForMutexToLeave              ; If not, restart the wait

;    invoke Sleep,100
;    jmp WaitForMutexToLeave

BeginProc:


No need for the loop which only eats up processor slices anyway, Try it, it might work.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

asmftw

Thanks donkey, problem solved!

Here's the code for anyone that wants it:

; A message box will be displayed. When you close it,
; the app will be destroyed allowing another copy to begin its work

.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc

include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

.data
mutexName db "Global\TEST"
hMutex dd 0

.code

start:

WaitForMutexToLeave:

    invoke CreateMutexA,0,0,ADDR mutexName     ; try to create the mutex
    test eax,eax                               ; No copies running yet?
    je BeginProc                               ; Start the process

    invoke OpenMutexA,\
      01F0001h,\                               ; (MUTEX_ALL_ACCES)
      TRUE,\                                   ; Do inherit
      ADDR mutexName                           ; Mutex String
    mov [hMutex],eax                           ; save the handle

    invoke WaitForSingleObject, eax, -1
    cmp eax,WAIT_ABANDONED                     ; Is the other process dead?
    je BeginProc                               ; If not, restart the wait

      push dword ptr [hMutex]
    call CloseHandle

    jmp WaitForMutexToLeave
BeginProc:
      push dword ptr [hMutex]
    call CloseHandle
    invoke MessageBox,0,0,0,0
    invoke ExitProcess,0
end start


I've never had this much trouble coding anything, so I hope someone on the internet finds this useful :)