Re: What if process crashes while holding a locked semaphore?
Re: What if process crashes while holding a locked semaphore?
- Subject: Re: What if process crashes while holding a locked semaphore?
- From: Terry Lambert <email@hidden>
- Date: Tue, 31 Mar 2009 04:24:02 -0700
This is what sem_trywait() is for.
A typical trick that's often used is to give the semaphore the value
of the pid holding the semaphore, then use sem_getvalue() to get the
pid and them kill(pid, 0); if the process is alive, you will get a
success for the kill or you will get an EPERM, indicating that the
process exists but you don't have permission to send it signals. If
the process doesn't exist, then you'll get ESRCH and you can cons up
the necessary ops to take over as the new owner.
An easy thing to do would be to switch to using System V semaphores
instead, and set the SEM_UNDO flag on a semop() to tell it what to
subtract from the value should the process crash (the semadj value).
That will resource track it without you needing to guess.
Another easy fix would be to not crash. 8-).
-- Terry
On Mar 30, 2009, at 11:42 PM, Jerry Krinock wrote:
David, thank you for the lesson in semaphore.h. I had been
wondering what that 'value' was for. Now I don't have to use a
crowbar any more :)
However, my bad code was not causing this particular problem.
Indeed, even using David's code, the system still does not release
the semaphore when a process crashes.
Steps to Reproduce:
1. Compile this code as a Standard "C" tool:
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <errno.h>
int main (int argc, const char * argv[]) {
sem_t* descriptor = sem_open("MySema1", // See (*)
(O_CREAT),
S_IRWXU,
1) ;
// (*) name must be < 31 characters or
// fails with errno = ENAMETOOLONG
if (descriptor != SEM_FAILED) {
printf("Waiting for semaphore\n") ;
sem_wait(descriptor);
printf("Acquired semaphore. Working.\n") ;
// Simulated work:
usleep(1000000) ;
// Uncomment the next line to crash
// *(char*)0 = 0 ;
printf("Done\n") ;
sem_post(descriptor);
sem_close(descriptor);
}
else {
printf("Unexpected error, errno=%d", errno) ;
return errno ;
}
return 0 ;
}
2. Run it a few times in Mac OS 10.5.6 and verify that it works.
3. Uncomment the *(char*)0=0.
4. Run it again, so it crashes.
5. Comment out the *(char*)0=0.
6. Run it again.
Expected result:
"Acquired semaphore...", since the system should have cleared the
semaphore value when the tool crashed.
Actual result:
"Waiting for semaphore", forever.
7. Change the semaphore name to "MySema2"
8. Run it again. It works again.
Why the unexpected result?
Thanks,
Jerry
_______________________________________________
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
_______________________________________________
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