From 5abda63a1fa4d2c867af8b33b0090cd651ba8599 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 15 Jan 2009 17:52:29 +0100 Subject: convert pa_client instantiation to use a pa_client_new_data struct and add hooks for manipulating it --- src/pulsecore/cli.c | 19 ++++++++++++++++--- src/pulsecore/client.c | 38 ++++++++++++++++++++++++++++++-------- src/pulsecore/client.h | 14 ++++++++++++-- src/pulsecore/core.h | 3 +++ src/pulsecore/protocol-esound.c | 22 ++++++++++++++++------ src/pulsecore/protocol-native.c | 22 ++++++++++++++++------ src/pulsecore/protocol-simple.c | 18 +++++++++++++----- 7 files changed, 106 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/pulsecore/cli.c b/src/pulsecore/cli.c index 67bf1e73..25a4f748 100644 --- a/src/pulsecore/cli.c +++ b/src/pulsecore/cli.c @@ -67,20 +67,33 @@ static void client_kill(pa_client *c); pa_cli* pa_cli_new(pa_core *core, pa_iochannel *io, pa_module *m) { char cname[256]; pa_cli *c; + pa_client_new_data data; + pa_client *client; + pa_assert(io); + pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname)); + + pa_client_new_data_init(&data); + data.driver = __FILE__; + data.module = m; + pa_proplist_sets(data.proplist, PA_PROP_APPLICATION_NAME, cname); + client = pa_client_new(core, &data); + pa_client_new_data_done(&data); + + if (!client) + return NULL; + c = pa_xnew(pa_cli, 1); c->core = core; + c->client = client; pa_assert_se(c->line = pa_ioline_new(io)); c->userdata = NULL; c->eof_callback = NULL; - pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname)); - pa_assert_se(c->client = pa_client_new(core, __FILE__, cname)); c->client->kill = client_kill; c->client->userdata = c; - c->client->module = m; pa_ioline_set_callback(c->line, line_callback, c); pa_ioline_puts(c->line, "Welcome to PulseAudio! Use \"help\" for usage information.\n"PROMPT); diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c index ab6e5df4..31631e1f 100644 --- a/src/pulsecore/client.c +++ b/src/pulsecore/client.c @@ -37,27 +37,46 @@ #include "client.h" -pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) { +pa_client_new_data* pa_client_new_data_init(pa_client_new_data *data) { + pa_assert(data); + + memset(data, 0, sizeof(*data)); + data->proplist = pa_proplist_new(); + + return data; +} + +void pa_client_new_data_done(pa_client_new_data *data) { + pa_assert(data); + + pa_proplist_free(data->proplist); +} + +pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) { pa_client *c; pa_core_assert_ref(core); + pa_assert(data); + + if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_NEW], data) < 0) + return NULL; c = pa_xnew(pa_client, 1); c->core = core; - c->proplist = pa_proplist_new(); - if (name) - pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name); - c->driver = pa_xstrdup(driver); - c->module = NULL; + c->proplist = pa_proplist_copy(data->proplist); + c->driver = pa_xstrdup(data->driver); + c->module = data->module; - c->kill = NULL; c->userdata = NULL; + c->kill = NULL; pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0); - pa_log_info("Created %u \"%s\"", c->index, pa_strnull(name)); + pa_log_info("Created %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME))); pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); + pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_PUT], c); + pa_core_check_idle(core); return c; @@ -69,11 +88,14 @@ void pa_client_free(pa_client *c) { pa_assert(c); pa_assert(c->core); + pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], c); + core = c->core; pa_idxset_remove_by_data(c->core->clients, c, NULL); pa_log_info("Freed %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME))); pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index); + pa_proplist_free(c->proplist); pa_xfree(c->driver); pa_xfree(c); diff --git a/src/pulsecore/client.h b/src/pulsecore/client.h index 28d1fe5f..8e72f323 100644 --- a/src/pulsecore/client.h +++ b/src/pulsecore/client.h @@ -42,11 +42,21 @@ struct pa_client { pa_module *module; char *driver; - void (*kill)(pa_client *c); void *userdata; + + void (*kill)(pa_client *c); }; -pa_client *pa_client_new(pa_core *c, const char *driver, const char *name); +typedef struct pa_client_new_data { + pa_proplist *proplist; + const char *driver; + pa_module *module; +} pa_client_new_data; + +pa_client_new_data *pa_client_new_data_init(pa_client_new_data *data); +void pa_client_new_data_done(pa_client_new_data *data); + +pa_client *pa_client_new(pa_core *c, pa_client_new_data *data); /* This function should be called only by the code that created the client */ void pa_client_free(pa_client *c); diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index f796fb93..f1f38ef1 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -76,6 +76,9 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST, PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED, PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED, + PA_CORE_HOOK_CLIENT_NEW, + PA_CORE_HOOK_CLIENT_PUT, + PA_CORE_HOOK_CLIENT_UNLINK, PA_CORE_HOOK_MAX } pa_core_hook_t; diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 2f014827..6524b684 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -1377,7 +1377,9 @@ static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timev void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esound_options *o) { connection *c; - char cname[256], pname[128]; + char pname[128]; + pa_client_new_data data; + pa_client *client; pa_assert(p); pa_assert(io); @@ -1389,6 +1391,18 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou return; } + pa_client_new_data_init(&data); + data.module = o->module; + data.driver = __FILE__; + pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); + pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "EsounD client (%s)", pname); + pa_proplist_sets(data.proplist, "esound-protocol.peer", pname); + client = pa_client_new(p->core, &data); + pa_client_new_data_done(&data); + + if (!client) + return; + c = pa_msgobject_new(connection); c->parent.parent.free = connection_free; c->parent.process_msg = connection_process_msg; @@ -1396,11 +1410,7 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou c->io = io; pa_iochannel_set_callback(c->io, io_callback, c); - pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - pa_snprintf(cname, sizeof(cname), "EsounD client (%s)", pname); - c->client = pa_client_new(p->core, __FILE__, cname); - pa_proplist_sets(c->client->proplist, "esound-protocol.peer", pname); - c->client->module = o->module; + c->client = client; c->client->kill = client_kill_cb; c->client->userdata = c; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 7cce3db0..d99e212f 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -4214,7 +4214,9 @@ static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timev void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *o) { pa_native_connection *c; - char cname[256], pname[128]; + char pname[128]; + pa_client *client; + pa_client_new_data data; pa_assert(p); pa_assert(io); @@ -4226,6 +4228,18 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati return; } + pa_client_new_data_init(&data); + data.module = o->module; + data.driver = __FILE__; + pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); + pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "Native client (%s)", pname); + pa_proplist_sets(data.proplist, "native-protocol.peer", pname); + client = pa_client_new(p->core, &data); + pa_client_new_data_done(&data); + + if (!client) + return; + c = pa_msgobject_new(pa_native_connection); c->parent.parent.free = native_connection_free; c->parent.process_msg = native_connection_process_msg; @@ -4257,13 +4271,9 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati c->is_local = pa_iochannel_socket_is_local(io); c->version = 8; - pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - pa_snprintf(cname, sizeof(cname), "Native client (%s)", pname); - c->client = pa_client_new(p->core, __FILE__, cname); - pa_proplist_sets(c->client->proplist, "native-protocol.peer", pname); + c->client = client; c->client->kill = client_kill_cb; c->client->userdata = c; - c->client->module = o->module; c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool); pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c); diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 9c4a5386..a754669c 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -476,7 +476,8 @@ static void io_callback(pa_iochannel*io, void *userdata) { void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simple_options *o) { connection *c = NULL; - char cname[256], pname[128]; + char pname[128]; + pa_client_new_data client_data; pa_assert(p); pa_assert(io); @@ -505,11 +506,18 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp c->playback.underrun = TRUE; pa_atomic_store(&c->playback.missing, 0); + pa_client_new_data_init(&client_data); + client_data.module = o->module; + client_data.driver = __FILE__; pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - pa_snprintf(cname, sizeof(cname), "Simple client (%s)", pname); - pa_assert_se(c->client = pa_client_new(p->core, __FILE__, cname)); - pa_proplist_sets(c->client->proplist, "simple-protocol.peer", pname); - c->client->module = o->module; + pa_proplist_setf(client_data.proplist, PA_PROP_APPLICATION_NAME, "Simple client (%s)", pname); + pa_proplist_sets(client_data.proplist, "simple-protocol.peer", pname); + c->client = pa_client_new(p->core, &client_data); + pa_client_new_data_done(&client_data); + + if (!c->client) + goto fail; + c->client->kill = client_kill_cb; c->client->userdata = c; -- cgit