0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-08 12:18:42 +00:00

Added a simple layer for semaphores

This commit is contained in:
Maria Matejka 2021-03-21 23:57:01 +01:00
parent bc353f1b50
commit 8d7fbf911a
2 changed files with 52 additions and 0 deletions

View File

@ -22,5 +22,17 @@ struct coroutine;
*/
struct coroutine *coro_run(pool *, void (*entry)(void *), void *data);
/* Semaphores are handy to sleep and wake worker threads. */
struct bsem;
/* Create a semaphore. Be sure to choose such a pool that happens to be freed
* only when the semaphore can't be waited for or posted. */
struct bsem *bsem_new(pool *);
/* Post a semaphore (wake the worker). */
void bsem_post(struct bsem *);
/* Wait for a semaphore. Never do this within a locked context. */
void bsem_wait(struct bsem *);
#endif

View File

@ -173,3 +173,43 @@ struct coroutine *coro_run(pool *p, void (*entry)(void *), void *data)
return c;
}
/* Semaphores */
struct bsem {
resource r;
sem_t sem;
};
static void bsem_free(resource *r)
{
struct bsem *b = (void *) r;
if (sem_destroy(&b->sem) < 0)
bug("sem_destroy() failed: %m");
}
static struct resclass bsem_class = {
.name = "Semaphore",
.size = sizeof(struct bsem),
.free = bsem_free,
};
struct bsem *bsem_new(pool *p) {
struct bsem *b = ralloc(p, &bsem_class);
if (sem_init(&b->sem, 0, 0) < 0)
bug("sem_init() failed: %m");
return b;
}
void bsem_post(struct bsem *b) {
if (sem_post(&b->sem) < 0)
bug("sem_post() failed: %m");
}
void bsem_wait(struct bsem *b) {
if (sem_wait(&b->sem) < 0)
if (errno == EINTR)
return bsem_wait(b);
else
bug("sem_wait() failed: %m");
}