The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: asmftw on November 03, 2007, 04:16:21 PM

Title: Mutex Problem
Post by: asmftw on November 03, 2007, 04:16:21 PM
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.
Title: Re: Mutex Problem
Post by: Ehtyar on November 04, 2007, 12:39:56 AM
You should be using a wait function (http://msdn2.microsoft.com/en-us/library/ms687069.aspx) 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.
Title: Re: Mutex Problem
Post by: asmftw on November 12, 2007, 03:49:13 AM
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.
Title: Re: Mutex Problem
Post by: Mark Jones on November 12, 2007, 03:59:04 PM
Round-about solution: create a third, supervisory thread, which monitors the other threads and terminates duplicates of process A or B?
Title: Re: Mutex Problem
Post by: donkey on November 12, 2007, 11:07:31 PM
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.
Title: Re: Mutex Problem
Post by: asmftw on November 13, 2007, 01:57:41 AM
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 :/
Title: Re: Mutex Problem
Post by: donkey on November 13, 2007, 05:47:25 AM
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
Title: Re: Mutex Problem
Post by: asmftw on November 29, 2007, 06:23:29 AM
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 :)