mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-12-21 14:30:02 +00:00
Fix shutdown codepaths
- Ensures various shutdown codepaths (interface, cpu/audio, main/video, ...) run on proper thread(s) - Actually now runs the CloseAL() code - Try to ensure all detached threads exit ... seems to help keep Valgrind happy =)
This commit is contained in:
parent
a796a9f14c
commit
80b880550f
@ -1270,7 +1270,6 @@ void c_interface_parameters()
|
||||
if (ch == 'Y')
|
||||
{
|
||||
save_settings();
|
||||
|
||||
c_eject_6( 0 );
|
||||
c_interface_print_screen( screen );
|
||||
c_eject_6( 1 );
|
||||
@ -1278,13 +1277,9 @@ void c_interface_parameters()
|
||||
#ifdef __linux__
|
||||
LOG("Back to Linux, w00t!\n");
|
||||
#endif
|
||||
#ifdef AUDIO_ENABLED
|
||||
speaker_destroy();
|
||||
MB_Destroy();
|
||||
#endif
|
||||
|
||||
video_shutdown();
|
||||
exit( 0 );
|
||||
c_interface_exit(ch);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
13
src/keys.c
13
src/keys.c
@ -444,13 +444,14 @@ int c_mygetch(int block)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (block)
|
||||
if (emulator_shutting_down) {
|
||||
next_key = kESC;
|
||||
}
|
||||
|
||||
while (next_key == -1 && block)
|
||||
{
|
||||
while (next_key == -1)
|
||||
{
|
||||
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
||||
nanosleep(&ts, NULL); // 30Hz framerate
|
||||
}
|
||||
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
||||
nanosleep(&ts, NULL); // 30Hz framerate
|
||||
}
|
||||
|
||||
retval = next_key;
|
||||
|
50
src/misc.c
50
src/misc.c
@ -22,6 +22,7 @@
|
||||
|
||||
extern uint8_t apple_iie_rom[32768];
|
||||
|
||||
bool emulator_shutting_down = false;
|
||||
bool do_logging = true; // also controlled by NDEBUG
|
||||
FILE *error_log = NULL;
|
||||
|
||||
@ -604,6 +605,44 @@ void c_initialize_firsttime(void) {
|
||||
#if !TESTING && !defined(__APPLE__) && !defined(ANDROID)
|
||||
extern void *cpu_thread(void *dummyptr);
|
||||
|
||||
static void _shutdown_threads(void) {
|
||||
LOG("Emulator waiting for other threads to clean up...");
|
||||
#if !__linux__
|
||||
#warning FIXME TODO ideally we have a more deterministic thread waiting routine ...
|
||||
sleep(2); // =P
|
||||
#else
|
||||
do {
|
||||
DIR *dir = opendir("/proc/self/task");
|
||||
if (!dir) {
|
||||
ERRLOG("Cannot open /proc/self/task !");
|
||||
break;
|
||||
}
|
||||
|
||||
int thread_count = 0;
|
||||
struct dirent *d = NULL;
|
||||
while ((d = readdir(dir)) != NULL) {
|
||||
if (strncmp(".", d->d_name, 2) == 0) {
|
||||
// ignore
|
||||
} else if (strncmp("..", d->d_name, 3) == 0) {
|
||||
// ignore
|
||||
} else {
|
||||
++thread_count;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
assert(thread_count >= 1 && "there must at least be one thread =P");
|
||||
if (thread_count == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
||||
nanosleep(&ts, NULL); // 30Hz framerate
|
||||
} while (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int _argc, char **_argv) {
|
||||
argc = _argc;
|
||||
argv = _argv;
|
||||
@ -618,6 +657,17 @@ int main(int _argc, char **_argv) {
|
||||
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
||||
|
||||
video_main_loop();
|
||||
|
||||
assert(emulator_shutting_down && "emulator is properly shutting down");
|
||||
|
||||
LOG("Emulator waiting for CPU thread clean up...");
|
||||
if (pthread_join(cpu_thread_id, NULL)) {
|
||||
ERRLOG("OOPS: pthread_join of CPU thread ...");
|
||||
}
|
||||
|
||||
_shutdown_threads();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -98,6 +98,8 @@ extern uint32_t softswitches;
|
||||
misc.c functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
extern bool emulator_shutting_down;
|
||||
|
||||
void c_initialize_firsttime();
|
||||
void c_initialize_sound_hooks();
|
||||
void c_disable_sound_hooks();
|
||||
|
20
src/timing.c
20
src/timing.c
@ -390,11 +390,29 @@ void *cpu_thread(void *dummyptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!emul_reinitialize);
|
||||
|
||||
if (UNLIKELY(emul_reinitialize)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (UNLIKELY(emulator_shutting_down)) {
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (UNLIKELY(emulator_shutting_down)) {
|
||||
break;
|
||||
}
|
||||
|
||||
reinitialize();
|
||||
} while (1);
|
||||
|
||||
#ifdef AUDIO_ENABLED
|
||||
speaker_destroy();
|
||||
MB_Destroy();
|
||||
DSUninit();
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -619,11 +619,9 @@ static void gldriver_init_common(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void gldriver_shutdown(void) {
|
||||
#if USE_GLUT
|
||||
glutDestroyWindow(glutWindow);
|
||||
#endif
|
||||
static void _gldriver_shutdown(void) {
|
||||
// Cleanup all OpenGL objects
|
||||
emulator_shutting_down = true;
|
||||
glDeleteTextures(1, &a2TextureName);
|
||||
a2TextureName = UNINITIALIZED_GL;
|
||||
_destroy_VAO(crtVAOName);
|
||||
@ -632,6 +630,15 @@ static void gldriver_shutdown(void) {
|
||||
glDeleteProgram(program);
|
||||
program = UNINITIALIZED_GL;
|
||||
glnode_shutdownNodes();
|
||||
LOG("Completed GLDriver shutdown ...");
|
||||
}
|
||||
|
||||
static void gldriver_shutdown(void) {
|
||||
#if USE_GLUT
|
||||
glutLeaveMainLoop();
|
||||
#else
|
||||
_gldriver_shutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -876,7 +883,10 @@ static void gldriver_init(void *fbo) {
|
||||
|
||||
static void gldriver_main_loop(void) {
|
||||
#if USE_GLUT
|
||||
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
||||
glutMainLoop();
|
||||
LOG("GLUT main loop finished...");
|
||||
_gldriver_shutdown();
|
||||
#endif
|
||||
// fall through if not GLUT
|
||||
}
|
||||
|
14
valgrind.suppress
Normal file
14
valgrind.suppress
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
IGNORE glutCreateWindow allocation
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
obj:/usr/lib/x86_64-linux-gnu/dri/i965_dri.so
|
||||
obj:/usr/lib/x86_64-linux-gnu/libGL.so.1.2.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libGL.so.1.2.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libGL.so.1.2.0
|
||||
fun:glXMakeContextCurrent
|
||||
fun:fgOpenWindow
|
||||
fun:fgCreateWindow
|
||||
fun:glutCreateWindow
|
||||
}
|
Loading…
Reference in New Issue
Block a user