summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/zix/sem.h9
-rw-r--r--test/test_sem.c2
-rw-r--r--test/test_tree.c98
3 files changed, 99 insertions, 10 deletions
diff --git a/include/zix/sem.h b/include/zix/sem.h
index 0337f03..3549e02 100644
--- a/include/zix/sem.h
+++ b/include/zix/sem.h
@@ -198,14 +198,11 @@ zix_sem_post(ZixSem* ZIX_NONNULL sem)
static inline ZixStatus
zix_sem_wait(ZixSem* ZIX_NONNULL sem)
{
- while (sem_wait(&sem->sem)) {
- if (errno != EINTR) {
- return ZIX_STATUS_ERROR;
- }
- /* Otherwise, interrupted, so try again. */
+ while (sem_wait(&sem->sem) && errno == EINTR) {
+ // Interrupted, try again
}
- return ZIX_STATUS_SUCCESS;
+ return zix_errno_status(errno);
}
static inline bool
diff --git a/test/test_sem.c b/test/test_sem.c
index bad0a44..3cda8ea 100644
--- a/test/test_sem.c
+++ b/test/test_sem.c
@@ -21,7 +21,7 @@ reader(void* ZIX_UNUSED(arg))
printf("Reader starting\n");
for (unsigned i = 0; i < n_signals; ++i) {
- zix_sem_wait(&sem);
+ assert(!zix_sem_wait(&sem));
}
printf("Reader finished\n");
diff --git a/test/test_tree.c b/test/test_tree.c
index 7c7fcf4..683673d 100644
--- a/test/test_tree.c
+++ b/test/test_tree.c
@@ -1,12 +1,17 @@
// Copyright 2011-2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
+#undef NDEBUG
+
+#include "failing_allocator.h"
#include "test_data.h"
+#include "zix/allocator.h"
#include "zix/attributes.h"
#include "zix/common.h"
#include "zix/tree.h"
+#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
@@ -45,11 +50,56 @@ test_fail(void)
}
static int
-stress(unsigned test_num, size_t n_elems)
+test_duplicate_insert(void)
+{
+ const uintptr_t r = 0xDEADBEEF;
+ ZixTreeIter* ti = NULL;
+ ZixTree* t = zix_tree_new(NULL, false, int_cmp, NULL, NULL, NULL);
+
+ assert(!zix_tree_begin(t));
+ assert(!zix_tree_end(t));
+ assert(!zix_tree_rbegin(t));
+ assert(!zix_tree_rend(t));
+
+ ZixStatus status = zix_tree_insert(t, (void*)r, &ti);
+ if (status) {
+ fprintf(stderr, "Insert failed\n");
+ return test_fail();
+ }
+
+ if ((uintptr_t)zix_tree_get(ti) != r) {
+ fprintf(stderr,
+ "Data corrupt (%" PRIuPTR " != %" PRIuPTR ")\n",
+ (uintptr_t)zix_tree_get(ti),
+ r);
+ return test_fail();
+ }
+
+ if ((status = zix_tree_insert(t, (void*)r, &ti)) != ZIX_STATUS_EXISTS) {
+ fprintf(stderr, "Duplicate insert succeeded (%s)\n", zix_strerror(status));
+ return test_fail();
+ }
+
+ zix_tree_free(t);
+ return 0;
+}
+
+static int
+stress(ZixAllocator* allocator, unsigned test_num, size_t n_elems)
{
uintptr_t r = 0U;
ZixTreeIter* ti = NULL;
- ZixTree* t = zix_tree_new(NULL, true, int_cmp, NULL, NULL, NULL);
+ ZixTree* t = zix_tree_new(allocator, true, int_cmp, NULL, NULL, NULL);
+
+ if (!t) {
+ fprintf(stderr, "Tree allocation failed\n");
+ return test_fail();
+ }
+
+ assert(!zix_tree_begin(t));
+ assert(!zix_tree_end(t));
+ assert(!zix_tree_rbegin(t));
+ assert(!zix_tree_rend(t));
// Insert n_elems elements
for (size_t i = 0; i < n_elems; ++i) {
@@ -187,12 +237,54 @@ stress(unsigned test_num, size_t n_elems)
return EXIT_SUCCESS;
}
+static void
+test_failed_alloc(void)
+{
+ static const size_t n_insertions = 4096;
+
+ ZixFailingAllocator allocator = zix_failing_allocator();
+
+ // Successfully test insertions to count the number of allocations
+ ZixTree* t = zix_tree_new(&allocator.base, false, int_cmp, NULL, NULL, NULL);
+ for (size_t i = 0U; i < n_insertions; ++i) {
+ assert(!zix_tree_insert(t, (void*)i, NULL));
+ }
+
+ // Test that tree allocation failure is handled gracefully
+ allocator.n_remaining = 0;
+ zix_tree_free(t);
+ assert(!zix_tree_new(&allocator.base, false, int_cmp, NULL, NULL, NULL));
+
+ // Allocate a new tree to try the same test again, but with allocation failure
+ allocator.n_remaining = 1;
+ t = zix_tree_new(&allocator.base, false, int_cmp, NULL, NULL, NULL);
+ assert(t);
+
+ // Test that each insertion allocation failing is handled gracefully
+ for (size_t i = 0U; i < n_insertions; ++i) {
+ allocator.n_remaining = 0;
+
+ assert(zix_tree_insert(t, (void*)i, NULL) == ZIX_STATUS_NO_MEM);
+ }
+
+ zix_tree_free(t);
+}
+
int
main(int argc, char** argv)
{
const unsigned n_tests = 3;
unsigned n_elems = 0;
+ assert(!zix_tree_iter_next(NULL));
+ assert(!zix_tree_iter_prev(NULL));
+
+ if (test_duplicate_insert()) {
+ return 1;
+ }
+
+ test_failed_alloc();
+
if (argc == 1) {
n_elems = 100000;
} else {
@@ -214,7 +306,7 @@ main(int argc, char** argv)
for (unsigned i = 0; i < n_tests; ++i) {
printf(".");
fflush(stdout);
- if (stress(i, n_elems)) {
+ if (stress(NULL, i, n_elems)) {
fprintf(stderr, "FAIL: Random seed %u\n", seed);
return test_fail();
}