Hello,

I would like to propose a patch which allow to not block signals
during execution of ftdi_transfer_data_done() function.
If we would like to have possibility to interrupt the
ftdi_transfer_data_done by signals we should use call the new function
ftdi_transfer_set_sigblock() before calling ftdi_transfer_data_done(),
example workflow:

ctrl = ftdi_write_data_submit() / ftdi_read_data_submit()
ftdi_transfer_set_sigblock(ctrl, 0);
ftdi_transfer_data_done(ctrl); // now signals can interrupt
ftdi_transfer_data_done()

If we don't call ftdi_transfer_set_sigblock() we will have the old
behaviour: the ftdi_transfer_data_done() will not be interrupted by
signals:

ctrl = ftdi_write_data_submit() / ftdi_read_data_submit()
ftdi_transfer_data_done(ctrl); // old behaviour:
ftdi_transfer_data_done() blocks signals

Best Regards
Michal Semeniuk


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to [email protected]   
diff --git a/src/ftdi.c b/src/ftdi.c
index fdf93fe..febab15 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -1613,6 +1613,7 @@ struct ftdi_transfer_control *ftdi_write_data_submit(struct ftdi_context *ftdi,
 
     tc->ftdi = ftdi;
     tc->completed = 0;
+    tc->sigblock = 1;
     tc->buf = buf;
     tc->size = size;
     tc->offset = 0;
@@ -1669,6 +1670,7 @@ struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, u
     tc->ftdi = ftdi;
     tc->buf = buf;
     tc->size = size;
+    tc->sigblock = 1;
 
     if (size <= (int)ftdi->readbuffer_remaining)
     {
@@ -1722,6 +1724,24 @@ struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, u
 }
 
 /**
+    Sets the signal block flag for given transfer control structure.
+    This flag allows to block signals during ftdi_transfer_data_done() execution.
+
+    \param tc Pointer to transfer control structure
+    \param flag Value of sigblock flag to set:
+        \li <tt> 0 </tt> ftdi_transfer_data_done() could be interrupted by signals
+        \li <tt> != 0 </tt> ftdi_transfer_data_done() will not honour signals
+*/
+
+void ftdi_transfer_set_sigblock(struct ftdi_transfer_control *tc, int flag)
+{
+    if (tc)
+        tc->sigblock = flag;
+
+    return;
+}
+
+/**
     Wait for completion of the transfer.
 
     Use libusb 1.0 asynchronous API.
@@ -1730,6 +1750,12 @@ struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, u
 
     \retval < 0: Some error happens
     \retval >= 0: Data size transferred
+
+    \remark
+    This function could be interrupted by signals
+    if sigblock field in tc structure was set to 0.
+    Default behaviour: signals are blocked.
+    See ftdi_transfer_set_sigblock()
 */
 
 int ftdi_transfer_data_done(struct ftdi_transfer_control *tc)
@@ -1742,7 +1768,7 @@ int ftdi_transfer_data_done(struct ftdi_transfer_control *tc)
                 &to, &tc->completed);
         if (ret < 0)
         {
-            if (ret == LIBUSB_ERROR_INTERRUPTED)
+            if ((tc->sigblock) && (ret == LIBUSB_ERROR_INTERRUPTED))
                 continue;
             libusb_cancel_transfer(tc->transfer);
             while (!tc->completed)
@@ -1756,10 +1782,10 @@ int ftdi_transfer_data_done(struct ftdi_transfer_control *tc)
     }
 
     ret = tc->offset;
-    /**
+    /*
      * tc->transfer could be NULL if "(size <= ftdi->readbuffer_remaining)"
      * at ftdi_read_data_submit(). Therefore, we need to check it here.
-     **/
+     */
     if (tc->transfer)
     {
         if (tc->transfer->status != LIBUSB_TRANSFER_COMPLETED)
diff --git a/src/ftdi.h b/src/ftdi.h
index ca38bbe..005b852 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -204,6 +204,7 @@ enum ftdi_module_detach_mode
 struct ftdi_transfer_control
 {
     int completed;
+    int sigblock;
     unsigned char *buf;
     int size;
     int offset;
@@ -524,6 +525,7 @@ extern "C"
     struct ftdi_transfer_control *ftdi_write_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size);
 
     struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size);
+    void ftdi_transfer_set_sigblock(struct ftdi_transfer_control *tc, int flag);
     int ftdi_transfer_data_done(struct ftdi_transfer_control *tc);
     void ftdi_transfer_data_cancel(struct ftdi_transfer_control *tc, struct timeval * to);
 

Reply via email to