X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fsession.c;h=138f4222263ebc6b1027df1b92348144429951d4;hb=4399cc0f41077cd975601a095fd272a2bf27bb99;hp=158b33cf856a21e8f547982a4742d9cab918b4e2;hpb=ca7dbb56161f9f4b7f842103fca59d41d559c793;p=libsigrok.git diff --git a/src/session.c b/src/session.c index 158b33cf..138f4222 100644 --- a/src/session.c +++ b/src/session.c @@ -17,6 +17,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -358,6 +359,22 @@ SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger return SR_OK; } +static gboolean sr_session_check_aborted(struct sr_session *session) +{ + gboolean stop; + + g_mutex_lock(&session->stop_mutex); + stop = session->abort_session; + if (stop) { + sr_session_stop_sync(session); + /* But once is enough. */ + session->abort_session = FALSE; + } + g_mutex_unlock(&session->stop_mutex); + + return stop; +} + /** * Call every device in the current session's callback. * @@ -370,9 +387,8 @@ SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger * sources to fire an event on the file descriptors, or * any of their timeouts to activate. In other words, this * can be used as a select loop. - * If FALSE, all sources have their callback run, regardless - * of file descriptor or timeout status. - * + * If FALSE, return immediately if none of the sources has + * events pending. * @retval SR_OK Success. * @retval SR_ERR Error occurred. */ @@ -380,6 +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; @@ -389,7 +410,6 @@ static int sr_session_iteration(struct sr_session *session, gboolean block) #ifdef HAVE_LIBUSB_1_0 if (session->ctx->usb_source_present) { - timeout = block ? 0 : session->source_timeout; ret = libusb_get_next_timeout(session->ctx->libusb_ctx, &tv); if (ret < 0) { sr_err("Error getting libusb timeout: %s", @@ -403,34 +423,49 @@ 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 (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); - } - /* - * We want to take as little time as possible to stop - * the session if we have been told to do so. Therefore, - * we check the flag after processing every source, not - * just once per main event loop. - */ - g_mutex_lock(&session->stop_mutex); - if (session->abort_session) { - sr_session_stop_sync(session); - /* But once is enough. */ - session->abort_session = FALSE; + 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, + * we check the flag after processing every source, not + * just once per main event loop. + */ + if (!stopped) { + stopped = sr_session_check_aborted(session); + stop_checked = TRUE; + } } - g_mutex_unlock(&session->stop_mutex); } + if (!stop_checked) + sr_session_check_aborted(session); return SR_OK; } @@ -770,6 +805,7 @@ SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi, packet_in = packet_out; } } + packet = packet_in; /* * If the last transform did output a packet, pass it to all datafeed @@ -855,6 +891,7 @@ SR_API int sr_session_source_add(struct sr_session *session, int fd, p.fd = fd; p.events = events; + p.revents = 0; return _sr_session_source_add(session, &p, timeout, cb, cb_data, (gintptr)fd); } @@ -907,6 +944,7 @@ SR_API int sr_session_source_add_channel(struct sr_session *session, #else p.fd = g_io_channel_unix_get_fd(channel); p.events = events; + p.revents = 0; #endif return _sr_session_source_add(session, &p, timeout, cb, cb_data, (gintptr)channel);