return -PA_ERR_IO;
}
+/* Called from the IO thread. */
+static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
+ struct userdata *u;
+ int r;
+
+ pa_assert(s);
+ pa_assert_se(u = s->userdata);
+
+ /* It may be that only the suspend cause is changing, in which case there's
+ * nothing to do. */
+ if (new_state == s->thread_info.state)
+ return 0;
+
+ switch (new_state) {
+ case PA_SINK_SUSPENDED: {
+ pa_assert(PA_SINK_IS_OPENED(s->thread_info.state));
+ if ((r = suspend(u)) < 0)
+ return r;
+ break;
+ }
+
+ case PA_SINK_IDLE:
+ case PA_SINK_RUNNING: {
+ if (s->thread_info.state == PA_SINK_INIT) {
+ if (build_pollfd(u) < 0)
+ return -PA_ERR_IO;
+ }
+
+ if (s->thread_info.state == PA_SINK_SUSPENDED) {
+ if ((r = unsuspend(u)) < 0)
+ return r;
+ }
+ break;
+ }
+
+ case PA_SINK_UNLINKED:
+ case PA_SINK_INIT:
+ case PA_SINK_INVALID_STATE:
+ break;
+ }
+
+ return 0;
+}
+
static int sink_process_msg(
pa_msgobject *o,
int code,
pa_memchunk *chunk) {
struct userdata *u = PA_SINK(o)->userdata;
- int r;
switch (code) {
- case PA_SINK_MESSAGE_SET_STATE:
- switch ((pa_sink_state_t)PA_PTR_TO_UINT(data)) {
- case PA_SINK_SUSPENDED: {
- pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
- if ((r = suspend(u)) < 0)
- return r;
- break;
- }
-
- case PA_SINK_IDLE:
- case PA_SINK_RUNNING: {
- if (u->sink->thread_info.state == PA_SINK_INIT) {
- if (build_pollfd(u) < 0)
- return -PA_ERR_IO;
- }
-
- if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
- if ((r = unsuspend(u)) < 0)
- return r;
- }
- break;
- }
-
- case PA_SINK_UNLINKED:
- case PA_SINK_INIT:
- case PA_SINK_INVALID_STATE:
- break;
- }
- break;
-
case PA_SINK_MESSAGE_GET_LATENCY: {
pa_usec_t now = pa_rtclock_now();
pa_usec_t latency = 0ULL;
}
u->sink->parent.process_msg = sink_process_msg;
+ u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
u->sink->update_requested_latency = sink_update_requested_latency_cb;
u->sink->userdata = u;