diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2023-08-13 23:16:20 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2023-08-13 23:16:20 -0700 |
commit | cf4b27c90534fe2c7842f96c1553eaace1e81190 (patch) | |
tree | 3d7d2f7481f88cae32c6c854646f5e89d6d039a1 /src | |
parent | a41d4e72dc915a8cb79aa8f1f2177def06d75844 (diff) |
til_fb: introduce til_fb_halt()
This makes it so til_fb_page_get() will return NULL when the fb
has been "halted". If til_fb_page_get() is already waiting for a
page to become available, it will be woken up by til_fb_halt().
Preparatory commit for eliminating the reliance on
pthread_cancel() to terminate rototiller_thread() on shutdown.
Cancellation is always a PITA, especially cross-platform, but in
general it's so easy to have subtle bugs when using it.
Diffstat (limited to 'src')
-rw-r--r-- | src/til_fb.c | 26 | ||||
-rw-r--r-- | src/til_fb.h | 1 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/til_fb.c b/src/til_fb.c index 10a5931..1bdb2e7 100644 --- a/src/til_fb.c +++ b/src/til_fb.c @@ -143,6 +143,7 @@ typedef struct til_fb_t { _til_fb_page_t *all_pages_tail; unsigned put_pages_count; + unsigned halted:1; } til_fb_t; #ifndef container_of @@ -391,8 +392,14 @@ static inline _til_fb_page_t * _til_fb_page_get(til_fb_t *fb) * pages faster than vhz. */ pthread_mutex_lock(&fb->inactive_mutex); - while (!(page = fb->inactive_pages_tail)) + while (!(page = fb->inactive_pages_tail) && !fb->halted) pthread_cond_wait(&fb->inactive_cond, &fb->inactive_mutex); + + if (!page) { + pthread_mutex_unlock(&fb->inactive_mutex); + return NULL; + } + fb->inactive_pages_tail = page->previous; if (fb->inactive_pages_tail) fb->inactive_pages_tail->next = NULL; @@ -410,7 +417,13 @@ static inline _til_fb_page_t * _til_fb_page_get(til_fb_t *fb) /* public interface */ til_fb_fragment_t * til_fb_page_get(til_fb_t *fb) { - return &(_til_fb_page_get(fb)->fragment.public); + _til_fb_page_t *page; + + page = _til_fb_page_get(fb); + if (!page) + return NULL; + + return &page->fragment.public; } @@ -602,6 +615,15 @@ void til_fb_rebuild(til_fb_t *fb) } +void til_fb_halt(til_fb_t *fb) +{ + assert(fb); + + fb->halted = 1; + pthread_cond_signal(&fb->inactive_cond); +} + + /* accessor for getting the ops_context */ void * til_fb_context(til_fb_t *fb) { diff --git a/src/til_fb.h b/src/til_fb.h index 1f100dd..5ad210f 100644 --- a/src/til_fb.h +++ b/src/til_fb.h @@ -55,6 +55,7 @@ til_fb_t * til_fb_free(til_fb_t *fb); void til_fb_get_put_pages_count(til_fb_t *fb, unsigned *count); int til_fb_new(const til_fb_ops_t *ops, const char *title, const til_setup_t *setup, int n_pages, til_fb_t **res_fb); void til_fb_rebuild(til_fb_t *fb); +void til_fb_halt(til_fb_t *fb); void * til_fb_context(til_fb_t *fb); int til_fb_flip(til_fb_t *fb); void til_fb_fragment_divide(til_fb_fragment_t *fragment, unsigned n_fragments, til_fb_fragment_t fragments[]); |