Make mailbox clearing idempotent.
Change-Id: Ib07df13119eee7b4d916688bdb68a0760aedccaa
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 73c7e66..d263d58 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -145,7 +145,7 @@
* Clears the caller's mailbox so a new message can be received.
*
* Returns:
- * - -1 on failure, if the mailbox hasn't been read or is already empty.
+ * - -1 on failure, if the mailbox hasn't been read.
* - 0 on success if no further action is needed.
* - 1 if it was called by the primary VM and the primary VM now needs to wake
* up or kick waiters. Waiters should be retrieved by calling
diff --git a/src/api.c b/src/api.c
index 5e7a033..ba89203 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1028,7 +1028,7 @@
* overwrite the old and will arrive asynchronously.
*
* Returns:
- * - -1 on failure, if the mailbox hasn't been read or is already empty.
+ * - -1 on failure, if the mailbox hasn't been read.
* - 0 on success if no further action is needed.
* - 1 if it was called by the primary VM and the primary VM now needs to wake
* up or kick waiters. Waiters should be retrieved by calling
@@ -1041,11 +1041,19 @@
int64_t ret;
vm_lock(vm, &locked);
- if (vm->mailbox.state == mailbox_state_read) {
+ switch (vm->mailbox.state) {
+ case mailbox_state_empty:
+ ret = 0;
+ break;
+
+ case mailbox_state_received:
+ ret = -1;
+ break;
+
+ case mailbox_state_read:
ret = api_waiter_result(locked, current, next);
vm->mailbox.state = mailbox_state_empty;
- } else {
- ret = -1;
+ break;
}
vm_unlock(&locked);
diff --git a/test/vmapi/primary_with_secondaries/interrupts.c b/test/vmapi/primary_with_secondaries/interrupts.c
index c18c8c9..ad61833 100644
--- a/test/vmapi/primary_with_secondaries/interrupts.c
+++ b/test/vmapi/primary_with_secondaries/interrupts.c
@@ -181,7 +181,6 @@
hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_C);
run_res = hf_vcpu_run(SERVICE_VM0, 0);
EXPECT_EQ(run_res.code, HF_VCPU_RUN_WAIT_FOR_INTERRUPT);
- EXPECT_EQ(hf_mailbox_clear(), -1);
/*
* Now send a message to the secondary to enable the interrupt ID, and
diff --git a/test/vmapi/primary_with_secondaries/mailbox.c b/test/vmapi/primary_with_secondaries/mailbox.c
index c54cdb4..bd5b588 100644
--- a/test/vmapi/primary_with_secondaries/mailbox.c
+++ b/test/vmapi/primary_with_secondaries/mailbox.c
@@ -61,6 +61,16 @@
}
/**
+ * Clearing an empty mailbox is a noop.
+ */
+TEST(mailbox, clear_empty)
+{
+ EXPECT_EQ(hf_mailbox_clear(), 0);
+ EXPECT_EQ(hf_mailbox_clear(), 0);
+ EXPECT_EQ(hf_mailbox_clear(), 0);
+}
+
+/**
* Send and receive the same message from the echo VM.
*/
TEST(mailbox, echo)