Reputation: 4396
I'm trying to use semphore on my mac, and it throws me an error when I try to close an open semaphore. All initializations were successful, but when it attempted to close second semaphore, it returned bad file descriptor error.
Below code is wrapper for open and close:
void init_sem(sem_t * s, char * sema_name, int value)
{
if((s = sem_open(sema_name, O_CREAT, 0644, value)) == SEM_FAILED)
{
perror("sem_open");
exit(1);
}
printf("init semaphore %s\n", sema_name);
}
void destroy_sem(sem_t * s, char * sema_name)
{
printf("destroying, %s\n", sema_name);
if (sem_close(s) == -1) {
perror("sem_close");
exit(EXIT_FAILURE);
}
if (sem_unlink(sema_name) == -1) {
perror("sem_unlink");
exit(EXIT_FAILURE);
}
}
and in main.c
sem_t * s, *a, *b;
init_sem(s, "/cs", 0);
init_sem(a, "/ps", 0);
init_sem(b, "/bs", 0);
destroy_sem(s, "/cs");
destroy_sem(a, "/ps"); //got error here
destroy_sem(b, "/bs");
Any idea why it doesn't work?
Upvotes: 0
Views: 773
Reputation: 5179
Gabe's answer is correct.
As an alternative, you can do this:
void init_sem(sem_t ** s, char * sema_name, int value)
{
if((*s = sem_open(sema_name, O_CREAT, 0644, value)) == SEM_FAILED)
{
perror("sem_open");
exit(1);
}
printf("init semaphore %s\n", sema_name);
}
void destroy_sem(sem_t * s, char * sema_name)
{
printf("destroying, %s\n", sema_name);
if (sem_close(s) == -1) {
perror("sem_close");
exit(EXIT_FAILURE);
}
if (sem_unlink(sema_name) == -1) {
perror("sem_unlink");
exit(EXIT_FAILURE);
}
}
int main (int argc, const char * argv[])
{
sem_t * s, *a, *b;
init_sem(&s, "/cs", 0);
init_sem(&a, "/ps", 0);
init_sem(&b, "/bs", 0);
destroy_sem(s, "/cs");
destroy_sem(a, "/ps");
destroy_sem(b, "/bs");
}
Upvotes: 0
Reputation: 86718
You are passing in *s
where it becomes a local variable. When you assign a value to it, the value goes away when init_sem
returns. Then when you call destroy_sim
, you are passing in an uninitialized value to sem_close
.
You need to return the value that gets returned from sem_open
:
sem_t * init_sem(char * sema_name, int value)
{
sem_t * s;
if((s = sem_open(sema_name, O_CREAT, 0644, value)) == SEM_FAILED)
{
perror("sem_open");
exit(1);
}
printf("init semaphore %s\n", sema_name);
return s;
}
Then call it like this:
s = init_sem("/cs", 0);
a = init_sem("/ps", 0);
b = init_sem("/bs", 0);
Upvotes: 1