[input] push and pop mutex cleanup around cancellation points #2837

This commit is contained in:
nick black 2025-01-23 19:15:05 -05:00
parent c11efe877f
commit 50f18543e4
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
2 changed files with 19 additions and 2 deletions

View File

@ -3,6 +3,10 @@ rearrangements of Notcurses.
* 3.0.14 (not yet released)
* `ncplane_family_destroy()` has been added to the API.
* Added some `foot` capabilities. Recognize `ghostty` and bless its
quadrants/sextants implementations.
* A bug introduced sometime in 2022 that caused unpredictable
hangs on exit was resolved (#2837), yay!
* 3.0.13 (2025-01-11)
* Fix regression when building with `USE_CXX=off`.

View File

@ -2668,6 +2668,11 @@ int inputready_fd(const inputctx* ictx){
#endif
}
static void
cleanup_mutex(void* v){
pthread_mutex_unlock(v);
}
static inline uint32_t
internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
uint32_t id;
@ -2690,10 +2695,16 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
}
return NCKEY_EOF;
}
int r;
pthread_cleanup_push(cleanup_mutex, &ictx->ilock);
if(ts == NULL){
pthread_cond_wait(&ictx->icond, &ictx->ilock);
r = pthread_cond_wait(&ictx->icond, &ictx->ilock);
}else{
int r = pthread_cond_timedwait(&ictx->icond, &ictx->ilock, ts);
r = pthread_cond_timedwait(&ictx->icond, &ictx->ilock, ts);
}
pthread_cleanup_pop(0);
if(r){
pthread_mutex_unlock(&ictx->ilock);
if(r == ETIMEDOUT){
pthread_mutex_unlock(&ictx->ilock);
if(ni){
@ -2728,9 +2739,11 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
logtrace("draining event readiness pipe %d", ictx->ivalid);
#ifndef __MINGW32__
char c;
pthread_cleanup_push(cleanup_mutex, &ictx->ilock);
while(read(ictx->readypipes[0], &c, sizeof(c)) == 1){
// FIXME accelerate?
}
pthread_cleanup_pop(0);
#else
// we ought be draining this, but it breaks everything, as we can't easily
// do nonblocking input from a pipe in windows, augh...