diff options
author | Wim Taymans <wtaymans@redhat.com> | 2017-02-15 09:49:21 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2017-02-15 10:00:39 +0100 |
commit | 833f5e6592da388f457c7fde8d3d9a9040384762 (patch) | |
tree | d3080e0055691514ab636881ade6bf1c2b6fb829 | |
parent | d90b38844ce62eef8c589fb51d2641afa858995d (diff) |
protocol-native: keep track of pending access checksaccess-hooks-core
Keep track of pending access checks and cancel/free them when the
connection is unlinked.
We don't need to keep a ref to the pdispatch object anymore now.
-rw-r--r-- | src/pulsecore/protocol-native.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 30c4fcdb5..766451953 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -168,6 +168,17 @@ typedef struct upload_stream { #define UPLOAD_STREAM(o) (upload_stream_cast(o)) PA_DEFINE_PRIVATE_CLASS(upload_stream, output_stream); +struct native_access_data { + pa_access_data d; + + pa_pdispatch *pdispatch; + PA_LLIST_FIELDS(struct native_access_data); + uint32_t command; + uint32_t tag; + pa_tagstruct *tagstruct; + pa_native_connection *connection; +}; + struct pa_native_connection { pa_msgobject parent; pa_native_protocol *protocol; @@ -189,11 +200,21 @@ struct pa_native_connection { pa_subscription *subscription; pa_time_event *auth_timeout_event; pa_srbchannel *srbpending; + PA_LLIST_HEAD(struct native_access_data, access_datas); }; #define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o)) PA_DEFINE_PRIVATE_CLASS(pa_native_connection, pa_msgobject); +static void access_data_free(struct native_access_data *data) { + PA_LLIST_REMOVE(struct native_access_data, data->connection->access_datas, data); + if (data->d.free_cb) + data->d.free_cb(data->d.userdata); + if (data->tagstruct) + pa_tagstruct_free(data->tagstruct); + pa_xfree(data); +}; + struct pa_native_protocol { PA_REFCNT_DECLARE; @@ -1188,6 +1209,9 @@ static void native_connection_unlink(pa_native_connection *c) { if (c->srbpending) pa_srbchannel_free(c->srbpending); + while (c->access_datas) + access_data_free(c->access_datas); + while ((r = pa_idxset_first(c->record_streams, NULL))) record_stream_unlink(r); @@ -4850,24 +4874,6 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, pa_pstream_send_simple_ack(c->pstream, tag); } -typedef struct native_access_data { - pa_access_data d; - - pa_pdispatch *pd; - uint32_t command; - uint32_t tag; - pa_tagstruct *tagstruct; - pa_native_connection *connection; -} native_access_data; - -static void access_data_free(native_access_data *data) { - if (data->pd) - pa_pdispatch_unref(data->pd); - if (data->tagstruct) - pa_tagstruct_free(data->tagstruct); - pa_xfree(data); -} - static const pa_pdispatch_cb_t access_granted_table[PA_COMMAND_MAX] = { [PA_COMMAND_CREATE_PLAYBACK_STREAM] = command_create_playback_stream, [PA_COMMAND_CREATE_RECORD_STREAM] = command_create_record_stream, @@ -4876,7 +4882,7 @@ static const pa_pdispatch_cb_t access_granted_table[PA_COMMAND_MAX] = { }; static void check_access_complete_cb(pa_access_data *data, pa_access_result_t res) { - native_access_data *d = (native_access_data *) data; + struct native_access_data *d = (struct native_access_data *) data; pa_native_connection *c = d->connection; uint32_t command, tag; @@ -4887,7 +4893,7 @@ static void check_access_complete_cb(pa_access_data *data, pa_access_result_t re goto finish; } - access_granted_table[d->command](d->pd, d->command, d->tag, d->tagstruct, d->connection); + access_granted_table[d->command](d->pdispatch, d->command, d->tag, d->tagstruct, d->connection); finish: access_data_free(d); @@ -4902,7 +4908,7 @@ static const pa_access_hook_t access_table[PA_COMMAND_MAX] = { static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); - native_access_data *data; + struct native_access_data *data; pa_access_result_t res; pa_native_connection_assert_ref(c); @@ -4912,7 +4918,7 @@ static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t ta return; } - data = pa_xnew0 (native_access_data, 1); + data = pa_xnew0 (struct native_access_data, 1); data->d.client_index = c->client->index; data->d.object_index = PA_INVALID_INDEX; data->d.event = 0; @@ -4923,11 +4929,12 @@ static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t ta if (res == PA_ACCESS_ASYNC_CHECK) { /* async, take a copy of the current state and wait for complete_cb */ data->d.complete_cb = check_access_complete_cb; - data->pd = pd ? pa_pdispatch_ref (pd) : NULL; + data->pdispatch = pd; data->command = command; data->tag = tag; data->tagstruct = t ? pa_tagstruct_copy (t) : NULL; data->connection = c; + PA_LLIST_PREPEND(struct native_access_data, c->access_datas, data); } else if (res == PA_ACCESS_DENIED) { pa_xfree(data); pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS); @@ -5262,6 +5269,8 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati c->authorized = false; c->srbpending = NULL; + PA_LLIST_HEAD_INIT(struct native_access_data, c->access_datas); + if (o->auth_anonymous) { pa_log_info("Client authenticated anonymously."); c->authorized = true; |