summaryrefslogtreecommitdiff
path: root/src/tests/eina/eina_test_thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/eina/eina_test_thread.c')
-rw-r--r--src/tests/eina/eina_test_thread.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/tests/eina/eina_test_thread.c b/src/tests/eina/eina_test_thread.c
new file mode 100644
index 0000000000..2b35907db7
--- /dev/null
+++ b/src/tests/eina/eina_test_thread.c
@@ -0,0 +1,124 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2020 Expertise Solutions Cons em Inf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <check.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_UNISTD
+# include <unistd.h>
+#endif
+
+#ifdef _WIN32
+# include <evil_private.h> /* mkdir */
+#endif
+
+#include <Eina.h>
+#include "eina_suite.h"
+
+static void
+thread_cleanup_fn(void *arg)
+{
+ *(int *) arg = 1;
+}
+
+static void *
+thread_fn_execute(void *arg, Eina_Thread t EINA_UNUSED)
+{
+ EINA_THREAD_CLEANUP_PUSH(thread_cleanup_fn, arg);
+ EINA_THREAD_CLEANUP_POP(1);
+ return NULL;
+}
+
+static void *
+thread_fn_skip(void *arg, Eina_Thread t EINA_UNUSED)
+{
+ EINA_THREAD_CLEANUP_PUSH(thread_cleanup_fn, arg);
+ EINA_THREAD_CLEANUP_POP(0);
+ return NULL;
+}
+
+static void *
+thread_fn_cancel(void *arg, Eina_Thread t EINA_UNUSED)
+{
+ Eina_Condition *cond = arg;
+
+ ck_assert(eina_thread_cancellable_set(EINA_TRUE, NULL));
+ ck_assert(eina_condition_signal(cond));
+
+ for (size_t i = 0; i < 100; ++i)
+ {
+ eina_thread_cancel_checkpoint();
+#ifdef _WIN32
+ Sleep(100);
+#else
+ usleep(100 * 1000);
+#endif
+ }
+
+ return NULL;
+}
+
+EFL_START_TEST(eina_thread_test_cleanup_execute)
+{
+ Eina_Thread t;
+ int flag = 0;
+ ck_assert(eina_thread_create(&t, EINA_THREAD_NORMAL, -1, thread_fn_execute, &flag));
+ eina_thread_join(t);
+ ck_assert_uint_eq(flag, 1);
+}
+EFL_END_TEST
+
+EFL_START_TEST(eina_thread_test_cleanup_skip)
+{
+ Eina_Thread t;
+ int flag = 2;
+ ck_assert(eina_thread_create(&t, EINA_THREAD_NORMAL, -1, thread_fn_skip, &flag));
+ eina_thread_join(t);
+ ck_assert_uint_eq(flag, 2);
+}
+EFL_END_TEST
+
+EFL_START_TEST(eina_thread_test_cancel)
+{
+ Eina_Thread t;
+ Eina_Lock mutex;
+ Eina_Condition cond;
+
+ ck_assert(eina_lock_new(&mutex));
+ ck_assert(eina_condition_new(&cond, &mutex));
+
+ ck_assert(eina_thread_create(&t, EINA_THREAD_NORMAL, -1, thread_fn_cancel, &cond));
+ ck_assert(eina_lock_take(&mutex));
+ ck_assert(eina_condition_wait(&cond));
+ ck_assert(eina_thread_cancel(t));
+ ck_assert_ptr_eq(eina_thread_join(t), EINA_THREAD_JOIN_CANCELED);
+
+ eina_condition_free(&cond);
+ eina_lock_free(&mutex);
+}
+EFL_END_TEST
+
+void
+eina_test_thread(TCase *tc)
+{
+ tcase_add_test(tc, eina_thread_test_cleanup_skip);
+ tcase_add_test(tc, eina_thread_test_cleanup_execute);
+ tcase_add_test(tc, eina_thread_test_cancel);
+}