Signed-off-by: rean <[email protected]>
---
core/semaphore.cc | 8 +++++++-
modules/tests/Makefile | 2 +-
tests/tst-sem-timed-wait.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 2 deletions(-)
create mode 100644 tests/tst-sem-timed-wait.cc
diff --git a/core/semaphore.cc b/core/semaphore.cc
index 73732b8..31fda35 100644
--- a/core/semaphore.cc
+++ b/core/semaphore.cc
@@ -48,7 +48,13 @@ bool semaphore::wait(unsigned units, sched::timer* tmr)
// if wr.owner, it's a timeout - post() didn't wake us and didn't decrease
// the semaphore's value for us. Note we are holding the mutex, so there
- // can be no race with post().
+ // can be no race with post(). To clean up we should remove the
+ // wait record (local variable) that we just pushed onto _waiters
+ // (via push_back)
+ if (wr.owner) {
+ _waiters.erase(_waiters.iterator_to(wr));
+ }
+
return !wr.owner;
}
diff --git a/modules/tests/Makefile b/modules/tests/Makefile
index fb8d001..6e3aea7 100644
--- a/modules/tests/Makefile
+++ b/modules/tests/Makefile
@@ -84,7 +84,7 @@ tests := tst-pthread.so misc-ramdisk.so tst-vblk.so
tst-bsd-evh.so \
tst-namespace.so tst-without-namespace.so payload-env.so \
payload-merge-env.so misc-execve.so misc-execve-payload.so
misc-mutex2.so \
tst-pthread-setcancelstate.so tst-syscall.so tst-pin.so tst-run.so \
- tst-ifaddrs.so tst-pthread-affinity-inherit.so
+ tst-ifaddrs.so tst-pthread-affinity-inherit.so tst-sem-timed-wait.so
# libstatic-thread-variable.so tst-static-thread-variable.so \
diff --git a/tests/tst-sem-timed-wait.cc b/tests/tst-sem-timed-wait.cc
new file mode 100644
index 0000000..f59d294
--- /dev/null
+++ b/tests/tst-sem-timed-wait.cc
@@ -0,0 +1,45 @@
+#include <osv/semaphore.hh>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+
+unsigned int tests_total = 0, tests_failed = 0;
+
+void report(const char* name, bool passed)
+{
+ static const char* status[] = {"FAIL", "PASS"};
+ printf("%s: %s\n", status[passed], name);
+ tests_total += 1;
+ tests_failed += !passed;
+}
+
+int main(void)
+{
+ printf("Starting sem_timed_wait test\n");
+
+ // Basic flow for test
+ // 1) Create a semaphore (initialized to 0)
+ // 2) Do a timed-wait on it
+ // 3) We're never signaled/woken so our stack-allocated wait_record remains
+ // on the semaphore's waiters list
+ //
+ // In the failure case the end result is a stacktrace that looks like:
+ // Assertion failed: !hook.is_linked()
+ //(/usr/include/boost/intrusive/detail/generic_hook.hpp: destructor_impl:
47)
+
+ //[backtrace]
+ //0x0000000000225a48 <__assert_fail+24>
+ //0x00000000003c40e9 <???+3948777>
+ //0x00000000003c4242 <semaphore::wait(unsigned int, sched::timer*)+98>
+ //0x0000100000c01057 <???+12587095>
+
+ semaphore sem(0);
+ sched::timer tmr(*sched::thread::current());
+ osv::clock::wall::duration time((std::chrono::seconds(0)));
+ tmr.set(time);
+ bool ret_val = sem.wait(1, &tmr);
+ report("sem_timedwait\0", ret_val == false);
+ printf("SUMMARY: %u tests / %u failures\n", tests_total, tests_failed);
+ return tests_failed == 0 ? 0 : 1;
+}
--
2.7.4
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.