mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	interfaces: add event to notify of global bound id
Make it possible to know when a proxy is bound to a global id before the global shows up in the registry. This makes it possible to match locally created objects to the one appearing in the registry and possibly avoid a second bind.
This commit is contained in:
		
							parent
							
								
									b264ef0772
								
							
						
					
					
						commit
						f56e4dbc4d
					
				
					 8 changed files with 81 additions and 3 deletions
				
			
		| 
						 | 
					@ -337,6 +337,21 @@ static int core_event_demarshal_remove_id(void *object, const struct pw_protocol
 | 
				
			||||||
	return pw_proxy_notify(proxy, struct pw_core_proxy_events, remove_id, 0, id);
 | 
						return pw_proxy_notify(proxy, struct pw_core_proxy_events, remove_id, 0, id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int core_event_demarshal_bound_id(void *object, const struct pw_protocol_native_message *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pw_proxy *proxy = object;
 | 
				
			||||||
 | 
						struct spa_pod_parser prs;
 | 
				
			||||||
 | 
						uint32_t id, global_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_pod_parser_init(&prs, msg->data, msg->size);
 | 
				
			||||||
 | 
						if (spa_pod_parser_get_struct(&prs,
 | 
				
			||||||
 | 
									SPA_POD_Int(&id),
 | 
				
			||||||
 | 
									SPA_POD_Int(&global_id)) < 0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return pw_proxy_notify(proxy, struct pw_core_proxy_events, bound_id, 0, id, global_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int core_event_demarshal_add_mem(void *object, const struct pw_protocol_native_message *msg)
 | 
					static int core_event_demarshal_add_mem(void *object, const struct pw_protocol_native_message *msg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_proxy *proxy = object;
 | 
						struct pw_proxy *proxy = object;
 | 
				
			||||||
| 
						 | 
					@ -454,6 +469,20 @@ static void core_event_marshal_remove_id(void *object, uint32_t id)
 | 
				
			||||||
	pw_protocol_native_end_resource(resource, b);
 | 
						pw_protocol_native_end_resource(resource, b);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void core_event_marshal_bound_id(void *object, uint32_t id, uint32_t global_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pw_resource *resource = object;
 | 
				
			||||||
 | 
						struct spa_pod_builder *b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_BOUND_ID, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_pod_builder_add_struct(b,
 | 
				
			||||||
 | 
								SPA_POD_Int(id),
 | 
				
			||||||
 | 
								SPA_POD_Int(global_id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pw_protocol_native_end_resource(resource, b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void core_event_marshal_add_mem(void *object, uint32_t id, uint32_t type, int fd, uint32_t flags)
 | 
					static void core_event_marshal_add_mem(void *object, uint32_t id, uint32_t type, int fd, uint32_t flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_resource *resource = object;
 | 
						struct pw_resource *resource = object;
 | 
				
			||||||
| 
						 | 
					@ -1894,6 +1923,7 @@ static const struct pw_core_proxy_events pw_protocol_native_core_event_marshal =
 | 
				
			||||||
	.ping = &core_event_marshal_ping,
 | 
						.ping = &core_event_marshal_ping,
 | 
				
			||||||
	.error = &core_event_marshal_error,
 | 
						.error = &core_event_marshal_error,
 | 
				
			||||||
	.remove_id = &core_event_marshal_remove_id,
 | 
						.remove_id = &core_event_marshal_remove_id,
 | 
				
			||||||
 | 
						.bound_id = &core_event_marshal_bound_id,
 | 
				
			||||||
	.add_mem = &core_event_marshal_add_mem,
 | 
						.add_mem = &core_event_marshal_add_mem,
 | 
				
			||||||
	.remove_mem = &core_event_marshal_remove_mem,
 | 
						.remove_mem = &core_event_marshal_remove_mem,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1906,6 +1936,7 @@ pw_protocol_native_core_event_demarshal[PW_CORE_PROXY_EVENT_NUM] =
 | 
				
			||||||
	[PW_CORE_PROXY_EVENT_PING] = { &core_event_demarshal_ping, 0, },
 | 
						[PW_CORE_PROXY_EVENT_PING] = { &core_event_demarshal_ping, 0, },
 | 
				
			||||||
	[PW_CORE_PROXY_EVENT_ERROR] = { &core_event_demarshal_error, 0, },
 | 
						[PW_CORE_PROXY_EVENT_ERROR] = { &core_event_demarshal_error, 0, },
 | 
				
			||||||
	[PW_CORE_PROXY_EVENT_REMOVE_ID] = { &core_event_demarshal_remove_id, 0, },
 | 
						[PW_CORE_PROXY_EVENT_REMOVE_ID] = { &core_event_demarshal_remove_id, 0, },
 | 
				
			||||||
 | 
						[PW_CORE_PROXY_EVENT_BOUND_ID] = { &core_event_demarshal_bound_id, 0, },
 | 
				
			||||||
	[PW_CORE_PROXY_EVENT_ADD_MEM] = { &core_event_demarshal_add_mem, 0, },
 | 
						[PW_CORE_PROXY_EVENT_ADD_MEM] = { &core_event_demarshal_add_mem, 0, },
 | 
				
			||||||
	[PW_CORE_PROXY_EVENT_REMOVE_MEM] = { &core_event_demarshal_remove_mem, 0, },
 | 
						[PW_CORE_PROXY_EVENT_REMOVE_MEM] = { &core_event_demarshal_remove_mem, 0, },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,9 +83,10 @@ struct pw_link_proxy { struct spa_interface iface; };
 | 
				
			||||||
#define PW_CORE_PROXY_EVENT_PING	2
 | 
					#define PW_CORE_PROXY_EVENT_PING	2
 | 
				
			||||||
#define PW_CORE_PROXY_EVENT_ERROR	3
 | 
					#define PW_CORE_PROXY_EVENT_ERROR	3
 | 
				
			||||||
#define PW_CORE_PROXY_EVENT_REMOVE_ID	4
 | 
					#define PW_CORE_PROXY_EVENT_REMOVE_ID	4
 | 
				
			||||||
#define PW_CORE_PROXY_EVENT_ADD_MEM	5
 | 
					#define PW_CORE_PROXY_EVENT_BOUND_ID	5
 | 
				
			||||||
#define PW_CORE_PROXY_EVENT_REMOVE_MEM	6
 | 
					#define PW_CORE_PROXY_EVENT_ADD_MEM	6
 | 
				
			||||||
#define PW_CORE_PROXY_EVENT_NUM		7
 | 
					#define PW_CORE_PROXY_EVENT_REMOVE_MEM	7
 | 
				
			||||||
 | 
					#define PW_CORE_PROXY_EVENT_NUM		8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** \struct pw_core_proxy_events
 | 
					/** \struct pw_core_proxy_events
 | 
				
			||||||
 *  \brief Core events
 | 
					 *  \brief Core events
 | 
				
			||||||
| 
						 | 
					@ -152,6 +153,18 @@ struct pw_core_proxy_events {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	void (*remove_id) (void *object, uint32_t id);
 | 
						void (*remove_id) (void *object, uint32_t id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Notify an object binding
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * This event is emited when a local object ID is bound to a
 | 
				
			||||||
 | 
						 * global ID. It is emited before the global becomes visible in the
 | 
				
			||||||
 | 
						 * registry.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * \param id bound object ID
 | 
				
			||||||
 | 
						 * \param global_id the global id bound to
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						void (*bound_id) (void *object, uint32_t id, uint32_t global_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Add memory for a client
 | 
						 * Add memory for a client
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,6 +180,7 @@ struct pw_global {
 | 
				
			||||||
#define pw_core_resource_ping(r,...)		pw_core_resource(r,ping,0,__VA_ARGS__)
 | 
					#define pw_core_resource_ping(r,...)		pw_core_resource(r,ping,0,__VA_ARGS__)
 | 
				
			||||||
#define pw_core_resource_error(r,...)		pw_core_resource(r,error,0,__VA_ARGS__)
 | 
					#define pw_core_resource_error(r,...)		pw_core_resource(r,error,0,__VA_ARGS__)
 | 
				
			||||||
#define pw_core_resource_remove_id(r,...)	pw_core_resource(r,remove_id,0,__VA_ARGS__)
 | 
					#define pw_core_resource_remove_id(r,...)	pw_core_resource(r,remove_id,0,__VA_ARGS__)
 | 
				
			||||||
 | 
					#define pw_core_resource_bound_id(r,...)	pw_core_resource(r,bound_id,0,__VA_ARGS__)
 | 
				
			||||||
#define pw_core_resource_add_mem(r,...)		pw_core_resource(r,add_mem,0,__VA_ARGS__)
 | 
					#define pw_core_resource_add_mem(r,...)		pw_core_resource(r,add_mem,0,__VA_ARGS__)
 | 
				
			||||||
#define pw_core_resource_remove_mem(r,...)	pw_core_resource(r,remove_mem,0,__VA_ARGS__)
 | 
					#define pw_core_resource_remove_mem(r,...)	pw_core_resource(r,remove_mem,0,__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -705,6 +706,7 @@ struct pw_resource {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define pw_proxy_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_proxy_events, m, v, ##__VA_ARGS__)
 | 
					#define pw_proxy_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_proxy_events, m, v, ##__VA_ARGS__)
 | 
				
			||||||
#define pw_proxy_emit_destroy(p)	pw_proxy_emit(p, destroy, 0)
 | 
					#define pw_proxy_emit_destroy(p)	pw_proxy_emit(p, destroy, 0)
 | 
				
			||||||
 | 
					#define pw_proxy_emit_bound(p,g)	pw_proxy_emit(p, bound, 0, g)
 | 
				
			||||||
#define pw_proxy_emit_done(p,s)		pw_proxy_emit(p, done, 0, s)
 | 
					#define pw_proxy_emit_done(p,s)		pw_proxy_emit(p, done, 0, s)
 | 
				
			||||||
#define pw_proxy_emit_error(p,s,r,m)	pw_proxy_emit(p, error, 0, s, r, m)
 | 
					#define pw_proxy_emit_error(p,s,r,m)	pw_proxy_emit(p, error, 0, s, r, m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,6 +111,9 @@ struct pw_proxy_events {
 | 
				
			||||||
	/** The proxy is destroyed */
 | 
						/** The proxy is destroyed */
 | 
				
			||||||
        void (*destroy) (void *data);
 | 
					        void (*destroy) (void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** a proxy is bound to a global id */
 | 
				
			||||||
 | 
					        void (*bound) (void *data, uint32_t global_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** a reply to a sync method completed */
 | 
						/** a reply to a sync method completed */
 | 
				
			||||||
        void (*done) (void *data, int seq);
 | 
					        void (*done) (void *data, int seq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,6 +145,17 @@ static void core_event_remove_id(void *data, uint32_t id)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void core_event_bound_id(void *data, uint32_t id, uint32_t global_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pw_remote *this = data;
 | 
				
			||||||
 | 
						struct pw_proxy *proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pw_log_debug(NAME" %p: proxy %u bound %u", this, id, global_id);
 | 
				
			||||||
 | 
						if ((proxy = pw_map_lookup(&this->objects, id)) != NULL) {
 | 
				
			||||||
 | 
							pw_proxy_emit_bound(proxy, global_id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void core_event_add_mem(void *data, uint32_t id, uint32_t type, int fd, uint32_t flags)
 | 
					static void core_event_add_mem(void *data, uint32_t id, uint32_t type, int fd, uint32_t flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_remote *this = data;
 | 
						struct pw_remote *this = data;
 | 
				
			||||||
| 
						 | 
					@ -173,6 +184,7 @@ static const struct pw_core_proxy_events core_events = {
 | 
				
			||||||
	.ping = core_event_ping,
 | 
						.ping = core_event_ping,
 | 
				
			||||||
	.done = core_event_done,
 | 
						.done = core_event_done,
 | 
				
			||||||
	.remove_id = core_event_remove_id,
 | 
						.remove_id = core_event_remove_id,
 | 
				
			||||||
 | 
						.bound_id = core_event_bound_id,
 | 
				
			||||||
	.add_mem = core_event_add_mem,
 | 
						.add_mem = core_event_add_mem,
 | 
				
			||||||
	.remove_mem = core_event_remove_mem,
 | 
						.remove_mem = core_event_remove_mem,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -207,6 +207,18 @@ int pw_resource_ping(struct pw_resource *resource, int seq)
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SPA_EXPORT
 | 
				
			||||||
 | 
					int pw_resource_bound_id(struct pw_resource *resource, uint32_t global_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pw_client *client = resource->client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (client->core_resource != NULL) {
 | 
				
			||||||
 | 
							pw_log_debug(NAME" %p: %u global_id:%u", resource, resource->id, global_id);
 | 
				
			||||||
 | 
							pw_core_resource_bound_id(client->core_resource, resource->id, global_id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
void pw_resource_errorf(struct pw_resource *resource, int res, const char *error, ...)
 | 
					void pw_resource_errorf(struct pw_resource *resource, int res, const char *error, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,6 +121,9 @@ void pw_resource_add_object_listener(struct pw_resource *resource,
 | 
				
			||||||
 * with the same \a sequence number in the return value. */
 | 
					 * with the same \a sequence number in the return value. */
 | 
				
			||||||
int pw_resource_ping(struct pw_resource *resource, int seq);
 | 
					int pw_resource_ping(struct pw_resource *resource, int seq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Notify global id this resource is bound to */
 | 
				
			||||||
 | 
					int pw_resource_bound_id(struct pw_resource *resource, uint32_t global_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Generate an error for a resource */
 | 
					/** Generate an error for a resource */
 | 
				
			||||||
void pw_resource_error(struct pw_resource *resource, int res, const char *error);
 | 
					void pw_resource_error(struct pw_resource *resource, int res, const char *error);
 | 
				
			||||||
void pw_resource_errorf(struct pw_resource *resource, int res, const char *error, ...) SPA_PRINTF_FUNC(3, 4);
 | 
					void pw_resource_errorf(struct pw_resource *resource, int res, const char *error, ...) SPA_PRINTF_FUNC(3, 4);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,7 @@ static void test_core_abi(void)
 | 
				
			||||||
		void (*ping) (void *object, uint32_t id, int seq);
 | 
							void (*ping) (void *object, uint32_t id, int seq);
 | 
				
			||||||
		void (*error) (void *object, uint32_t id, int seq, int res, const char *error);
 | 
							void (*error) (void *object, uint32_t id, int seq, int res, const char *error);
 | 
				
			||||||
		void (*remove_id) (void *object, uint32_t id);
 | 
							void (*remove_id) (void *object, uint32_t id);
 | 
				
			||||||
 | 
							void (*bound_id) (void *object, uint32_t id, uint32_t global_id);
 | 
				
			||||||
		void (*add_mem) (void *object, uint32_t id, uint32_t type, int fd, uint32_t flags);
 | 
							void (*add_mem) (void *object, uint32_t id, uint32_t type, int fd, uint32_t flags);
 | 
				
			||||||
		void (*remove_mem) (void *object, uint32_t id);
 | 
							void (*remove_mem) (void *object, uint32_t id);
 | 
				
			||||||
	} events = { PW_VERSION_CORE_PROXY_EVENTS, };
 | 
						} events = { PW_VERSION_CORE_PROXY_EVENTS, };
 | 
				
			||||||
| 
						 | 
					@ -84,6 +85,7 @@ static void test_core_abi(void)
 | 
				
			||||||
	TEST_FUNC(e, events, ping);
 | 
						TEST_FUNC(e, events, ping);
 | 
				
			||||||
	TEST_FUNC(e, events, error);
 | 
						TEST_FUNC(e, events, error);
 | 
				
			||||||
	TEST_FUNC(e, events, remove_id);
 | 
						TEST_FUNC(e, events, remove_id);
 | 
				
			||||||
 | 
						TEST_FUNC(e, events, bound_id);
 | 
				
			||||||
	TEST_FUNC(e, events, add_mem);
 | 
						TEST_FUNC(e, events, add_mem);
 | 
				
			||||||
	TEST_FUNC(e, events, remove_mem);
 | 
						TEST_FUNC(e, events, remove_mem);
 | 
				
			||||||
	spa_assert(PW_VERSION_CORE_PROXY_EVENTS == 0);
 | 
						spa_assert(PW_VERSION_CORE_PROXY_EVENTS == 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue