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:
Daniel Elstner 2015-08-30 15:25:33 +02:00
parent 32af282c5e
commit 4399cc0f41
1 changed files with 18 additions and 6 deletions

View File

@ -396,8 +396,11 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
{
unsigned int i;
int ret, timeout;
int revents;
gboolean stop_checked;
gboolean stopped;
struct source *source;
GPollFD *pollfd;
#ifdef HAVE_LIBUSB_1_0
int usb_timeout;
struct timeval tv;
@ -420,26 +423,35 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
#endif
ret = g_poll(session->pollfds, session->num_sources, timeout);
#ifdef G_OS_UNIX
if (ret < 0 && errno != EINTR) {
sr_err("Error in poll: %s", g_strerror(errno));
return SR_ERR;
}
#else
if (ret < 0) {
sr_err("Error in poll: %d", ret);
return SR_ERR;
}
#endif
stop_checked = FALSE;
stopped = FALSE;
for (i = 0; i < session->num_sources; i++) {
if ((ret > 0 && session->pollfds[i].revents > 0) || (ret == 0
&& session->source_timeout == session->sources[i].timeout)) {
source = &session->sources[i];
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,
* or if the poll timed out and this source
* asked for that timeout.
*/
if (!session->sources[i].cb(session->pollfds[i].fd,
session->pollfds[i].revents,
session->sources[i].cb_data))
if (!source->cb(pollfd->fd, revents, source->cb_data))
sr_session_source_remove(session,
session->sources[i].poll_object);
source->poll_object);
/*
* We want to take as little time as possible to stop
* the session if we have been told to do so. Therefore,