From 7a4ded8380a915197414874f3f1f5e704dbe2a8e Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Mon, 9 Jan 2023 15:43:25 -1000 Subject: [PATCH] FRONTPANEL: Avoid potential deadlock when shutting down a panel application --- sim_console.c | 3 ++- sim_frontpanel.c | 17 +++++++++++++++-- sim_frontpanel.h | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/sim_console.c b/sim_console.c index 95a7e8df..82b26ddd 100644 --- a/sim_console.c +++ b/sim_console.c @@ -633,7 +633,7 @@ for (i=connections=0; ilp, i); if (rem->read_timeout != sim_rem_read_timeout) { if (rem->read_timeout) @@ -668,6 +668,7 @@ for (i=connections=0; iline); + fprintf (st, "\n"); } } return SCPE_OK; diff --git a/sim_frontpanel.c b/sim_frontpanel.c index 95a5b9e6..cc2e0755 100644 --- a/sim_frontpanel.c +++ b/sim_frontpanel.c @@ -822,8 +822,8 @@ else { fclose (fIn); fIn = NULL; fprintf (fOut, "set remote notelnet\n"); - if (device_panel_count) - fprintf (fOut, "set remote connections=%d\n", (int)device_panel_count+1); + if ((device_panel_count != 0) || (debug_file != NULL)) + fprintf (fOut, "set remote connections=%d\n", (int)(device_panel_count + 1 + ((debug_file != NULL) ? 1 : 0))); fprintf (fOut, "set remote -u telnet=%s\n", hostport); fprintf (fOut, "set remote master\n"); fprintf (fOut, "exit\n"); @@ -1430,10 +1430,23 @@ if (usecs_between_callbacks && (0 == panel->usecs_between_callbacks)) { /* Need pthread_cond_destroy (&panel->startup_done); } if ((usecs_between_callbacks == 0) && panel->usecs_between_callbacks) { /* Need to stop callbacks */ + OperationalState PriorState = panel->State; /* record initial state */ _panel_debug (panel, DBG_THR, "Shutting down callback thread", NULL, 0); + + if (PriorState == Run) { /* If running? */ + pthread_mutex_unlock (&panel->io_lock); /* allow access */ + sim_panel_exec_halt (panel); /* Stop for Now */ + pthread_mutex_lock (&panel->io_lock); /* acquire access */ + } panel->usecs_between_callbacks = 0; /* flag disabled */ pthread_mutex_unlock (&panel->io_lock); /* allow access */ pthread_join (panel->callback_thread, NULL); /* synchronize with thread rundown */ + + if (PriorState == Run) { /* If was running? */ + pthread_mutex_lock (&panel->io_lock); /* allow access */ + sim_panel_exec_halt (panel); /* resume running */ + pthread_mutex_unlock (&panel->io_lock); /* acquire access */ + } pthread_mutex_lock (&panel->io_lock); /* reacquire access */ } pthread_mutex_unlock (&panel->io_lock); diff --git a/sim_frontpanel.h b/sim_frontpanel.h index 38e5aecd..6623b13c 100644 --- a/sim_frontpanel.h +++ b/sim_frontpanel.h @@ -56,7 +56,7 @@ extern "C" { #if !defined(__VAX) /* Unsupported platform */ -#define SIM_FRONTPANEL_VERSION 13 +#define SIM_FRONTPANEL_VERSION 14 /**