Fix_nwipe_not_exiting_when_using_konsole

This fixes a issue related to konsole and terminals based on Konsole,
like cool retro terminal. If you exit the terminal before exiting nwipe,
nwipe will then continue running in the background but detached from any
terminals input/output. This causes a call to halfdelay()/getch() to
return immediately, thus removing the delay and causing the thread to
run at full speed causing 100% CPU in a core. This requires nwipe to
then be killed manually. This patch is related to the last patch in
that both patches do much the same thing but the previous patch fixes
the problem when nwipe is sitting at the drive selection screen, while
this patch fixes the problem during a wipe.

This problem would only be seen in specific KDE konsole related
terminals and only if you do not exit nwipe by using nwipe's control c
to abort or use the space bar on completion of the wipe.

Much like the same check we perform in the nwipe_gui_select() function,
here we check that we are not looping any faster than as defined by the
halfdelay() function, typically this loop runs at 10 times a second.
This check makes sure that if the loop runs faster than double this
value i.e 20 times a second then the program exits. This check is
therefore determining whether the getch() function is returning
immediately rather than blocking for the defined period of 100ms.
Why is this necessary? Some terminals (konsole & deriviatives) that are
exited while nwipe is still running fail to terminate nwipe this causes
the halfdelay()/getch() functions to immediately fail causing the loop
frequency to drastically increase. We detect that speed increase here
and therefore close down nwipe. This doesn't affect the use of the tmux
terminal by which you can detach and reattach to running nwipe
processes. The tmux terminal will still work correctly when a nwipe
session is detached.
This commit is contained in:
PartialVolume
2022-03-03 19:48:44 +00:00
parent 3f3ea5e04b
commit 791c6f3975
3 changed files with 55 additions and 5 deletions

View File

@@ -647,8 +647,6 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
* period */
int expected_iterations;
time_t iteration_timestamp;
time_t previous_iteration_timestamp;
do
@@ -2544,6 +2542,20 @@ void* nwipe_gui_status( void* ptr )
/* Set to 1 initially to start loop. */
int nwipe_active = 1;
/* Used in the gui status loop to trap a failure of the halfdelay(), getch() mechanism to block for the designated
* period */
int expected_iterations;
/* Used in the selection loop to trap a failure of the timeout(), getch() mechanism to block for the designated
* period, initialise the counter */
int iteration_counter = 0;
time_t previous_iteration_timestamp = time( NULL );
/* Calculate Maximum allowed iterations per second (typically 20), which is double the expected iterations
* (typically 10) */
expected_iterations = ( 1000 / GETCH_GUI_STATS_UPDATE_MS ) * 2;
if( nwipe_time_start == 0 )
{
/* This is the first time that we have been called. */
@@ -2562,10 +2574,41 @@ void* nwipe_gui_status( void* ptr )
* 2. By keeping the delay below 0.2 seconds, i.e 0.1, it makes the keypress and resizing
* nice and responsive.
*/
halfdelay( 1 ); // Important, don't change this unless you know what you are doing ! Related to getch().
halfdelay( GETCH_GUI_STATS_UPDATE_MS ); // Important, don't change this unless you know what you are doing !
// Related to getch().
keystroke = getch(); // Get user input.
iteration_counter++;
/* Much like the same check we perform in the nwipe_gui_select() function, here we check that we are not looping
* any faster than as defined by the halfdelay() function above, typically this loop runs at 10 times a second.
* This check makes sure that if the loop runs faster than double this value i.e 20 times a second then the
* program exits. This check is therefore determining whether the getch() function is returning immediately
* rather than blocking for the defined period of 100ms. Why is this necessary? Some terminals (konsole &
* deriviatives) that are exited while nwipe is still running fail to terminate nwipe this causes the
* halfdelay()/getch() functions to immediately fail causing the loop frequency to drastically increase. We
* detect that speed increase here and therefore close down nwipe. This doesn't affect the use of the tmux
* terminal by which you can detach and reattach to running nwipe processes. tmux still works correctly.
*/
if( previous_iteration_timestamp == time( NULL ) )
{
if( iteration_counter > expected_iterations )
{
nwipe_log( NWIPE_LOG_ERROR,
"GUI.c,nwipe_gui_status(), loop runaway, did you close the terminal without exiting "
"nwipe? Initiating shutdown now." );
/* Issue signal to nwipe to shutdown immediately but gracefully */
terminate_signal = 1;
}
}
else
{
/* new second, so reset counter */
iteration_counter = 0;
previous_iteration_timestamp = time( NULL );
}
/* Get the current time. */
if( nwipe_active && terminate_signal != 1 )
{

View File

@@ -50,6 +50,13 @@ void nwipe_update_speedring( nwipe_speedring_t* speedring, u64 speedring_done, t
#define NOMENCLATURE_RESULT_STR_SIZE 8
/* Note Do not change unless you understand how this value affects keyboard response and screen refresh when
* the drive selection screen is displayed. (prior to wipe starting). */
#define GETCH_BLOCK_MS 250 /* millisecond block time for getch() */
/* Note The value of 1 (100ms) is the ideal speed for screen refresh during a wipe, a value of 2 is noticably slower,
* don't change unless you understand how this value affects keyboard responsiveness and speed of screen stats/spinner
* updating */
#define GETCH_GUI_STATS_UPDATE_MS 1 /* 1 * 100 = 1/10/sec = millisecond block time for gui stats screen updates */
#endif /* GUI_H_ */

View File

@@ -4,7 +4,7 @@
* used by configure to dynamically assign those values
* to documentation files.
*/
const char* version_string = "0.32.026";
const char* version_string = "0.32.027";
const char* program_name = "nwipe";
const char* author_name = "Martijn van Brummelen";
const char* email_address = "git@brumit.nl";
@@ -14,4 +14,4 @@ Modifications to original dwipe Copyright Andy Beverley <andy@andybev.com>\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS\n\
FOR A PARTICULAR PURPOSE.\n";
const char* banner = "nwipe 0.32.026";
const char* banner = "nwipe 0.32.027";