Submitted by Ivan Frederiks:

patch #9079: Fix ftdi_syncbb teardown

Fix teardown sequence between reader thread and libusb.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1473 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2021-11-14 13:34:20 +00:00
parent 5e6a662e8a
commit ebea9b5237
1 changed files with 10 additions and 11 deletions

View File

@ -173,16 +173,22 @@ static void add_to_buf (unsigned char c) {
} }
static void *reader (void *arg) { static void *reader (void *arg) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
struct ftdi_context *handle = (struct ftdi_context *)(arg); struct ftdi_context *handle = (struct ftdi_context *)(arg);
unsigned char buf[0x1000]; unsigned char buf[0x1000];
int br, i; int br, i;
while (1) { while (1) {
/* 'old_cancel_state' added for portability reasons,
* see pthread_setcancelstate() manual */
int old_cancel_state;
pthread_testcancel(); pthread_testcancel();
/* isolate libftdi and libusb from cancellation requests to prevent unhandled behavior */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancel_state);
br = ftdi_read_data (handle, buf, sizeof(buf)); br = ftdi_read_data (handle, buf, sizeof(buf));
for (i=0; i<br; i++) for (i=0; i<br; i++)
add_to_buf (buf[i]); add_to_buf (buf[i]);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
} }
return NULL; return NULL;
} }
@ -681,21 +687,14 @@ cleanup_no_usb:
static void ft245r_close(PROGRAMMER * pgm) { static void ft245r_close(PROGRAMMER * pgm) {
int retry_times = 0;
if (handle) { if (handle) {
/* reader thread must be stopped before libftdi de-initialization */
pthread_cancel(readerthread);
pthread_join(readerthread, NULL);
// I think the switch to BB mode and back flushes the buffer. // 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_SYNCBB); // set Synchronous BitBang, all in puts
ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
ftdi_usb_close(handle); ftdi_usb_close(handle);
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); ftdi_deinit (handle);
free(handle); free(handle);
handle = NULL; handle = NULL;