Skip to content

Instantly share code, notes, and snippets.

@rianhunter
Created September 1, 2019 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rianhunter/a0bd4c9e8ab550ecadbe2464995726a8 to your computer and use it in GitHub Desktop.
Save rianhunter/a0bd4c9e8ab550ecadbe2464995726a8 to your computer and use it in GitHub Desktop.
Shows proper usage of sem_init()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semaphore.h>
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
int test_semaphore(sem_t *sem) {
pid_t pid;
pid = fork();
if (pid < 0) {
fprintf(stderr, "failed to fork: %s\n", strerror(errno));
return -1;
}
if (pid > 0) {
int status;
/* after posting, child should exit successfully */
sem_post(sem);
printf("Waiting for child to react to sem_post()...\n");
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) > 1) {
return -1;
}
return !WEXITSTATUS(status);
} else {
int ret;
struct timespec to;
ret = clock_gettime(CLOCK_REALTIME, &to);
if (ret < 0) {
fprintf(stderr, "failed to clock_gettime(): %s\n", strerror(errno));
return 255;
}
/* wait for sem_post() for 5 seconds */
to.tv_sec += 5;
ret = sem_timedwait(sem, &to);
if (ret < 0 && errno != ETIMEDOUT) {
fprintf(stderr, "failed to timedwait: %s\n", strerror(errno));
return 255;
}
exit(!ret ? EXIT_SUCCESS : EXIT_FAILURE);
}
/* notreached */
}
int main() {
int ret;
sem_t stack_allocated, *mmap_shared;
sem_init(&stack_allocated, 1, 0);
ret = test_semaphore(&stack_allocated);
if (ret < 0) {
return EXIT_FAILURE;
}
if (!ret) {
printf("Stack-allocated semaphore across fork() is broken\n");
} else {
printf("Stack-allocated semaphore across fork() works\n");
}
printf("\n");
mmap_shared = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (mmap_shared == MAP_FAILED) {
return EXIT_FAILURE;
}
sem_init(mmap_shared, 1, 0);
ret = test_semaphore(mmap_shared);
if (ret < 0) {
return EXIT_FAILURE;
}
if (!ret) {
printf("Mapped semaphore across fork() is broken\n");
} else {
printf("Mapped semaphore across fork() works\n");
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment