Prev: Help needed in hooking MS Office File Open/Save Dialog ........
Next: Is it possible to determine (programmatically) if system was just powered up or rebooted
From: Kevin English on 9 Jul 2010 20:54 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 10 Jul 2010 10:56 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 12 Jul 2010 01:53
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 |