From: Kevin English on
On Fri, 09 Jul 2010 11:14:50 -0700, Larry Lindstrom
<larryl_turbo(a)hotmail.com> wrote:

> The following fragment doesn't seem to work:
>
> hmutex = CreateMutex(NULL, FALSE, mutex_name);
>
> wait_return = WaitForSingleObjectEx(hmutex, wait_ms, TRUE);
>
> When the first process is running, and holding the mutex,
>WaitForSingleObjectEx() returns WAIT_ABANDONED on the first call.
Looks like it is working as documented. Some thread aquired the mutex
and then the thread exited without releasing the mutex. The first
process is not holding the mutex any longer. The thread that locked
the mutex with WaitForSingleObject[Ex] no longer exists.
> Subsequent calls to WaitForSingleObjectEx(), while the first process
>continues to run, return WAIT_OBJECT_0.
All calls from all threads, or only calls from a specific thread?
The next call should, as should all calls subsequent calls from the
same thread. The first process can continue to run as long as it
wants, but if the thread that aquired the mutex with
WaitForSingleObject[Ex} no longer exists, the mutex is available for
the next thread waiting on it.
> I have so much work to do. But it looks like I'll be plowing
>through 146 pages of Richter's chapter on thread synchronization.
So much work can be good or bad depending on how you look at it.
Understanding Richter's chapter is worthwhile.
>
> I'm seeing references to event objects, asynchronous procedure calls
>and other topics. A lot of time can be consumed trying to understand
>issues that turn out to have no bearing on the problem at hand.
Very True. So what is the problem at hand?

To me it looks like you are trying to use a Mutex to prevent the same
process from running multiple times. This is a documented way of
doing that. It is not necessary for the process to ever aquire the
Mutex in order to accomplish this. Simply use CreateMutex(), check
for errors first, then check if if the mutex already was created by
another process (if GetLastError()==ERROR_ALREADY_EXISTS).
However, you must check for real errors first - i.e. hmutex==NULL.
And as always, close and handles that you aquire when they are no
longer needed.
It also looks like you aquire the Mutex in your first process and the
thread that aquires it exits, thus releasing the mutex.
What is the purpose of aquiring the Mutex? If all you care about is
whether process A or B should be allowed to run, I doubt that you
really need to aquire it. Also you don't show the code from the first
process that aquires the Mutex or how the thread that aquired it
terminates.
Start with a description of what you really want to achieve. I think
it will turn out to be a lot easier than you are making it look.
WIN32 Mutexes are rock solid and very worthwhile understanding and
using.
Hope this helps.
--
Kevin English
From: Kevin English on
On Sat, 10 Jul 2010 04:12:06 -0700, Larry Lindstrom
<larryl_turbo(a)hotmail.com> wrote:
> My mutex test works so well to prevent multiple instances of the
>same program from running, I thought that a couple of simple twists of
>that code would provide a reliable method to prevent the Second program
>from running until the First program had terminated.
Larry,
It should work.
My approach would be
ProcessA:
if ((hmtx = CreateMutex(...))==NULL)
error msg and exit
if (GetLastError()==ERROR_ALREADY_EXISTS)
error msg and exit
/*
* ProcessA now has handle to the mutex but does not own the mutex
* Check and see if db needs converted or whatever
*/
if (dbconversionneeded()) {
WaitForSingleObject(hmtx,...);
/* error checking omitted */
/* Now we own the mutex */
CreateProcess(ProcessB);
/* Make sure processB has time to start */
WaitForInputIdle(processB);
ReleaseMutex(hmtx);
ExitProcess();
}
ProcessB:
if ((hmtx = CreateMutex(...))==NULL)
error msg and exit
/*
* we dont care if we created the mutex or not
* so dont check if it already exists, just wait until
* we can get ownership of it
*/
WaitForSingleObject(hmtx,...);
/* error checking omittted */
/*
* We own the mutex and can convert the data base
* but we should check if conversion is really needed just in case
* this process got started other than through the call to
* CreateProcess() in ProcessA
*/
convertdb();
ReleaseMutex();
ExitProcess();
--
Kevin English
From: Larry Lindstrom on
On 7/10/2010 7:56 AM, Kevin English wrote:
> On Sat, 10 Jul 2010 04:12:06 -0700, Larry Lindstrom
> <larryl_turbo(a)hotmail.com> wrote:
>> My mutex test works so well to prevent multiple instances of the
>> same program from running, I thought that a couple of simple twists of
>> that code would provide a reliable method to prevent the Second program
>>from running until the First program had terminated.
> Larry,
> It should work.
> My approach would be
> ProcessA:
> if ((hmtx = CreateMutex(...))==NULL)
> error msg and exit
> if (GetLastError()==ERROR_ALREADY_EXISTS)
> error msg and exit
> /*
> * ProcessA now has handle to the mutex but does not own the mutex
> * Check and see if db needs converted or whatever
> */
> if (dbconversionneeded()) {
> WaitForSingleObject(hmtx,...);
> /* error checking omitted */
> /* Now we own the mutex */
> CreateProcess(ProcessB);
> /* Make sure processB has time to start */
> WaitForInputIdle(processB);
> ReleaseMutex(hmtx);
> ExitProcess();
> }
> ProcessB:
> if ((hmtx = CreateMutex(...))==NULL)
> error msg and exit
> /*
> * we dont care if we created the mutex or not
> * so dont check if it already exists, just wait until
> * we can get ownership of it
> */
> WaitForSingleObject(hmtx,...);
> /* error checking omittted */
> /*
> * We own the mutex and can convert the data base
> * but we should check if conversion is really needed just in case
> * this process got started other than through the call to
> * CreateProcess() in ProcessA
> */
> convertdb();
> ReleaseMutex();
> ExitProcess();

Thanks again Keven and Allan:

I almost had it before. I needed to make First Program's call to
CreateMutex() with the initial owner flag set to true. This set proper
signaling for Second Program's WaitForSingleObject().

You kept me focused on the CerateMutex() and WaitForSingleObject()
functions, which saved me from wondering through unfruitful
investigations of other topics.

Larry