AndreasKaram
AndreasKaram

Reputation: 29

Semaphore closing failed: Bad file descriptor using POSIX semaphores on MAC OS

this is my main file:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>  // Χρειάζεται για τη συνάρτηση sleep
#include "ipc_utils.h"

#define MAX_PASSENGERS 100

void *passenger(void *arg);  // Δήλωση της συνάρτησης passenger

sem_t *boat_semaphore;  // Διαθέσιμες θέσεις στη λέμβο
sem_t *boat_queue;      // Ουρά επιβατών
sem_t *boat_ready;      // Έλεγχος πλήρους λέμβου

int num_passengers, num_boats, boat_capacity;

void *boat(void *arg) {
    int *boat_id = (int *)arg;

    while (1) {
        printf("Boat %d is ready to board passengers.\n", *boat_id);

        // Αναμονή μέχρι να γεμίσει η λέμβος
        for (int i = 0; i < boat_capacity; i++) {
            sem_wait(&boat_ready);
        }

        printf("Boat %d is departing.\n", *boat_id);

        // Προσομοίωση αναχώρησης και επιστροφής
        sleep(2);
        printf("Boat %d has returned.\n", *boat_id);

        // Επαναφορά θέσεων στη λέμβο
        for (int i = 0; i < boat_capacity; i++) {
            sem_post(&boat_semaphore);
        }
    }
    free(boat_id);
    return NULL;
}

int main() {
    //int num_passengers, num_boats, boat_capacity;

    printf("Enter the number of passengers: ");
    scanf("%d", &num_passengers);
    printf("Enter the number of boats: ");
    scanf("%d", &num_boats);
    printf("Enter the capacity of each boat: ");
    scanf("%d", &boat_capacity);

    if (num_passengers > MAX_PASSENGERS) {
        printf("Error: Maximum number of passengers is %d.\n", MAX_PASSENGERS);
        return EXIT_FAILURE;
    }

    pthread_t passenger_threads[num_passengers];
    pthread_t boat_threads[num_boats];

    // Αρχικοποίηση σημαφόρων
    init_semaphore(&boat_semaphore, boat_capacity);
    init_semaphore(&boat_queue, num_passengers);
    init_semaphore(&boat_ready, 0);

    // Δημιουργία νημάτων για λέμβους
    for (int i = 0; i < num_boats; i++) {
        int *boat_id = malloc(sizeof(int));
        *boat_id = i + 1;
        pthread_create(&boat_threads[i], NULL, boat, boat_id);
    }

    // Δημιουργία νημάτων για επιβάτες
    for (int i = 0; i < num_passengers; i++) {
        int *passenger_id = malloc(sizeof(int));
        *passenger_id = i + 1;
        pthread_create(&passenger_threads[i], NULL, passenger, passenger_id);
    }

    // Συγχώνευση νημάτων επιβατών
    for (int i = 0; i < num_passengers; i++) {
        pthread_join(passenger_threads[i], NULL);
    }

    // Καταστροφή σημαφόρων
    destroy_semaphore(&boat_semaphore);
    destroy_semaphore(&boat_queue);
    destroy_semaphore(&boat_ready);

    return 0;
}

and this is the file for opening and closing the semaphores:

#include "ipc_utils.h"
#include <fcntl.h>    // For O_CREAT
#include <sys/stat.h> // For mode_t

// Initialize the semaphore using sem_open
void init_semaphore(sem_t **sem, int value) {
    *sem = sem_open("/my_semaphore", O_CREAT, 0666, value);
    if (*sem == SEM_FAILED) {
        perror("Semaphore initialization failed");
        exit(EXIT_FAILURE);
    } else {
        printf("Semaphore successfully created with value %d.\n", value);
    }
}

// Close and unlink the semaphore (proper cleanup)
void destroy_semaphore(sem_t *sem) {
    if (sem == SEM_FAILED) {
        perror("Invalid semaphore, cannot close");
        exit(EXIT_FAILURE);
    }

    // Close the semaphore
    if (sem_close(sem) != 0) {
        perror("Semaphore closing failed");
        exit(EXIT_FAILURE);
    } else {
        printf("Semaphore closed successfully.\n");
    }

    // Unlink the semaphore
    if (sem_unlink("/my_semaphore") != 0) {
        perror("Semaphore unlinking failed");
        exit(EXIT_FAILURE);
    } else {
        printf("Semaphore unlinked successfully.\n");
    }
}

// Error handling function
void handle_error(const char *msg) {
    perror(msg);
    exit(EXIT_FAILURE);
}

I keep getting this error: Semaphore closing failed: Bad file descriptor

As far as i know the semaphores are opened correctly.What can be the cause? Have i entered the values on opening semaphores correctly? I have previously tried with semaphores init and destroy but apparently this command is not working on macos

Upvotes: 2

Views: 43

Answers (1)

ikegami
ikegami

Reputation: 386541

Always enable your compiler's warnings and heed them! With gcc, I use -Wall -Wextra -pedantic. It would have caught the error.

destroy_semaphore(&boat_semaphore);
destroy_semaphore(&boat_queue);
destroy_semaphore(&boat_ready);

should be

destroy_semaphore(boat_semaphore);
destroy_semaphore(boat_queue);
destroy_semaphore(boat_ready);

Upvotes: 1

Related Questions