Add sr_session_iteration() API function

This commit is contained in:
Bert Vermeulen 2013-07-15 14:14:28 +02:00
parent f336618c3d
commit b483be7456
2 changed files with 38 additions and 29 deletions

View File

@ -97,6 +97,7 @@ SR_API int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb,
void *cb_data); void *cb_data);
/* Session control */ /* Session control */
SR_API int sr_session_iteration(gboolean block);
SR_API int sr_session_start(void); SR_API int sr_session_start(void);
SR_API int sr_session_run(void); SR_API int sr_session_run(void);
SR_API int sr_session_stop(void); SR_API int sr_session_stop(void);

View File

@ -232,41 +232,48 @@ SR_API int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb, void *cb_
return SR_OK; return SR_OK;
} }
static int sr_session_run_poll(void) /**
* Call every device in the session's callback.
*
* For sessions not driven by select loops such as sr_session_run(),
* but driven by another scheduler, this can be used to poll the devices
* from within that scheduler.
*
* @return SR_OK upon success, SR_ERR on errors.
*/
SR_API int sr_session_iteration(gboolean block)
{ {
unsigned int i; unsigned int i;
int ret; int ret;
while (session->num_sources > 0) { ret = g_poll(session->pollfds, session->num_sources,
ret = g_poll(session->pollfds, session->num_sources, block ? session->source_timeout : 0);
session->source_timeout); for (i = 0; i < session->num_sources; i++) {
for (i = 0; i < session->num_sources; i++) { if (session->pollfds[i].revents > 0 || (ret == 0
if (session->pollfds[i].revents > 0 || (ret == 0 && session->source_timeout == session->sources[i].timeout)) {
&& session->source_timeout == session->sources[i].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))
sr_session_source_remove(session->sources[i].poll_object);
}
/* /*
* We want to take as little time as possible to stop * Invoke the source's callback on an event,
* the session if we have been told to do so. Therefore, * or if the poll timed out and this source
* we check the flag after processing every source, not * asked for that timeout.
* just once per main event loop.
*/ */
g_mutex_lock(&session->stop_mutex); if (!session->sources[i].cb(session->pollfds[i].fd,
if (session->abort_session) { session->pollfds[i].revents,
sr_session_stop_sync(); session->sources[i].cb_data))
/* But once is enough. */ sr_session_source_remove(session->sources[i].poll_object);
session->abort_session = FALSE;
}
g_mutex_unlock(&session->stop_mutex);
} }
/*
* 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();
/* But once is enough. */
session->abort_session = FALSE;
}
g_mutex_unlock(&session->stop_mutex);
} }
return SR_OK; return SR_OK;
@ -343,7 +350,8 @@ SR_API int sr_session_run(void)
session->sources[0].cb(-1, 0, session->sources[0].cb_data); session->sources[0].cb(-1, 0, session->sources[0].cb_data);
} else { } else {
/* Real sources, use g_poll() main loop. */ /* Real sources, use g_poll() main loop. */
sr_session_run_poll(); while (session->num_sources)
sr_session_iteration(TRUE);
} }
return SR_OK; return SR_OK;