- Detecting when a process is abruptly terminated...
- Posted by Chris Thomasson on May 8th, 2008
I am doing a general-purpose shared memory allocator and need to determine
when a process has been unexpectedly terminated so that it can make a
reclaim adjustment to the allocator state. In other words, if ProcessA
allocates a block of shared memory, and gets terminates, I want to be able
to catch this and reclaim the block. What do you think is the most elegant
solution? I want to avoid creating a "watchdog" process...
--
Chris M. Thomasson
http://appcore.home.comcast.net
- Posted by foobar on May 8th, 2008
Elegant one I think would be one that uses Operating System
notifications directly.
Some thing like you maintain list of process handles that register
with your memory allocator.
Use WaitForMultipleObjects on all of above handles from a thread
inside your process.
If this call gets unblocked then you know some process has exited. Now
find out which process has exited and take action.
To update the list of process handles when new process registers or an
existing process unregisters you need to
devise a method. For example, let us say you add one other
synchronization object handle to the above list so that you can
intentionally
unblock the waiting thread when you need to update the list of process
handles. I don't think I am building a full
fledged solution here but I think it can be taken further to
accomplish the task.
"Watchdog" or some monitor program running in the background that
continuously monitors the processes is
one simple approach with a few drawbacks.
WMI also has the support to send event notifications when process
terminates. I think you will need to look at
Win32_ProcessStopTrace class and use it appropriately. In this case
you are introducing WMI service
into the solution and you would need to handle cases like what should
happen when WMI service restarts, etc.
On May 8, 11:25 am, "Chris Thomasson" <cris...@comcast.net> wrote:
- Posted by Chris Thomasson on May 10th, 2008
"foobar" <somefoobar@gmail.com> wrote in message
news:e9d40eca-c317-4229-b1e6-923b8bb65440@y38g2000hsy.googlegroups.com...
[...]
Humm... Well, it looks like I have to use a manager process. I don't think
there is any other clean method for detecting and recovering from
TerminateProcess. Okay, that's fine. Now, I need to think about efficient
means of maintaining coherency when process get terminated in the middle of
a critical-section. Windows process level mutexs have the WAIT_ABANDONDED
state. The following threads deals with some of this:
http://groups.google.com/group/comp....f2a233bd65bf8a
http://groups.google.com/group/comp....775d829f3f1259
(read all...)
Basically, you keep a version number in the critical-section in order to
detect different "levels" of coherent data. Something like:
lock();
// see if we need to recover from a disaster!
if (version != 3) {
if (version > -1 && version < 3) {
// perform recovery
switch (version) {
case 0:
case 1:
case 2:
}
} else {
// the version is trashed! Something very bad happened!
abort();
}
}
// zero version
// membar
--------------------------------------
// perform action 1
--------------------------------------
// membar
// inc version
--------------------------------------
// perform action 2
--------------------------------------
// membar
// inc version
--------------------------------------
// perform action 3
--------------------------------------
// membar
// inc version
assert(version == 3);
unlock();
Any suggestions?
- Posted by boris on May 10th, 2008
"Chris Thomasson" <cristom@comcast.net> wrote in message
news:fsidnbwvkJFOl7jVnZ2dnUVZ_u-dnZ2d@comcast.com...
hEventOkForClientToProceed - manual reset event;
hEventNotifyManager - auto reset event;
in client process:
while (1)
{
ret = WaitForSingleObject(hMutex,INFINITE);
if (ret ==WAIT_ABANDONED)
CloseHandle(hMutex);
// full memory fence
if ( pSharedMemory->mutexVersion != mutexVersion)
{
ResetEvent(hEventOkForClientToProceed);
SetEvent(hEventNotifyManager);
WaitForSingleObject(hEventOkForClientToProceed,INF INITE);
}
mutexVersion = pSharedMemory->mutexVersion;
hMutex = OpenMutex(SYNCHRONIZE,FALSE,pSharedMemory->strMutexName);
continue;
}
break;
}
in manager process:
WaitForSingleObject(hEventNotifyManager,INFINITE);
//Validate/repair shared memory state/data;
CloseHandle(hMutex);
while (1)
{
// full memory fence
strcpy(pSharedMemory->strMutexName,MyGenerateMutexName());
pSharedMemory->mutexVersion++;
hMutex= CreateMutex(NULL.TRUE,pSharedMemory->strMutexName);
if ( hMutex )
{
if ( ERROR_ALREADY_EXISTS == GetLastError() )
{
continue;
}
ReleaseMutex(hMutex);
break;
}
else
{
// unrecoverable error
}
}
// full memory fence
SetEvent(hEventOkForClientToProceed);
One thing missing: syncronising access to control structures
(pSharedMemory->strMutexName, pSharedMemory->mutexVersion) - is it needed?
Boris
- Posted by boris on May 10th, 2008
Oops: bug fix (see inline below).
"boris" <someone@nospam.net> wrote in message
news:48257a55$0$34507$742ec2ed@news.sonic.net...
CloseHandle(hMutex);