mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2024-11-24 15:55:02 +00:00
154 lines
3.8 KiB
C
154 lines
3.8 KiB
C
#include "sentry_core.h"
|
||
#include "sentry_sync.h"
|
||
#include "sentry_testsupport.h"
|
||
|
||
#ifdef SENTRY_PLATFORM_WINDOWS
|
||
# include <windows.h>
|
||
# define sleep_s(SECONDS) Sleep((SECONDS)*1000)
|
||
#else
|
||
# include <unistd.h>
|
||
# define sleep_s(SECONDS) sleep(SECONDS)
|
||
#endif
|
||
|
||
struct task_state {
|
||
int executed;
|
||
bool running;
|
||
};
|
||
|
||
static void
|
||
task_func(void *data, void *UNUSED(state))
|
||
{
|
||
struct task_state *state = data;
|
||
state->executed++;
|
||
}
|
||
|
||
static void
|
||
cleanup_func(void *data)
|
||
{
|
||
struct task_state *state = data;
|
||
state->running = false;
|
||
}
|
||
|
||
SENTRY_TEST(background_worker)
|
||
{
|
||
for (size_t i = 0; i < 100; i++) {
|
||
sentry_bgworker_t *bgw = sentry__bgworker_new(NULL, NULL);
|
||
TEST_CHECK(!!bgw);
|
||
|
||
sentry__bgworker_start(bgw);
|
||
|
||
struct task_state ts;
|
||
ts.executed = 0;
|
||
ts.running = true;
|
||
for (size_t j = 0; j < 10; j++) {
|
||
sentry__bgworker_submit(bgw, task_func, cleanup_func, &ts);
|
||
}
|
||
|
||
TEST_CHECK_INT_EQUAL(sentry__bgworker_shutdown(bgw, 5000), 0);
|
||
sentry__bgworker_decref(bgw);
|
||
|
||
TEST_CHECK_INT_EQUAL(ts.executed, 10);
|
||
TEST_CHECK(!ts.running);
|
||
}
|
||
}
|
||
|
||
static void
|
||
sleep_task(void *UNUSED(data), void *UNUSED(state))
|
||
{
|
||
sleep_s(1);
|
||
}
|
||
|
||
static void
|
||
trailing_task(void *data, void *UNUSED(state))
|
||
{
|
||
bool *executed = (bool *)data;
|
||
*executed = true;
|
||
}
|
||
|
||
static bool
|
||
drop_lessthan(void *task, void *data)
|
||
{
|
||
return (size_t)task < (size_t)data;
|
||
}
|
||
|
||
static bool
|
||
drop_greaterthan(void *task, void *data)
|
||
{
|
||
return (size_t)task > (size_t)data;
|
||
}
|
||
|
||
static bool
|
||
collect(void *task, void *data)
|
||
{
|
||
sentry_value_t *list = (sentry_value_t *)data;
|
||
sentry_value_append(*list, sentry_value_new_int32((int32_t)(size_t)task));
|
||
return true;
|
||
}
|
||
|
||
SENTRY_TEST(task_queue)
|
||
{
|
||
sentry_bgworker_t *bgw = sentry__bgworker_new(NULL, NULL);
|
||
sentry__bgworker_submit(bgw, sleep_task, NULL, NULL);
|
||
sentry__bgworker_decref(bgw);
|
||
|
||
bgw = sentry__bgworker_new(NULL, NULL);
|
||
|
||
// submit before starting
|
||
for (size_t i = 0; i < 20; i++) {
|
||
sentry__bgworker_submit(bgw, sleep_task, NULL, (void *)(i % 10));
|
||
}
|
||
|
||
sentry__bgworker_start(bgw);
|
||
|
||
size_t dropped = 0;
|
||
dropped = sentry__bgworker_foreach_matching(
|
||
bgw, sleep_task, drop_lessthan, (void *)4);
|
||
TEST_CHECK_INT_EQUAL(dropped, 8);
|
||
dropped = sentry__bgworker_foreach_matching(
|
||
bgw, sleep_task, drop_greaterthan, (void *)6);
|
||
TEST_CHECK_INT_EQUAL(dropped, 6);
|
||
|
||
int shutdown = sentry__bgworker_shutdown(bgw, 500);
|
||
TEST_CHECK_INT_EQUAL(shutdown, 1);
|
||
|
||
// submit another task to the worker which is still in shutdown
|
||
bool executed_after_shutdown = false;
|
||
sentry__bgworker_submit(bgw, trailing_task, NULL, &executed_after_shutdown);
|
||
|
||
sentry_value_t list = sentry_value_new_list();
|
||
dropped
|
||
= sentry__bgworker_foreach_matching(bgw, sleep_task, collect, &list);
|
||
TEST_CHECK_INT_EQUAL(dropped, 6);
|
||
TEST_CHECK_JSON_VALUE(list, "[4,5,6,4,5,6]");
|
||
sentry_value_decref(list);
|
||
|
||
sentry__bgworker_decref(bgw);
|
||
// the worker is still "executing" one task, so lets sleep here as well so
|
||
// we don’t leak
|
||
sleep_s(1);
|
||
|
||
// the worker will still execute tasks as long as there are some, even if it
|
||
// was instructed to shut down
|
||
TEST_CHECK(executed_after_shutdown);
|
||
}
|
||
|
||
SENTRY_TEST(bgworker_flush)
|
||
{
|
||
sentry_bgworker_t *bgw = sentry__bgworker_new(NULL, NULL);
|
||
sentry__bgworker_submit(bgw, sleep_task, NULL, NULL);
|
||
|
||
sentry__bgworker_start(bgw);
|
||
|
||
// first flush times out
|
||
int flush = sentry__bgworker_flush(bgw, 500);
|
||
TEST_CHECK_INT_EQUAL(flush, 1);
|
||
|
||
// second flush succeeds
|
||
flush = sentry__bgworker_flush(bgw, 1000);
|
||
TEST_CHECK_INT_EQUAL(flush, 0);
|
||
|
||
int shutdown = sentry__bgworker_shutdown(bgw, 500);
|
||
TEST_CHECK_INT_EQUAL(shutdown, 0);
|
||
sentry__bgworker_decref(bgw);
|
||
}
|