core: make mbox_post()/__sem_down_slow() check if valid
[syslinux.git] / core / thread / mbox.c
blobd1c640a941edda406641db9e488354e546c26c28
1 /*
2 * mbox.c
4 * Simple thread mailbox interface
5 */
7 #include "thread.h"
8 #include "mbox.h"
9 #include <errno.h>
11 void mbox_init(struct mailbox *mbox, size_t size)
13 if (!!mbox) {
14 sem_init(&mbox->prod_sem, size); /* All slots empty */
15 sem_init(&mbox->cons_sem, 0); /* No slots full */
16 sem_init(&mbox->head_sem, 1); /* Head mutex */
17 sem_init(&mbox->tail_sem, 1); /* Tail mutex */
19 mbox->wrap = &mbox->data[size];
20 mbox->head = &mbox->data[0];
21 mbox->tail = &mbox->data[0];
25 int mbox_post(struct mailbox *mbox, void *msg, mstime_t timeout)
27 if (!mbox_is_valid(mbox))
28 return ENOMEM;
29 if (sem_down(&mbox->prod_sem, timeout) == (mstime_t)-1)
30 return ENOMEM;
31 sem_down(&mbox->head_sem, 0);
33 *mbox->head = msg;
34 mbox->head++;
35 if (mbox->head == mbox->wrap)
36 mbox->head = &mbox->data[0];
38 sem_up(&mbox->head_sem);
39 sem_up(&mbox->cons_sem);
40 return 0;
43 mstime_t mbox_fetch(struct mailbox *mbox, void **msg, mstime_t timeout)
45 mstime_t t;
47 if (!mbox)
48 return -1;
49 t = sem_down(&mbox->cons_sem, timeout);
50 if (t == (mstime_t)-1)
51 return -1;
52 t += sem_down(&mbox->tail_sem, 0);
54 if (msg)
55 *msg = *mbox->tail;
56 mbox->tail++;
57 if (mbox->tail == mbox->wrap)
58 mbox->tail = &mbox->data[0];
60 sem_up(&mbox->tail_sem);
61 sem_up(&mbox->prod_sem);
62 return t;