Re: Detecting a running application
From: Rob Kennedy (me3_at_privacy.net)
Date: 08/28/04
- Next message: Stark: "IndexOf"
- Previous message: J French: "Re: Detecting a running application"
- In reply to: David Reeve: "Re: Detecting a running application"
- Next in thread: David Reeve: "Re: Detecting a running application"
- Reply: David Reeve: "Re: Detecting a running application"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 28 Aug 2004 02:21:42 -0500
David Reeve wrote:
> This reminded me I had some dubious 'one instance' code I was using
> throughout a lot of my production code. It showed up in MemProof as a number
> of errors associated with mutex handling. However, because it worked, and
> the beasts were snapping at my heels I never really followed up on it till
> now. So a quick read of W32 help raises a few questions about the code in
> the FAQ.
>
> In the FAQ, this bit is OK...
>
> hMyMutex := CreateMutex (nil, True, pChar (Uppercase (ExtractFileName
> (Application.ExeName))
> if (hMyMutex = 0) or (GetLastError = error_Already_Exists) then
> do_something_about_it
>
> Though I doubt the need for (hMyMutex = 0) , and as Laura has it, it is
> simpler.
An already-existing mutex isn't the only reason CreateMutex might fail.
If the mutex already exists, but the user doesn't have sufficient
privileges to open it, then GetLastError will return Error_Access_Denied
(or something like that) and CreateMutex will return 0. You need to
check the handle value for 0, and you need to check GetLastError for
Error_Already_Exists.
> Another point I wasn't aware of is that mutexs share namespace with
> events, semaphores and file mapping objects, so it seems a sensible
> precaution to give it a unique name rather than name it from the app....
> small point no doubt.
Yes, it's a small point, but one that shouldn't be overlooked. Also, you
should pay attention to the different naming rules on various Windows
versions. The "global\" prefix is only meaningful on some, and will
cause errors on others. And if you have a global name, then you probably
shouldn't use "nil" as the first parameter to CreateMutex since only the
original mutex creator would have access to it.
> Now this bit raises some queries....
>
> finally
> ReleaseMutex (hMyMutex);
> end;
>
> Alerted to it by MemProof, I checked the return of this function. It fails
> because windows reckons the thread doesn't own it, and thus can't release
> it. Why? On stepping the value of hMyMutex is still as allocated by create.
> The create function was called with bInitialOwner param set True.
It was, but not because it's required. The technique for detecting
multiple instances does not have anything to do with the
mutual-exclusion properties of a mutex. All the technique is doing is
using the fact that Windows will tell you, atomically, which the named
object you request already exists. No program ever needs to have
ownership of the mutex, and thus no program ever really needs to release
ownership, either.
MSDN discourages setting bInitialOwner = True when using a mutex in this
way because "it can be difficult to be certain which process has initial
ownership."
> But, taking a slightly wider view, why release ownership, when what you want
> to do is close the handle?
Exactly. That code should call CloseHandle, not ReleaseMutex.
> And further to this, why close the handle? Help is pretty clear that the
> handle is closed when the app terminates.
Well, you'd do that to keep MemProof quiet. That's what got you
examining this in the first palce, after all!
-- Rob
- Next message: Stark: "IndexOf"
- Previous message: J French: "Re: Detecting a running application"
- In reply to: David Reeve: "Re: Detecting a running application"
- Next in thread: David Reeve: "Re: Detecting a running application"
- Reply: David Reeve: "Re: Detecting a running application"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|
|