pulse: protect context

Make sure the context is READY when calling function
Protect pa_operation_sync against disconnected context

Fixes #365
This commit is contained in:
Wim Taymans 2020-11-04 19:27:17 +01:00
parent 7a43769648
commit 6444147a12
2 changed files with 52 additions and 1 deletions

View file

@ -619,6 +619,8 @@ pa_operation* pa_context_suspend_sink_by_name(pa_context *c, const char *sink_na
pa_operation *o;
struct success_ack *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: name:%s suspend:%d", c, sink_name, suspend);
o = pa_operation_new(c, NULL, on_success, sizeof(struct success_ack));
d = o->userdata;
@ -636,6 +638,8 @@ pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int
pa_operation *o;
struct success_ack *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index:%u suspend:%d", c, idx, suspend);
o = pa_operation_new(c, NULL, on_success, sizeof(struct success_ack));
d = o->userdata;
@ -993,6 +997,7 @@ pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, p
pa_assert(c->refcount >= 1);
pa_assert(cb);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
pw_log_debug("context %p: index %d", c, idx);
@ -1158,6 +1163,8 @@ pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *sourc
pa_operation *o;
struct success_ack *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: name:%s", c, source_name);
o = pa_operation_new(c, NULL, on_success, sizeof(struct success_ack));
@ -1176,6 +1183,8 @@ pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, in
pa_operation *o;
struct success_ack *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index:%u", c, idx);
o = pa_operation_new(c, NULL, on_success, sizeof(struct success_ack));
d = o->userdata;
@ -1309,6 +1318,8 @@ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb,
pa_assert(c->refcount >= 1);
pa_assert(cb);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p", c);
o = pa_operation_new(c, NULL, server_info, sizeof(struct server_data));
d = o->userdata;
@ -1363,6 +1374,7 @@ pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_
pa_assert(c->refcount >= 1);
pa_assert(cb);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
pw_log_debug("context %p index:%u", c, idx);
@ -1560,6 +1572,8 @@ pa_operation* pa_context_load_module(pa_context *c, const char*name, const char
pa_assert(c->refcount >= 1);
pa_assert(name != NULL);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: name:%s arg:%s", c, name, argument);
o = pa_operation_new(c, NULL, on_load_module, sizeof(struct load_module));
@ -1610,6 +1624,8 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_s
struct module_info *m;
int error;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: %u", c, idx);
if ((m = find_module(c, idx)) != NULL) {
pw_proxy_destroy(m->proxy);
@ -1672,6 +1688,7 @@ pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_
pa_assert(c->refcount >= 1);
pa_assert(cb);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
pw_log_debug("context %p: index:%u", c, idx);
@ -1757,6 +1774,7 @@ pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_suc
pa_operation *o;
struct kill_client *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
pw_log_debug("context %p: index:%u", c, idx);
@ -2012,6 +2030,8 @@ pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card
pa_operation *o;
struct success_ack *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p: card_name:%s port_name:%s offset:%"PRIi64, c, card_name, port_name, offset);
o = pa_operation_new(c, NULL, on_success, sizeof(struct success_ack));
d = o->userdata;
@ -2146,6 +2166,7 @@ pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sin
pa_assert(c->refcount >= 1);
pa_assert(cb);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
pw_log_debug("context %p: info for %d", c, idx);
@ -2257,6 +2278,8 @@ pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, co
pa_operation *o;
struct target_node *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p: index:%u name:%s", c, idx, sink_name);
o = pa_operation_new(c, NULL, do_target_node, sizeof(struct target_node));
d = o->userdata;
@ -2278,6 +2301,8 @@ pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, u
pa_operation *o;
struct target_node *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p: index:%u sink_index:%u", c, idx, sink_idx);
o = pa_operation_new(c, NULL, do_target_node, sizeof(struct target_node));
d = o->userdata;
@ -2341,6 +2366,8 @@ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, cons
pa_operation *o;
struct stream_volume *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index %d", c, idx);
o = pa_operation_new(c, NULL, do_stream_volume_mute, sizeof(struct stream_volume));
d = o->userdata;
@ -2361,6 +2388,8 @@ pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mu
pa_operation *o;
struct stream_volume *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index %d", c, idx);
o = pa_operation_new(c, NULL, do_stream_volume_mute, sizeof(struct stream_volume));
d = o->userdata;
@ -2414,6 +2443,8 @@ pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context
pa_operation *o;
struct kill_stream *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index %d", c, idx);
o = pa_operation_new(c, NULL, do_kill_stream, sizeof(struct kill_stream));
d = o->userdata;
@ -2547,6 +2578,7 @@ pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_
pa_assert(c->refcount >= 1);
pa_assert(cb);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
pw_log_debug("%p: index:%u", c, idx);
@ -2603,6 +2635,8 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx,
pa_operation *o;
struct target_node *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p index:%u name:%s", c, idx, source_name);
o = pa_operation_new(c, NULL, do_target_node, sizeof(struct target_node));
d = o->userdata;
@ -2624,6 +2658,8 @@ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx
pa_operation *o;
struct target_node *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p index:%u source_index:%u", c, idx, source_idx);
o = pa_operation_new(c, NULL, do_target_node, sizeof(struct target_node));
d = o->userdata;
@ -2645,6 +2681,8 @@ pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, c
pa_operation *o;
struct stream_volume *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index %d", c, idx);
o = pa_operation_new(c, NULL, do_stream_volume_mute, sizeof(struct stream_volume));
d = o->userdata;
@ -2665,6 +2703,8 @@ pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int
pa_operation *o;
struct stream_volume *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index %d", c, idx);
o = pa_operation_new(c, NULL, do_stream_volume_mute, sizeof(struct stream_volume));
d = o->userdata;
@ -2684,6 +2724,8 @@ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_cont
pa_operation *o;
struct kill_stream *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("context %p: index %d", c, idx);
o = pa_operation_new(c, NULL, do_kill_stream, sizeof(struct kill_stream));
d = o->userdata;
@ -2721,6 +2763,8 @@ pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdat
pa_operation *o;
struct stat_ack *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p", c);
o = pa_operation_new(c, NULL, on_stat_info, sizeof(struct stat_ack));
d = o->userdata;
@ -2755,6 +2799,8 @@ pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name
pa_operation *o;
struct sample_info *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p nane:%s", c, name);
o = pa_operation_new(c, NULL, on_sample_info, sizeof(struct sample_info));
d = o->userdata;
@ -2772,6 +2818,8 @@ pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, p
pa_operation *o;
struct sample_info *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p index:%u", c, idx);
o = pa_operation_new(c, NULL, on_sample_info, sizeof(struct sample_info));
d = o->userdata;
@ -2801,6 +2849,8 @@ pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t
pa_operation *o;
struct sample_info *d;
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pw_log_debug("%p", c);
o = pa_operation_new(c, NULL, on_sample_info_list, sizeof(struct sample_info));
d = o->userdata;

View file

@ -51,6 +51,7 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb
int pa_operation_sync(pa_operation *o)
{
pa_context *c = o->context;
if (c->core != NULL)
c->pending_seq = pw_core_sync(c->core, PW_ID_CORE, 0);
o->sync = true;
pw_log_debug("operation %p: sync seq:%d", o, c->pending_seq);