don't deadlock in demo when cancelled

pull/385/head v1.2.2
nick black 5 years ago
parent e72111ac8b
commit 91f59b763d
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -5,7 +5,6 @@
#include <assert.h>
#include <unistd.h>
#include <limits.h>
#include <pthread.h>
#include <stdatomic.h>
#include <version.h>
#include <notcurses/notcurses.h>
@ -148,7 +147,8 @@ int demo_render(struct notcurses* nc);
#define DEMO_RENDER(nc) { int demo_render_err = demo_render(nc); if(demo_render_err){ return demo_render_err; }}
// locked by callers to notcurses_render() and notcurses_refresh(), all internal
extern pthread_mutex_t demo_render_lock;
void lock_demo_render(void);
void unlock_demo_render(void);
// if you won't be doing things, and it's a long sleep, consider using
// demo_nanosleep(). it updates the HUD, which looks better to the user.

@ -1,11 +1,12 @@
#include "demo.h"
#include <pthread.h>
// we provide a heads-up display throughout the demo, detailing the demos we're
// about to run, running, and just runned. the user can move this HUD with
// their mouse. it should always be on the top of the z-stack.
struct ncplane* hud = NULL;
pthread_mutex_t demo_render_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t demo_render_lock = PTHREAD_MUTEX_INITIALIZER;
// while the HUD is grabbed by the mouse, these are set to the position where
// the grab started. they are reset once the HUD is released.
@ -340,6 +341,10 @@ int hud_completion_notify(const demoresult* result){
return 0;
}
static void unlock_mutex(void* vm){
pthread_mutex_unlock(vm);
}
// inform the HUD of an upcoming demo
int hud_schedule(const char* demoname){
elem* cure;
@ -440,9 +445,20 @@ int demo_render(struct notcurses* nc){
return -1;
}
}
int ret = 0;
pthread_cleanup_push(unlock_mutex, &demo_render_lock);
// lock against a possible notcurses_refresh() on Ctrl+L
pthread_mutex_lock(&demo_render_lock);
int ret = notcurses_render(nc);
ret = notcurses_render(nc);
pthread_mutex_unlock(&demo_render_lock);
pthread_cleanup_pop(1);
return ret;
}
void lock_demo_render(void){
pthread_mutex_lock(&demo_render_lock);
}
void unlock_demo_render(void){
pthread_mutex_unlock(&demo_render_lock);
}

@ -97,9 +97,9 @@ ultramegaok_demo(void* vnc){
}
}
if(id == 'L' && ni.ctrl){
pthread_mutex_lock(&demo_render_lock);
lock_demo_render();
notcurses_refresh(nc);
pthread_mutex_unlock(&demo_render_lock);
unlock_demo_render();
continue;
}
// if this was about the menu or HUD, pass to them, and continue

Loading…
Cancel
Save