Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Semaphores and shared memory already opened / Problem with O_EXCL flag

I’m currently working on a programm that has a shared memory and semaphores. However I have issues with initializing them. Whenever I wanna open them (whilst having the O_EXCL flag active I keep getting erros. That should mean they are already open when starting but I have no idea how or why.

static sem_t *s1 = NULL;

void initSEM(void)
{
    atexit(closeSEM);
    s1 = sem_open(SEM_1, O_CREAT | O_EXCL, 0600, 1);
    if (s1 == SEM_FAILED)
    {
        printf("%s", "ERROR: Semaphore 1 could not be opened.");
        exit(EXIT_FAILURE);
    }
}

void closeSEM(void)
{
    if (sem_close(s1) == -1)
    {
        exit(EXIT_FAILURE);
    }
    if (sem_close(s2) == -1)
    {
        exit(EXIT_FAILURE);
    }
    if (sem_close(s3) == -1)
    {
        exit(EXIT_FAILURE);
    }
    if (sem_unlink(SEM_1) == -1)
    {
        exit(EXIT_FAILURE);
    }
    if (sem_unlink(SEM_2) == -1)
    {
        exit(EXIT_FAILURE);
    }
    if (sem_unlink(SEM_2) == -1)
    {
        exit(EXIT_FAILURE);
    }
}

In my main function I just call this. Same thing for the shared memory. I have no idea why this is happening.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Your code, as written, need fail to open a single semaphore only once, and from then on, will never properly sem_unlink any of the semaphores, so they continue existing for the next program run.

The sequence of events is:

  1. At some point in development, a sem_open fails for whatever reason
  2. The corresponding sem_close then fails, and you exit(EXIT_FAILURE); rather than performing any remaining sem_close calls and all of the sem_unlink calls, so the named semaphore continues to exist
  3. On future runs, all sem_open calls with O_CREAT/O_EXCL fail (because none of them were unlinked), and the problem is never fixed

The simplest solution is to just remove all the exit(EXIT_FAILURE); calls (perhaps replacing them with debug logging); if the program otherwise ran to completion successfully, cleanup failures aren’t that important; it’s more important to ensure all the cleanup is performed than to fail-fast when some cleanup fails.

It might also make sense to register separate atexit handlers for each named semaphore, and only after sem_open succeeds for that semaphore, so opening one semaphore doesn’t register cleanup functions for all of them, nor does a failed open cause you to schedule cleanup. Doing so would reduce the number of failures expected in common failure cases by limiting cleanup to those cases where it is needed.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading