Locking a shared memory object (crash safe )
Locking a shared memory object (crash safe )
- Subject: Locking a shared memory object (crash safe )
- From: Nicholaz Beresford <email@hidden>
- Date: Wed, 19 Mar 2008 14:28:01 +0100
I'm porting an application from WIN32 which does shared memory. Under
Windows we use a Named Mutex to lock the memory. This works well even
if the app crashes (Win32 releases the mutex when crashing).
Under darwin we're doing it via posix shared-mem and posix sems, but
posix sems retain their states when the app goes down, so from that
point every access to the shared mem will lock until the machine is
rebooted.
To avoid this I want to intercept the crash signals, post semaphores
and proceed with the standard signal handling. Details are below, but
what I'd like to know if this is sensible or if I'm doing something
utterly stupid (we're not using signal()/sigaction() anywhere else in
the code, so we're only dealing with the default behavior and want to
get a chance to clean up the most urgent stuff between the crash and the
standard crash-handler). From observation it seems to work as planned,
but I'm using this family of functions for the first time, so I'd want
to be sure (unless of course someone has a better way than using posix
sems in the first place, but flock() doesn't seeem to work on shared mem).
#### We're catching the following signals:
SIGHANDLER::InterceptSignal(SIGHUP, yesno);
SIGHANDLER::InterceptSignal(SIGINT, yesno);
SIGHANDLER::InterceptSignal(SIGABRT, yesno);
SIGHANDLER::InterceptSignal(SIGSTOP, yesno);
SIGHANDLER::InterceptSignal(SIGKILL, yesno);
SIGHANDLER::InterceptSignal(SIGTERM, yesno);
SIGHANDLER::InterceptSignal(SIGTRAP, yesno);
SIGHANDLER::InterceptSignal(SIGBUS, yesno);
SIGHANDLER::InterceptSignal(SIGSEGV, yesno);
SIGHANDLER::InterceptSignal(SIGILL, yesno);
SIGHANDLER::InterceptSignal(SIGFPE, yesno);
#### I'm setting up signal handlers like this:
struct sigaction new_action= NULLSTRUCT,
old_action= NULLSTRUCT;
ASSERT(signum<ARRAYMAX(SIGHANDLER::OldActions));
// Set up the structure to specify the new action
new_action.sa_handler= SIGHANDLER::SigHandler;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = SA_RESETHAND; // only once
sigaction(signum, NULL, &SIGHANDLER::OldActions[signum]);
if (old_action.sa_handler!=SIG_IGN)
sigaction(signum, &new_action, &SIGHANDLER::OldActions[signum]);
#### Then in the signal handler I'm restoring the old behavior (and
we're using sigaction with RESETHAND), then raise the signal again
(after posting my locked semaphores of course).
sigaction(signum, &SIGHANDLER::OldActions[signum], NULL);
memset(&SIGHANDLER::OldActions[signum], 0, sizeof(struct sigaction));
raise(signum); // raise the signal again to the previous handler
Thanks!
Nick
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden