session: Do not expect meaningful errno on non-UNIX
Looking at the g_poll() implementations for various systems, it appears that on Windows the return value is 0 if the wait was interrupted, and errno is never set. Also, the MacOS X wrapper around select() does not clear revents on timeout. To deal with these issues, check for EINTR only on Unices, and assume revents to be invalid unless g_poll() returned a positive value.
This commit is contained in:
parent
32af282c5e
commit
4399cc0f41
|
@ -396,8 +396,11 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret, timeout;
|
int ret, timeout;
|
||||||
|
int revents;
|
||||||
gboolean stop_checked;
|
gboolean stop_checked;
|
||||||
gboolean stopped;
|
gboolean stopped;
|
||||||
|
struct source *source;
|
||||||
|
GPollFD *pollfd;
|
||||||
#ifdef HAVE_LIBUSB_1_0
|
#ifdef HAVE_LIBUSB_1_0
|
||||||
int usb_timeout;
|
int usb_timeout;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -420,26 +423,35 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = g_poll(session->pollfds, session->num_sources, timeout);
|
ret = g_poll(session->pollfds, session->num_sources, timeout);
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
if (ret < 0 && errno != EINTR) {
|
if (ret < 0 && errno != EINTR) {
|
||||||
sr_err("Error in poll: %s", g_strerror(errno));
|
sr_err("Error in poll: %s", g_strerror(errno));
|
||||||
return SR_ERR;
|
return SR_ERR;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (ret < 0) {
|
||||||
|
sr_err("Error in poll: %d", ret);
|
||||||
|
return SR_ERR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
stop_checked = FALSE;
|
stop_checked = FALSE;
|
||||||
stopped = FALSE;
|
stopped = FALSE;
|
||||||
|
|
||||||
for (i = 0; i < session->num_sources; i++) {
|
for (i = 0; i < session->num_sources; i++) {
|
||||||
if ((ret > 0 && session->pollfds[i].revents > 0) || (ret == 0
|
source = &session->sources[i];
|
||||||
&& session->source_timeout == session->sources[i].timeout)) {
|
pollfd = &session->pollfds[i];
|
||||||
|
revents = (ret > 0) ? pollfd->revents : 0;
|
||||||
|
|
||||||
|
if (revents > 0 || (ret == 0
|
||||||
|
&& session->source_timeout == source->timeout)) {
|
||||||
/*
|
/*
|
||||||
* Invoke the source's callback on an event,
|
* Invoke the source's callback on an event,
|
||||||
* or if the poll timed out and this source
|
* or if the poll timed out and this source
|
||||||
* asked for that timeout.
|
* asked for that timeout.
|
||||||
*/
|
*/
|
||||||
if (!session->sources[i].cb(session->pollfds[i].fd,
|
if (!source->cb(pollfd->fd, revents, source->cb_data))
|
||||||
session->pollfds[i].revents,
|
|
||||||
session->sources[i].cb_data))
|
|
||||||
sr_session_source_remove(session,
|
sr_session_source_remove(session,
|
||||||
session->sources[i].poll_object);
|
source->poll_object);
|
||||||
/*
|
/*
|
||||||
* We want to take as little time as possible to stop
|
* We want to take as little time as possible to stop
|
||||||
* the session if we have been told to do so. Therefore,
|
* the session if we have been told to do so. Therefore,
|
||||||
|
|
Loading…
Reference in New Issue