1
0
mirror of git://sigrok.org/libserialport synced 2023-08-10 21:13:24 +03:00

Handle EINTR from tcdrain() in sp_drain().

This commit is contained in:
Martin Ling 2013-11-27 14:31:54 +00:00
parent b87deb7c70
commit 2c827b2188
2 changed files with 23 additions and 6 deletions

View File

@ -878,6 +878,13 @@ enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
/** /**
* Wait for buffered data to be transmitted. * Wait for buffered data to be transmitted.
* *
* @warning If your program runs on Unix, defines its own signal handlers, and
* needs to abort draining the output buffer when when these are
* called, then you should not use this function. It repeats system
* calls that return with EINTR. To be able to abort a drain from a
* signal handler, you would need to implement your own blocking
* drain by polling the result of sp_output_waiting().
*
* @param port Pointer to port structure. * @param port Pointer to port structure.
* *
* @return SP_OK upon success, a negative error code otherwise. * @return SP_OK upon success, a negative error code otherwise.

View File

@ -799,13 +799,23 @@ enum sp_return sp_drain(struct sp_port *port)
/* Returns non-zero upon success, 0 upon failure. */ /* Returns non-zero upon success, 0 upon failure. */
if (FlushFileBuffers(port->hdl) == 0) if (FlushFileBuffers(port->hdl) == 0)
RETURN_FAIL("FlushFileBuffers() failed"); RETURN_FAIL("FlushFileBuffers() failed");
#else
/* Returns 0 upon success, -1 upon failure. */
if (tcdrain(port->fd) < 0)
RETURN_FAIL("tcdrain() failed");
#endif
RETURN_OK(); RETURN_OK();
#else
int result;
while (1) {
result = tcdrain(port->fd);
if (result < 0) {
if (errno == EINTR) {
DEBUG("tcdrain() was interrupted");
continue;
} else {
RETURN_FAIL("tcdrain() failed");
}
} else {
RETURN_OK();
}
}
#endif
} }
enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout) enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout)