mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-12-22 05:29:52 +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')
|
if (ch == 'Y')
|
||||||
{
|
{
|
||||||
save_settings();
|
save_settings();
|
||||||
|
|
||||||
c_eject_6( 0 );
|
c_eject_6( 0 );
|
||||||
c_interface_print_screen( screen );
|
c_interface_print_screen( screen );
|
||||||
c_eject_6( 1 );
|
c_eject_6( 1 );
|
||||||
@ -1278,13 +1277,9 @@ void c_interface_parameters()
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
LOG("Back to Linux, w00t!\n");
|
LOG("Back to Linux, w00t!\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef AUDIO_ENABLED
|
|
||||||
speaker_destroy();
|
|
||||||
MB_Destroy();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
video_shutdown();
|
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;
|
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;
|
retval = next_key;
|
||||||
|
50
src/misc.c
50
src/misc.c
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
extern uint8_t apple_iie_rom[32768];
|
extern uint8_t apple_iie_rom[32768];
|
||||||
|
|
||||||
|
bool emulator_shutting_down = false;
|
||||||
bool do_logging = true; // also controlled by NDEBUG
|
bool do_logging = true; // also controlled by NDEBUG
|
||||||
FILE *error_log = NULL;
|
FILE *error_log = NULL;
|
||||||
|
|
||||||
@ -604,6 +605,44 @@ void c_initialize_firsttime(void) {
|
|||||||
#if !TESTING && !defined(__APPLE__) && !defined(ANDROID)
|
#if !TESTING && !defined(__APPLE__) && !defined(ANDROID)
|
||||||
extern void *cpu_thread(void *dummyptr);
|
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) {
|
int main(int _argc, char **_argv) {
|
||||||
argc = _argc;
|
argc = _argc;
|
||||||
argv = _argv;
|
argv = _argv;
|
||||||
@ -618,6 +657,17 @@ int main(int _argc, char **_argv) {
|
|||||||
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
||||||
|
|
||||||
video_main_loop();
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ extern uint32_t softswitches;
|
|||||||
misc.c functions
|
misc.c functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
extern bool emulator_shutting_down;
|
||||||
|
|
||||||
void c_initialize_firsttime();
|
void c_initialize_firsttime();
|
||||||
void c_initialize_sound_hooks();
|
void c_initialize_sound_hooks();
|
||||||
void c_disable_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();
|
reinitialize();
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
|
#ifdef AUDIO_ENABLED
|
||||||
|
speaker_destroy();
|
||||||
|
MB_Destroy();
|
||||||
|
DSUninit();
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,11 +619,9 @@ static void gldriver_init_common(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gldriver_shutdown(void) {
|
static void _gldriver_shutdown(void) {
|
||||||
#if USE_GLUT
|
|
||||||
glutDestroyWindow(glutWindow);
|
|
||||||
#endif
|
|
||||||
// Cleanup all OpenGL objects
|
// Cleanup all OpenGL objects
|
||||||
|
emulator_shutting_down = true;
|
||||||
glDeleteTextures(1, &a2TextureName);
|
glDeleteTextures(1, &a2TextureName);
|
||||||
a2TextureName = UNINITIALIZED_GL;
|
a2TextureName = UNINITIALIZED_GL;
|
||||||
_destroy_VAO(crtVAOName);
|
_destroy_VAO(crtVAOName);
|
||||||
@ -632,6 +630,15 @@ static void gldriver_shutdown(void) {
|
|||||||
glDeleteProgram(program);
|
glDeleteProgram(program);
|
||||||
program = UNINITIALIZED_GL;
|
program = UNINITIALIZED_GL;
|
||||||
glnode_shutdownNodes();
|
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) {
|
static void gldriver_main_loop(void) {
|
||||||
#if USE_GLUT
|
#if USE_GLUT
|
||||||
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
||||||
glutMainLoop();
|
glutMainLoop();
|
||||||
|
LOG("GLUT main loop finished...");
|
||||||
|
_gldriver_shutdown();
|
||||||
#endif
|
#endif
|
||||||
// fall through if not GLUT
|
// 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