diff --git a/ft245r.c b/ft245r.c index ca78a73d..b155e82e 100644 --- a/ft245r.c +++ b/ft245r.c @@ -173,16 +173,22 @@ static void add_to_buf (unsigned char c) { } 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); unsigned char buf[0x1000]; int br, i; while (1) { + /* 'old_cancel_state' added for portability reasons, + * see pthread_setcancelstate() manual */ + int old_cancel_state; 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)); for (i=0; i<br; i++) add_to_buf (buf[i]); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state); } return NULL; } @@ -681,21 +687,14 @@ cleanup_no_usb: static void ft245r_close(PROGRAMMER * pgm) { - int retry_times = 0; 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. 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); - 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;