Skip to content

Commit

Permalink
Improve thread cancellation error reporting
Browse files Browse the repository at this point in the history
Check for specific errors.
Add retry loop with timeout for pthread_join.
  • Loading branch information
PartialVolume committed Dec 7, 2021
1 parent 4351b3d commit c433326
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 24 deletions.
78 changes: 63 additions & 15 deletions src/nwipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ int main( int argc, char** argv )
int nwipe_enumerated; // The number of contexts that have been enumerated.
int nwipe_error = 0; // An error counter.
int nwipe_selected = 0; // The number of contexts that have been selected.
int any_threads_still_running; // used in wipe thread cancellation wait loop
int thread_timeout_counter; // timeout thread cancellation after THREAD_CANCELLATION_TIMEOUT seconds
pthread_t nwipe_gui_thread = 0; // The thread ID of the GUI thread.
pthread_t nwipe_sigint_thread; // The thread ID of the sigint handler.

Expand Down Expand Up @@ -587,7 +589,6 @@ int main( int argc, char** argv )
if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "Requesting wipe thread cancellation for %s", c2[i]->device_name );
nwipe_log( NWIPE_LOG_INFO, "Please wait.." );
}
pthread_cancel( c2[i]->thread );
}
Expand Down Expand Up @@ -622,27 +623,74 @@ int main( int argc, char** argv )
}

/* Now join the wipe threads and wait until they have terminated */
for( i = 0; i < nwipe_selected; i++ )
any_threads_still_running = 1;
thread_timeout_counter = THREAD_CANCELLATION_TIMEOUT;
while( any_threads_still_running )
{
/* quit waiting if we've tried 'thread_timeout_counter' times */
if( thread_timeout_counter == 0 )
{
break;
}

if( c2[i]->thread )
any_threads_still_running = 0;
for( i = 0; i < nwipe_selected; i++ )
{
/* Joins the thread and waits for completion before continuing */
r = pthread_join( c2[i]->thread, NULL );
if( r != 0 )
if( c2[i]->thread )
{
nwipe_log( NWIPE_LOG_WARNING, "main()>pthread_join():Error when waiting for wipe thread to cancel." );
}
c2[i]->thread = 0; /* Zero the thread so we know it's been cancelled */
printf( "\nWaiting for wipe thread to cancel for %s\n", c2[i]->device_name );

if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "Wipe thread for device %s has been cancelled", c2[i]->device_name );
}
/* Joins the thread and waits for completion before continuing */
r = pthread_join( c2[i]->thread, NULL );
if( r != 0 )
{
nwipe_log( NWIPE_LOG_ERROR,
"Error joining the wipe thread when waiting for thread to cancel.",
c2[i]->device_name );

if( r == EDEADLK )
{
nwipe_log( NWIPE_LOG_ERROR,
"Error joining the wipe thread: EDEADLK: Deadlock detected.",
c2[i]->device_name );
}
else
{
if( r == EINVAL )
{
nwipe_log( NWIPE_LOG_ERROR,
"Error joining the wipe thread: %s EINVAL: thread is not joinable.",
c2[i]->device_name );
}
else
{
if( r == ESRCH )
{
nwipe_log( NWIPE_LOG_ERROR,
"Error joining the wipe thread: %s ESRCH: no matching thread found",
c2[i]->device_name );
}
}
}

/* Close the device file descriptor. */
close( c2[i]->device_fd );
any_threads_still_running = 1;
}
else
{
c2[i]->thread = 0; /* Zero the thread so we know it's been cancelled */

if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "Wipe thread for device %s has terminated", c2[i]->device_name );
}

/* Close the device file descriptor. */
close( c2[i]->device_fd );
}
}
}
thread_timeout_counter--;
sleep( 1 );
}
if( nwipe_options.verbose )
{
Expand Down
9 changes: 2 additions & 7 deletions src/nwipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,6 @@ extern int errno;
/* 0=wipe not yet started, 1=wipe has been started by the user */
extern int global_wipe_status;

/* Global array to hold log values to print when logging to STDOUT */
/* char **log_lines;
int log_current_element = 0;
int log_elements_allocated = 0;
int log_elements_displayed = 0;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; */

/* Ncurses headers. */
#ifdef NCURSES_IN_SUBDIR
#include <ncurses/ncurses.h>
Expand Down Expand Up @@ -113,6 +106,8 @@ typedef unsigned char u8;
#define BLKBSZSET _IOW( 0x12, 113, size_t )
#define BLKGETSIZE64 _IOR( 0x12, 114, sizeof( u64 ) )

#define THREAD_CANCELLATION_TIMEOUT 10

/* This is required for ioctl FDFLUSH. */
#include <linux/fd.h>

Expand Down
4 changes: 2 additions & 2 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* used by configure to dynamically assign those values
* to documentation files.
*/
const char* version_string = "0.32.016";
const char* version_string = "0.32.017";
const char* program_name = "nwipe";
const char* author_name = "Martijn van Brummelen";
const char* email_address = "[email protected]";
Expand All @@ -14,4 +14,4 @@ Modifications to original dwipe Copyright Andy Beverley <[email protected]>\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.016";
const char* banner = "nwipe 0.32.017";

0 comments on commit c433326

Please sign in to comment.