X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=session.c;h=acf1158b4e3ad0e75061c4aa9ab831f5c5aadbd1;hb=a76842947faadad98572f011cb20f3220998f71b;hp=c372cb6b968c874fc9026762c8720cdf1a118c89;hpb=c7142604a2d29ca58f6e4d7cba070a329030e60b;p=libsigrok.git diff --git a/session.c b/session.c index c372cb6b..acf1158b 100644 --- a/session.c +++ b/session.c @@ -79,6 +79,8 @@ SR_API struct sr_session *sr_session_new(void) } session->source_timeout = -1; + session->abort_session = FALSE; + g_mutex_init(&session->stop_mutex); return session; } @@ -101,6 +103,8 @@ SR_API int sr_session_destroy(void) /* TODO: Error checks needed? */ + g_mutex_clear(&session->stop_mutex); + g_free(session); session = NULL; @@ -283,6 +287,16 @@ static int sr_session_run_poll(void) session->sources[i].cb_data)) sr_session_source_remove(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(); + g_mutex_unlock(&session->stop_mutex); } } @@ -366,29 +380,18 @@ SR_API int sr_session_run(void) return SR_OK; } -/** - * Halt the current session. - * - * This function is deprecated and should not be used in new code, use - * sr_session_stop() instead. The behaviour of this function is identical to - * sr_session_stop(). - * - * @return SR_OK upon success, SR_ERR_BUG if no session exists. - */ -SR_API int sr_session_halt(void) -{ - return sr_session_stop(); -} - /** * Stop the current session. * * The current session is stopped immediately, with all acquisition sessions * being stopped and hardware drivers cleaned up. * + * This must be called from within the session thread, to prevent freeing + * resources that the session thread will try to use. + * * @return SR_OK upon success, SR_ERR_BUG if no session exists. */ -SR_API int sr_session_stop(void) +SR_PRIV int sr_session_stop_sync(void) { struct sr_dev_inst *sdi; GSList *l; @@ -420,6 +423,33 @@ SR_API int sr_session_stop(void) return SR_OK; } +/** + * Stop the current session. + * + * The current session is stopped immediately, with all acquisition sessions + * being stopped and hardware drivers cleaned up. + * + * If the session is run in a separate thread, this function will not block + * until the session is finished executing. It is the caller's responsibility + * to wait for the session thread to return before assuming that the session is + * completely decommissioned. + * + * @return SR_OK upon success, SR_ERR_BUG if no session exists. + */ +SR_API int sr_session_stop(void) +{ + if (!session) { + sr_err("%s: session was NULL", __func__); + return SR_ERR_BUG; + } + + g_mutex_lock(&session->stop_mutex); + session->abort_session = TRUE; + g_mutex_unlock(&session->stop_mutex); + + return SR_OK; +} + /** * Debug helper. *