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:
parent
bc353f1b50
commit
8d7fbf911a
12
lib/coro.h
12
lib/coro.h
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user