From c34fb8884413e44dc95decb773d04fb2b583dba7 Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Wed, 11 Mar 2020 12:39:57 +0000
Subject: [PATCH] Submitted by: kautism patch #9893: [PATCH] Reader reads ftdi
 handle after main thread close it * ft245r.c: Wait until reader thread has
 been stopped before closing FTDI

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1434 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog |  6 ++++++
 NEWS      |  1 +
 ft245r.c  | 12 ++++++++++--
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ed71a6f8..ee0036b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2020-03-11  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by: kautism
+	patch #9893: [PATCH] Reader reads ftdi handle after main thread close it
+	* ft245r.c: Wait until reader thread has been stopped before closing FTDI
+
 2020-03-11  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	Fix compiler warnings
diff --git a/NEWS b/NEWS
index 431746a6..2f495742 100644
--- a/NEWS
+++ b/NEWS
@@ -68,6 +68,7 @@ Current:
     patch #8444: Proposal for modifications in -B and -U command options managment (partially)
     patch #9735: spelling error fix: psuedo -> pseudo
     patch #9728: Fix UsbTiny programmer
+    patch #9893: [PATCH] Reader reads ftdi handle after main thread close it
 
   * Internals:
     - New avrdude.conf keyword "family_id", used to verify SIB attributes
diff --git a/ft245r.c b/ft245r.c
index 7f9883f1..ca78a73d 100644
--- a/ft245r.c
+++ b/ft245r.c
@@ -681,14 +681,22 @@ cleanup_no_usb:
 
 
 static void ft245r_close(PROGRAMMER * pgm) {
+    int retry_times = 0;
     if (handle) {
         // I think the switch to BB mode and back flushes the buffer.
         ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts
         ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
         ftdi_usb_close(handle);
-        ftdi_deinit (handle);
-        pthread_cancel(readerthread);
+        while(pthread_cancel(readerthread) && retry_times < 100) {
+            retry_times++;
+            usleep(100);
+        }
+        if (retry_times >= 100) {
+            avrdude_message(MSG_INFO, "Too many retry to close reader thread\n");
+        }
+
         pthread_join(readerthread, NULL);
+        ftdi_deinit (handle);
         free(handle);
         handle = NULL;
     }