mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
rework initial connection
Make a steal_fd method on the remote. Add a hello method that sends the initial core info and types to the client. With an explicit method we can do this multiple times when we steal the fd from a remote and use it to make a new remote.
This commit is contained in:
parent
527f4683ba
commit
1c44629cf9
8 changed files with 84 additions and 18 deletions
|
|
@ -527,14 +527,19 @@ static int impl_connect(struct pw_protocol_client *client)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int impl_get_fd(struct pw_protocol_client *client)
|
||||
static int impl_steal_fd(struct pw_protocol_client *client)
|
||||
{
|
||||
struct client *impl = SPA_CONTAINER_OF(client, struct client, this);
|
||||
int fd;
|
||||
|
||||
if (impl->source == NULL)
|
||||
return -EIO;
|
||||
|
||||
return impl->source->fd;
|
||||
fd = dup(impl->source->fd);
|
||||
|
||||
pw_protocol_client_disconnect(client);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -636,6 +641,8 @@ static int impl_connect_fd(struct pw_protocol_client *client, int fd)
|
|||
struct client *impl = SPA_CONTAINER_OF(client, struct client, this);
|
||||
struct pw_remote *remote = client->remote;
|
||||
|
||||
impl->disconnecting = false;
|
||||
|
||||
impl->connection = pw_protocol_native_connection_new(fd);
|
||||
if (impl->connection == NULL)
|
||||
goto error_close;
|
||||
|
|
@ -707,7 +714,7 @@ impl_new_client(struct pw_protocol *protocol,
|
|||
impl->properties = properties ? pw_properties_copy(properties) : NULL;
|
||||
|
||||
this->connect = impl_connect;
|
||||
this->get_fd = impl_get_fd;
|
||||
this->steal_fd = impl_steal_fd;
|
||||
this->connect_fd = impl_connect_fd;
|
||||
this->disconnect = impl_disconnect;
|
||||
this->destroy = impl_destroy;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,18 @@
|
|||
|
||||
#include "connection.h"
|
||||
|
||||
static void core_marshal_hello(void *object)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_HELLO);
|
||||
|
||||
spa_pod_builder_struct(b, "P", NULL);
|
||||
|
||||
pw_protocol_native_end_proxy(proxy, b);
|
||||
}
|
||||
|
||||
static void core_marshal_client_update(void *object, const struct spa_dict *props)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
|
|
@ -403,6 +415,20 @@ static int core_demarshal_permissions(void *object, void *data, size_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int core_demarshal_hello(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
void *ptr;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs, "[P]", &ptr, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pw_resource_do(resource, struct pw_core_proxy_methods, hello);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int core_demarshal_sync(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -947,6 +973,7 @@ static void registry_marshal_bind(void *object, uint32_t id,
|
|||
|
||||
static const struct pw_core_proxy_methods pw_protocol_native_core_method_marshal = {
|
||||
PW_VERSION_CORE_PROXY_METHODS,
|
||||
&core_marshal_hello,
|
||||
&core_marshal_update_types_client,
|
||||
&core_marshal_sync,
|
||||
&core_marshal_get_registry,
|
||||
|
|
@ -956,6 +983,7 @@ static const struct pw_core_proxy_methods pw_protocol_native_core_method_marshal
|
|||
};
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_core_method_demarshal[PW_CORE_PROXY_METHOD_NUM] = {
|
||||
{ &core_demarshal_hello, 0, },
|
||||
{ &core_demarshal_update_types_server, 0, },
|
||||
{ &core_demarshal_sync, 0, },
|
||||
{ &core_demarshal_get_registry, 0, },
|
||||
|
|
|
|||
|
|
@ -99,6 +99,18 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = destroy_registry_resource
|
||||
};
|
||||
|
||||
static void core_hello(void *object)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct pw_core *this = resource->core;
|
||||
|
||||
pw_log_debug("core %p: hello from source %p", this, resource);
|
||||
resource->client->n_types = 0;
|
||||
|
||||
this->info.change_mask = PW_CORE_CHANGE_MASK_ALL;
|
||||
pw_core_resource_info(resource, &this->info);
|
||||
}
|
||||
|
||||
static void core_client_update(void *object, const struct spa_dict *props)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -248,6 +260,7 @@ static void core_update_types(void *object, uint32_t first_id, const char **type
|
|||
|
||||
static const struct pw_core_proxy_methods core_methods = {
|
||||
PW_VERSION_CORE_PROXY_METHODS,
|
||||
.hello = core_hello,
|
||||
.update_types = core_update_types,
|
||||
.sync = core_sync,
|
||||
.get_registry = core_get_registry,
|
||||
|
|
@ -295,8 +308,6 @@ core_bind_func(struct pw_global *global,
|
|||
|
||||
pw_log_debug("core %p: bound to %d", this, resource->id);
|
||||
|
||||
this->info.change_mask = PW_CORE_CHANGE_MASK_ALL;
|
||||
pw_core_resource_info(resource, &this->info);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,13 +66,14 @@ struct pw_link_proxy;
|
|||
|
||||
#define PW_VERSION_CORE 0
|
||||
|
||||
#define PW_CORE_PROXY_METHOD_UPDATE_TYPES 0
|
||||
#define PW_CORE_PROXY_METHOD_SYNC 1
|
||||
#define PW_CORE_PROXY_METHOD_GET_REGISTRY 2
|
||||
#define PW_CORE_PROXY_METHOD_CLIENT_UPDATE 3
|
||||
#define PW_CORE_PROXY_METHOD_PERMISSIONS 4
|
||||
#define PW_CORE_PROXY_METHOD_CREATE_OBJECT 5
|
||||
#define PW_CORE_PROXY_METHOD_NUM 6
|
||||
#define PW_CORE_PROXY_METHOD_HELLO 0
|
||||
#define PW_CORE_PROXY_METHOD_UPDATE_TYPES 1
|
||||
#define PW_CORE_PROXY_METHOD_SYNC 2
|
||||
#define PW_CORE_PROXY_METHOD_GET_REGISTRY 3
|
||||
#define PW_CORE_PROXY_METHOD_CLIENT_UPDATE 4
|
||||
#define PW_CORE_PROXY_METHOD_PERMISSIONS 5
|
||||
#define PW_CORE_PROXY_METHOD_CREATE_OBJECT 6
|
||||
#define PW_CORE_PROXY_METHOD_NUM 7
|
||||
|
||||
/**
|
||||
* Key to update default permissions of globals without specific
|
||||
|
|
@ -110,6 +111,11 @@ struct pw_link_proxy;
|
|||
struct pw_core_proxy_methods {
|
||||
#define PW_VERSION_CORE_PROXY_METHODS 0
|
||||
uint32_t version;
|
||||
/**
|
||||
* Start a conversation with the server. This will send
|
||||
* the core info and server types.
|
||||
*/
|
||||
void (*hello) (void *object);
|
||||
/**
|
||||
* Update the type map
|
||||
*
|
||||
|
|
@ -179,6 +185,12 @@ struct pw_core_proxy_methods {
|
|||
uint32_t new_id);
|
||||
};
|
||||
|
||||
static inline void
|
||||
pw_core_proxy_hello(struct pw_core_proxy *core)
|
||||
{
|
||||
pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, hello);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pw_core_proxy_update_types(struct pw_core_proxy *core, uint32_t first_id, const char **types, uint32_t n_types)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
static void do_stop(void *data, uint64_t count)
|
||||
{
|
||||
struct pw_main_loop *this = data;
|
||||
pw_log_debug("main-loop %p: do stop", this);
|
||||
this->running = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,14 +42,14 @@ struct pw_protocol_client {
|
|||
struct pw_remote *remote; /**< the associated remote */
|
||||
|
||||
int (*connect) (struct pw_protocol_client *client);
|
||||
int (*get_fd) (struct pw_protocol_client *client);
|
||||
int (*steal_fd) (struct pw_protocol_client *client);
|
||||
int (*connect_fd) (struct pw_protocol_client *client, int fd);
|
||||
void (*disconnect) (struct pw_protocol_client *client);
|
||||
void (*destroy) (struct pw_protocol_client *client);
|
||||
};
|
||||
|
||||
#define pw_protocol_client_connect(c) ((c)->connect(c))
|
||||
#define pw_protocol_client_get_fd(c) ((c)->get_fd(c))
|
||||
#define pw_protocol_client_steal_fd(c) ((c)->steal_fd(c))
|
||||
#define pw_protocol_client_connect_fd(c,fd) ((c)->connect_fd(c,fd))
|
||||
#define pw_protocol_client_disconnect(c) ((c)->disconnect(c))
|
||||
#define pw_protocol_client_destroy(c) ((c)->destroy(c))
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ static int do_connect(struct pw_remote *remote)
|
|||
|
||||
pw_core_proxy_add_listener(remote->core_proxy, &impl->core_listener, &core_proxy_events, remote);
|
||||
|
||||
pw_core_proxy_hello(remote->core_proxy);
|
||||
pw_core_proxy_client_update(remote->core_proxy, &remote->properties->dict);
|
||||
pw_core_proxy_sync(remote->core_proxy, 0);
|
||||
|
||||
|
|
@ -404,9 +405,14 @@ int pw_remote_connect_fd(struct pw_remote *remote, int fd)
|
|||
return do_connect(remote);
|
||||
}
|
||||
|
||||
int pw_remote_get_fd(struct pw_remote *remote)
|
||||
int pw_remote_steal_fd(struct pw_remote *remote)
|
||||
{
|
||||
return pw_protocol_client_get_fd(remote->conn);
|
||||
int fd;
|
||||
|
||||
fd = pw_protocol_client_steal_fd(remote->conn);
|
||||
pw_remote_update_state(remote, PW_REMOTE_STATE_UNCONNECTED, NULL);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int pw_remote_disconnect(struct pw_remote *remote)
|
||||
|
|
|
|||
|
|
@ -178,8 +178,9 @@ int pw_remote_connect(struct pw_remote *remote);
|
|||
* \return 0 on success, < 0 on error */
|
||||
int pw_remote_connect_fd(struct pw_remote *remote, int fd);
|
||||
|
||||
/** Get the fd of the remote connection or < 0 on error */
|
||||
int pw_remote_get_fd(struct pw_remote *remote);
|
||||
/** Steal the fd of the remote connection or < 0 on error. The remote
|
||||
* will be in the unconnected state after this call. */
|
||||
int pw_remote_steal_fd(struct pw_remote *remote);
|
||||
|
||||
/** Get the core proxy, can only be called when connected */
|
||||
struct pw_core_proxy * pw_remote_get_core_proxy(struct pw_remote *remote);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue