support: loop_enter/leave hardening

This commit adds a counter for loop_enter/leave and checks:

 - consecutive enter are used on the same thread
 - leave is used on the same thread as enter
 - at destruction, the enter_count must be 0
This commit is contained in:
Alexandre BIQUE 2022-02-08 10:58:36 +01:00 committed by Wim Taymans
parent 834ecd733d
commit 0b637c3291

View file

@ -79,6 +79,7 @@ struct impl {
int poll_fd; int poll_fd;
pthread_t thread; pthread_t thread;
int enter_count;
struct spa_poll_event dispatching[MAX_EP]; struct spa_poll_event dispatching[MAX_EP];
uint32_t n_dispatching; uint32_t n_dispatching;
@ -297,14 +298,31 @@ loop_add_hook(void *object,
static void loop_enter(void *object) static void loop_enter(void *object)
{ {
struct impl *impl = object; struct impl *impl = object;
impl->thread = pthread_self(); pthread_t thread_id = pthread_self();
if (impl->enter_count == 0) {
spa_return_if_fail(impl->thread == 0);
impl->thread = thread_id;
impl->enter_count = 1;
} else {
spa_return_if_fail(impl->enter_count > 0);
spa_return_if_fail(impl->thread == thread_id);
impl->enter_count++;
}
spa_log_trace(impl->log, "%p: enter %lu", impl, impl->thread); spa_log_trace(impl->log, "%p: enter %lu", impl, impl->thread);
} }
static void loop_leave(void *object) static void loop_leave(void *object)
{ {
struct impl *impl = object; struct impl *impl = object;
pthread_t thread_id = pthread_self();
spa_return_if_fail(impl->enter_count > 0);
spa_return_if_fail(impl->thread == thread_id);
spa_log_trace(impl->log, "%p: leave %lu", impl, impl->thread); spa_log_trace(impl->log, "%p: leave %lu", impl, impl->thread);
if (--impl->enter_count == 0)
impl->thread = 0; impl->thread = 0;
} }
@ -755,6 +773,10 @@ static int impl_clear(struct spa_handle *handle)
impl = (struct impl *) handle; impl = (struct impl *) handle;
if (impl->enter_count != 0)
spa_log_warn(impl->log, "%p: loop is entered %d times",
impl, impl->enter_count);
spa_list_consume(source, &impl->source_list, link) spa_list_consume(source, &impl->source_list, link)
loop_destroy_source(impl, &source->source); loop_destroy_source(impl, &source->source);