-#include <spinlock.h>
+#include <mutex.h>
#include <sem.h>
+#include <corax/errno.h>
+#include <string.h>
#include "mailbox.h"
int mailbox_init(struct mailbox *mbox)
if(mbox) {
/* zero the entire mailbox */
memset(mbox, 0, sizeof(*mbox));
-
- /* this should really always return zero */
- ret_val = sem_post(&(mbox->mb_wsem));
+ ret_val = 0;
}
return(ret_val);
if(mbox) {
/*
- * Wait until the mailbox is available. The sem_wait()
- * function always succeeds, so we don't need to bother
- * checking its return value
+ * Wait until the mailbox is available. We don't need
+ * to perform any error handling here since the
+ * mutex_lock() function will always succeed.
*/
- sem_wait(&(mbox->mb_wsem));
+ mutex_lock(&(mbox->mb_lock));
/* place the message in the mailbox */
mbox->mb_msg = msg;
/*
- * Notify receivers that a message is ready to be received.
- * Since we're only putting one message at a time into the
- * mailbox, this really shouldn't overflow. If it does, some
- * other part of the kernel must have overwritten the memory
- * of we have a use-after-free bug. Either way, the mailbox
- * isn't really safe to use anymore.
+ * Notify receivers that a message is ready to be
+ * received. Since we're only putting one message at a
+ * time into the mailbox, this really shouldn't
+ * overflow. If it does, some other part of the kernel
+ * must have overwritten the memory of we have a
+ * use-after-free bug. Either way, the mailbox isn't
+ * safe to use anymore.
*/
ret_val = sem_post(&(mbox->mb_rsem));
if(!ret_val) {
- /* wait for synchronization */
- ret_val = sem_wait(&(mbox->mb_ssem));
- } else {
- /* put the semaphore back into its original state */
- sem_post(&(mbox->mb_wsem));
+ /* rendevouz with the sender */
+ sem_wait(&(mbox->mb_ssem));
}
+
+ /*
+ * The message has been retrieved by some other task.
+ * Unlock the mutex so the next task can put a message
+ * into the mailbox. The mutex_unlock() function
+ * should absolutely not fail, unless there is a bug
+ * in the kernel.
+ */
+ ret_val = mutex_unlock(&(mbox->mb_lock));
+
+ /*
+ * We return the return value from mutex_unlock() so
+ * that the caller can determine if a kernel bug has
+ * occured (in which case it should probably attempt
+ * to exit safely.
+ */
}
+ /*
+ * Return values:
+ * 0
+ * Everything went better than expected
+ * -EINVAL
+ * mbox was NULL
+ * -EALREADY, -EPERM
+ * Kernel bug
+ */
+
return(ret_val);
}
if(mbox) {
/*
- * Wait for a message to be placed in the mailbox. This
- * function always succeeds, so we don't have to check its
- * return value.
+ * Wait for a message to be placed in the mailbox.
+ * This function always succeeds, so we don't have to
+ * check its return value.
*/
sem_wait(&(mbox->mb_rsem));
*dst = mbox->mb_msg;
/*
-
+ * Rendevouz with the sender: Let them know we have
+ * received their message.
+ */
+ ret_val = sem_post(&(mbox->mb_ssem));
}
return(ret_val);