mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
protocol-native: always create a local server
Always create a local server without any socket. We can use this to create clients that connect locally (in-process), such as the cli or any app that wants to create a local pipeline.
This commit is contained in:
parent
8917e1e149
commit
c0f5e8d967
3 changed files with 101 additions and 23 deletions
|
|
@ -75,6 +75,8 @@ struct protocol_data {
|
|||
struct pw_module *module;
|
||||
struct spa_hook module_listener;
|
||||
struct pw_protocol *protocol;
|
||||
|
||||
struct server *local;
|
||||
};
|
||||
|
||||
struct client {
|
||||
|
|
@ -317,7 +319,7 @@ static const struct pw_protocol_native_connection_events server_conn_events = {
|
|||
.start = on_start,
|
||||
};
|
||||
|
||||
static struct pw_client *client_new(struct server *s, int fd)
|
||||
static struct client_data *client_new(struct server *s, int fd)
|
||||
{
|
||||
struct client_data *this;
|
||||
struct pw_client *client;
|
||||
|
|
@ -360,6 +362,7 @@ static struct pw_client *client_new(struct server *s, int fd)
|
|||
if (client == NULL)
|
||||
goto exit;
|
||||
|
||||
|
||||
this = pw_client_get_user_data(client);
|
||||
client->protocol = protocol;
|
||||
spa_list_append(&s->this.client_list, &client->protocol_link);
|
||||
|
|
@ -391,7 +394,11 @@ static struct pw_client *client_new(struct server *s, int fd)
|
|||
if ((res = pw_client_register(client, NULL)) < 0)
|
||||
goto cleanup_client;
|
||||
|
||||
return client;
|
||||
if (!client->busy)
|
||||
pw_loop_update_io(pw_core_get_main_loop(core),
|
||||
this->source, this->source->mask | SPA_IO_IN);
|
||||
|
||||
return this;
|
||||
|
||||
cleanup_client:
|
||||
pw_client_destroy(client);
|
||||
|
|
@ -472,8 +479,7 @@ static void
|
|||
socket_data(void *data, int fd, uint32_t mask)
|
||||
{
|
||||
struct server *s = data;
|
||||
struct pw_client *client;
|
||||
struct client_data *c;
|
||||
struct client_data *client;
|
||||
struct sockaddr_un name;
|
||||
socklen_t length;
|
||||
int client_fd;
|
||||
|
|
@ -491,11 +497,6 @@ socket_data(void *data, int fd, uint32_t mask)
|
|||
close(client_fd);
|
||||
return;
|
||||
}
|
||||
c = client->user_data;
|
||||
|
||||
if (!client->busy)
|
||||
pw_loop_update_io(client->protocol->core->main_loop,
|
||||
c->source, c->source->mask | SPA_IO_IN);
|
||||
}
|
||||
|
||||
static int add_socket(struct pw_protocol *protocol, struct server *s)
|
||||
|
|
@ -764,9 +765,52 @@ static void impl_destroy(struct pw_protocol_client *client)
|
|||
free(impl);
|
||||
}
|
||||
|
||||
static int pw_protocol_native_connect_internal(struct pw_protocol_client *client,
|
||||
const struct spa_dict *props,
|
||||
void (*done_callback) (void *data, int res),
|
||||
void *data)
|
||||
{
|
||||
int res, sv[2];
|
||||
struct pw_protocol *protocol = client->protocol;
|
||||
struct protocol_data *d = pw_protocol_get_user_data(protocol);
|
||||
struct server *s = d->local;
|
||||
struct pw_permission permissions[1];
|
||||
struct client_data *c;
|
||||
|
||||
pw_log_debug("server %p: internal connect", s);
|
||||
|
||||
if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, sv) < 0) {
|
||||
res = -errno;
|
||||
pw_log_error("server %p: socketpair() failed with error: %m", s);
|
||||
goto error;
|
||||
}
|
||||
|
||||
c = client_new(s, sv[0]);
|
||||
if (c == NULL) {
|
||||
res = -errno;
|
||||
pw_log_error("server %p: failed to create client: %m", s);
|
||||
goto error_close;
|
||||
}
|
||||
permissions[0].id = SPA_ID_INVALID;
|
||||
permissions[0].permissions = PW_PERM_RWX;
|
||||
pw_client_update_permissions(c->client, 1, permissions);
|
||||
|
||||
res = pw_protocol_client_connect_fd(client, sv[1], true);
|
||||
done:
|
||||
if (done_callback)
|
||||
done_callback(data, res);
|
||||
return res;
|
||||
|
||||
error_close:
|
||||
close(sv[0]);
|
||||
close(sv[1]);
|
||||
error:
|
||||
goto done;
|
||||
}
|
||||
|
||||
static struct pw_protocol_client *
|
||||
impl_new_client(struct pw_protocol *protocol,
|
||||
struct pw_properties *properties)
|
||||
const struct pw_properties *properties)
|
||||
{
|
||||
struct client *impl;
|
||||
struct pw_protocol_client *this;
|
||||
|
|
@ -776,6 +820,8 @@ impl_new_client(struct pw_protocol *protocol,
|
|||
if ((impl = calloc(1, sizeof(struct client))) == NULL)
|
||||
return NULL;
|
||||
|
||||
pw_log_debug(NAME" %p: new client %p", protocol, impl);
|
||||
|
||||
this = &impl->this;
|
||||
this->protocol = protocol;
|
||||
|
||||
|
|
@ -786,13 +832,22 @@ impl_new_client(struct pw_protocol *protocol,
|
|||
goto error_free;
|
||||
}
|
||||
|
||||
if (properties)
|
||||
if (properties) {
|
||||
str = pw_properties_get(properties, PW_KEY_REMOTE_INTENTION);
|
||||
if (str == NULL &&
|
||||
(str = pw_properties_get(properties, PW_KEY_REMOTE_NAME)) != NULL &&
|
||||
strcmp(str, impl->core->info.name) == 0)
|
||||
str = "internal";
|
||||
}
|
||||
if (str == NULL)
|
||||
str = "generic";
|
||||
|
||||
pw_log_debug(NAME" %p: connect %s", protocol, str);
|
||||
|
||||
if (!strcmp(str, "screencast"))
|
||||
this->connect = pw_protocol_native_connect_portal_screencast;
|
||||
else if (!strcmp(str, "internal"))
|
||||
this->connect = pw_protocol_native_connect_internal;
|
||||
else
|
||||
this->connect = pw_protocol_native_connect_local_socket;
|
||||
|
||||
|
|
@ -880,15 +935,13 @@ get_name(const struct pw_properties *properties)
|
|||
return name;
|
||||
}
|
||||
|
||||
static struct pw_protocol_server *
|
||||
impl_add_server(struct pw_protocol *protocol,
|
||||
struct pw_properties *properties)
|
||||
static struct server *
|
||||
create_server(struct pw_protocol *protocol,
|
||||
const struct pw_properties *properties)
|
||||
{
|
||||
struct pw_protocol_server *this;
|
||||
struct pw_core *core = protocol->core;
|
||||
struct server *s;
|
||||
const char *name;
|
||||
int res;
|
||||
|
||||
if ((s = calloc(1, sizeof(struct server))) == NULL)
|
||||
return NULL;
|
||||
|
|
@ -902,10 +955,29 @@ impl_add_server(struct pw_protocol *protocol,
|
|||
|
||||
spa_list_append(&protocol->server_list, &this->link);
|
||||
|
||||
name = get_name(pw_core_get_properties(core));
|
||||
|
||||
pw_loop_add_hook(pw_core_get_main_loop(core), &s->hook, &impl_hooks, s);
|
||||
|
||||
pw_log_info(NAME" %p: created server %p", protocol, this);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static struct pw_protocol_server *
|
||||
impl_add_server(struct pw_protocol *protocol,
|
||||
const struct pw_properties *properties)
|
||||
{
|
||||
struct pw_protocol_server *this;
|
||||
struct server *s;
|
||||
const char *name;
|
||||
int res;
|
||||
|
||||
if ((s = create_server(protocol, properties)) == NULL)
|
||||
return NULL;
|
||||
|
||||
this = &s->this;
|
||||
|
||||
name = get_name(properties);
|
||||
|
||||
if ((res = init_socket_name(s, name)) < 0)
|
||||
goto error;
|
||||
|
||||
|
|
@ -915,7 +987,7 @@ impl_add_server(struct pw_protocol *protocol,
|
|||
if ((res = add_socket(protocol, s)) < 0)
|
||||
goto error;
|
||||
|
||||
pw_log_info(NAME" %p: Added server %p %s", protocol, this, name);
|
||||
pw_log_info(NAME" %p: Listening on '%s'", protocol, name);
|
||||
|
||||
return this;
|
||||
|
||||
|
|
@ -1017,6 +1089,7 @@ int pipewire__module_init(struct pw_module *module, const char *args)
|
|||
struct pw_protocol *this;
|
||||
const char *val;
|
||||
struct protocol_data *d;
|
||||
const struct pw_properties *props;
|
||||
int res;
|
||||
|
||||
if (pw_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native) != NULL)
|
||||
|
|
@ -1040,11 +1113,15 @@ int pipewire__module_init(struct pw_module *module, const char *args)
|
|||
d->protocol = this;
|
||||
d->module = module;
|
||||
|
||||
d->local = create_server(this, props);
|
||||
|
||||
props = pw_core_get_properties(core);
|
||||
|
||||
val = getenv("PIPEWIRE_DAEMON");
|
||||
if (val == NULL)
|
||||
val = pw_properties_get(pw_core_get_properties(core), PW_KEY_CORE_DAEMON);
|
||||
val = pw_properties_get(props, PW_KEY_CORE_DAEMON);
|
||||
if (val && pw_properties_parse_bool(val)) {
|
||||
if (impl_add_server(this, NULL) == NULL) {
|
||||
if (impl_add_server(this, props) == NULL) {
|
||||
res = -errno;
|
||||
goto error_cleanup;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ static struct pw_core_proxy *core_proxy_new(struct pw_core *core,
|
|||
res = -errno;
|
||||
goto exit_cleanup;
|
||||
}
|
||||
pw_log_debug(NAME" %p: new", p);
|
||||
|
||||
if (properties == NULL)
|
||||
properties = pw_properties_new(NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ struct pw_protocol_implementaton {
|
|||
uint32_t version;
|
||||
|
||||
struct pw_protocol_client * (*new_client) (struct pw_protocol *protocol,
|
||||
struct pw_properties *properties);
|
||||
const struct pw_properties *properties);
|
||||
struct pw_protocol_server * (*add_server) (struct pw_protocol *protocol,
|
||||
struct pw_properties *properties);
|
||||
const struct pw_properties *properties);
|
||||
};
|
||||
|
||||
struct pw_protocol_events {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue