Stanislav Pankevich
Stanislav Pankevich

Reputation: 11368

Can I delete a named semaphore created with sem_open?

I am experimenting with the named semaphores and there is something that I don't understand about the behavior of sem_close and sem_destroy. In my example, it looks like the semaphore that I create does not get deleted.

#include <iostream>

#include <semaphore.h>

int main() {
  char sem_name[] = "/sem-1";

  {
    sem_t *sptr = sem_open(sem_name, O_CREAT, 0644, 0);
    if (sptr != SEM_FAILED) {
      printf("sem_open success\n");

      // neither of these works
      sem_close(sptr);
      // sem_destroy(sptr);
    } else {
      printf("sem_open error #1: %s\n", strerror(errno));
    }
  }

  sem_t *sptr = sem_open(sem_name, O_CREAT | O_EXCL, 0644, 0);
  printf("sem_open error #2: %s\n", strerror(errno));
  assert(sptr != SEM_FAILED);

  return 0;
}

The output:

sem_open success
sem_open error #2: File exists
Assertion failed: (sptr != SEM_FAILED), function main, file /tmp/delete_me/main.cpp, line 22.

I would expect the assertion to not be hit and also the error #2 to not shown.

Additionally, macOS says that the sem_destroy method is deprecated but I am still using both sem_close() and sem_destroy but they both seem to not delete the semaphore.

Background: I am trying to port NASA Core Flight System to macOS. Their POSIX implementation uses sem_ calls and I am trying to understand if I can make them work on macOS with some minor modifications.

Upvotes: 1

Views: 2587

Answers (1)

l&#39;L&#39;l
l&#39;L&#39;l

Reputation: 47169

Since macOS only recognizes named semaphores, using sem_destroy() won't work. sem_destroy() destroys an unnamed semaphore at the address pointed to by sem. Only a semaphore that has been initialized by sem_init() should be destroyed using sem_destroy().

You could likely overcome this issue by using sem_unlink:

...
sem_close(sptr);
sem_unlink(sem_name);
...

SEM_UNLINK(2)

NAME
sem_unlink -- remove a named semaphore

SYNOPSIS

 #include <semaphore.h>
 int sem_unlink(const char *name);

DESCRIPTION
The named semaphore named name is removed. If the semaphore is in use by other processes, then name is immediately disassociated with the sema-phore, semaphore, phore, but the semaphore itself will not be removed until all references to it have been closed. Subsequent calls to sem_open() using name will refer to or create a new semaphore named name.

 If successful, `sem_unlink()` will return 0.  Otherwise, -1 is returned and
 errno is set, and the state of the semaphore is unchanged.

ERRORS
sem_unlink() succeeds unless:

 [EACCES]           Permission is denied to be remove the semaphore.

 [ENAMETOOLONG]     name exceeded SEM_NAME_LEN characters.

 [ENOENT]           The named semaphore does not exist.

macOS Manual Pages | sem_unlink()

Upvotes: 2

Related Questions