mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Improve async handling
Don't use special callback in node to receive the results. Instead, use a generic result callback to receive the result. This makes things a bit more symetric and generic again because then you can choose how to match the result to the request and you have a generic way to handle both the sync and async case. We can then also remove the wait method. This also makes the remote interface and spa interface to objects very similar. Make a helper object to receive and dispatch results. Use this in the helper for enum_params. Make device use the same result callbacks.
This commit is contained in:
		
							parent
							
								
									98463b689b
								
							
						
					
					
						commit
						d2c18c7b1a
					
				
					 64 changed files with 1298 additions and 1141 deletions
				
			
		| 
						 | 
				
			
			@ -41,6 +41,8 @@
 | 
			
		|||
#define MAX_FDS 1024
 | 
			
		||||
#define MAX_FDS_MSG 28
 | 
			
		||||
 | 
			
		||||
#define HDR_SIZE	16
 | 
			
		||||
 | 
			
		||||
static bool debug_messages = 0;
 | 
			
		||||
 | 
			
		||||
struct buffer {
 | 
			
		||||
| 
						 | 
				
			
			@ -277,7 +279,8 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con
 | 
			
		|||
		       uint8_t *opcode,
 | 
			
		||||
		       uint32_t *dest_id,
 | 
			
		||||
		       void **dt,
 | 
			
		||||
		       uint32_t *sz)
 | 
			
		||||
		       uint32_t *sz,
 | 
			
		||||
		       int *seq)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this);
 | 
			
		||||
	size_t len, size;
 | 
			
		||||
| 
						 | 
				
			
			@ -310,19 +313,20 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con
 | 
			
		|||
	data += buf->offset;
 | 
			
		||||
	size -= buf->offset;
 | 
			
		||||
 | 
			
		||||
	if (size < 8) {
 | 
			
		||||
		if (connection_ensure_size(conn, buf, 8) == NULL)
 | 
			
		||||
	if (size < HDR_SIZE) {
 | 
			
		||||
		if (connection_ensure_size(conn, buf, HDR_SIZE) == NULL)
 | 
			
		||||
			return false;
 | 
			
		||||
		buf->update = true;
 | 
			
		||||
		goto again;
 | 
			
		||||
	}
 | 
			
		||||
	p = (uint32_t *) data;
 | 
			
		||||
	data += 8;
 | 
			
		||||
	size -= 8;
 | 
			
		||||
	data += HDR_SIZE;
 | 
			
		||||
	size -= HDR_SIZE;
 | 
			
		||||
 | 
			
		||||
	*dest_id = p[0];
 | 
			
		||||
	*opcode = p[1] >> 24;
 | 
			
		||||
	len = p[1] & 0xffffff;
 | 
			
		||||
	*seq = p[2];
 | 
			
		||||
 | 
			
		||||
	if (len > size) {
 | 
			
		||||
		if (connection_ensure_size(conn, buf, len) == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -332,7 +336,7 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con
 | 
			
		|||
	}
 | 
			
		||||
	buf->size = len;
 | 
			
		||||
	buf->data = data;
 | 
			
		||||
	buf->offset += 8;
 | 
			
		||||
	buf->offset += HDR_SIZE;
 | 
			
		||||
 | 
			
		||||
	*dt = buf->data;
 | 
			
		||||
	*sz = buf->size;
 | 
			
		||||
| 
						 | 
				
			
			@ -345,11 +349,11 @@ static inline void *begin_write(struct pw_protocol_native_connection *conn, uint
 | 
			
		|||
	struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this);
 | 
			
		||||
	uint32_t *p;
 | 
			
		||||
	struct buffer *buf = &impl->out;
 | 
			
		||||
	/* 4 for dest_id, 1 for opcode, 3 for size and size for payload */
 | 
			
		||||
	if ((p = connection_ensure_size(conn, buf, 8 + size)) == NULL)
 | 
			
		||||
	/* header and size for payload */
 | 
			
		||||
	if ((p = connection_ensure_size(conn, buf, HDR_SIZE + size)) == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return p + 2;
 | 
			
		||||
	return SPA_MEMBER(p, HDR_SIZE, void);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int builder_overflow(void *callbacks_data, uint32_t size)
 | 
			
		||||
| 
						 | 
				
			
			@ -392,20 +396,21 @@ pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn,
 | 
			
		|||
	struct buffer *buf = &impl->out;
 | 
			
		||||
	uint32_t seq;
 | 
			
		||||
 | 
			
		||||
	if ((p = connection_ensure_size(conn, buf, 8 + size)) == NULL)
 | 
			
		||||
	if ((p = connection_ensure_size(conn, buf, HDR_SIZE + size)) == NULL)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	seq = impl->seq;
 | 
			
		||||
	impl->seq = (impl->seq + 1) & SPA_ASYNC_SEQ_MASK;
 | 
			
		||||
 | 
			
		||||
	*p++ = impl->dest_id;
 | 
			
		||||
	*p++ = (impl->opcode << 24) | (size & 0xffffff);
 | 
			
		||||
	p[0] = impl->dest_id;
 | 
			
		||||
	p[1] = (impl->opcode << 24) | (size & 0xffffff);
 | 
			
		||||
	p[2] = seq;
 | 
			
		||||
 | 
			
		||||
	buf->buffer_size += 8 + size;
 | 
			
		||||
	buf->buffer_size += HDR_SIZE + size;
 | 
			
		||||
 | 
			
		||||
	if (debug_messages) {
 | 
			
		||||
		fprintf(stderr, ">>>>>>>>> out: %d %d %d\n", impl->dest_id, impl->opcode, size);
 | 
			
		||||
	        spa_debug_pod(0, NULL, (struct spa_pod *)p);
 | 
			
		||||
	        spa_debug_pod(0, NULL, SPA_MEMBER(p, HDR_SIZE, struct spa_pod));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spa_hook_list_call(&conn->listener_list,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ bool
 | 
			
		|||
pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *conn,
 | 
			
		||||
				       uint8_t *opcode,
 | 
			
		||||
				       uint32_t *dest_id,
 | 
			
		||||
				       void **data, uint32_t *size);
 | 
			
		||||
				       void **data, uint32_t *size, int *seq);
 | 
			
		||||
 | 
			
		||||
uint32_t pw_protocol_native_connection_add_fd(struct pw_protocol_native_connection *conn, int fd);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -646,7 +646,7 @@ static int device_demarshal_info(void *object, void *data, size_t size)
 | 
			
		|||
	return pw_proxy_notify(proxy, struct pw_device_proxy_events, info, 0, &info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next,
 | 
			
		||||
static int device_marshal_param(void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next,
 | 
			
		||||
		const struct spa_pod *param)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_resource *resource = object;
 | 
			
		||||
| 
						 | 
				
			
			@ -655,6 +655,7 @@ static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint3
 | 
			
		|||
	b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_PARAM, NULL);
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_add_struct(b,
 | 
			
		||||
			SPA_POD_Int(seq),
 | 
			
		||||
			SPA_POD_Id(id),
 | 
			
		||||
			SPA_POD_Int(index),
 | 
			
		||||
			SPA_POD_Int(next),
 | 
			
		||||
| 
						 | 
				
			
			@ -667,29 +668,33 @@ static int device_demarshal_param(void *object, void *data, size_t size)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_proxy *proxy = object;
 | 
			
		||||
	struct spa_pod_parser prs;
 | 
			
		||||
	uint32_t id, index, next;
 | 
			
		||||
	uint32_t seq, id, index, next;
 | 
			
		||||
	struct spa_pod *param;
 | 
			
		||||
 | 
			
		||||
	spa_pod_parser_init(&prs, data, size);
 | 
			
		||||
	if (spa_pod_parser_get_struct(&prs,
 | 
			
		||||
				SPA_POD_Int(&seq),
 | 
			
		||||
				SPA_POD_Id(&id),
 | 
			
		||||
				SPA_POD_Int(&index),
 | 
			
		||||
				SPA_POD_Int(&next),
 | 
			
		||||
				SPA_POD_Pod(¶m)) < 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return pw_proxy_notify(proxy, struct pw_device_proxy_events, param, 0, id, index, next, param);
 | 
			
		||||
	return pw_proxy_notify(proxy, struct pw_device_proxy_events, param, 0,
 | 
			
		||||
			seq, id, index, next, param);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int device_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num,
 | 
			
		||||
		const struct spa_pod *filter)
 | 
			
		||||
static int device_marshal_enum_params(void *object, uint32_t seq,
 | 
			
		||||
		uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_proxy *proxy = object;
 | 
			
		||||
	struct spa_pod_builder *b;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, NULL);
 | 
			
		||||
	b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, &res);
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_add_struct(b,
 | 
			
		||||
			SPA_POD_Int(res),
 | 
			
		||||
			SPA_POD_Id(id),
 | 
			
		||||
			SPA_POD_Int(index),
 | 
			
		||||
			SPA_POD_Int(num),
 | 
			
		||||
| 
						 | 
				
			
			@ -702,18 +707,20 @@ static int device_demarshal_enum_params(void *object, void *data, size_t size)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_resource *resource = object;
 | 
			
		||||
	struct spa_pod_parser prs;
 | 
			
		||||
	uint32_t id, index, num;
 | 
			
		||||
	uint32_t id, index, num, seq;
 | 
			
		||||
	struct spa_pod *filter;
 | 
			
		||||
 | 
			
		||||
	spa_pod_parser_init(&prs, data, size);
 | 
			
		||||
	if (spa_pod_parser_get_struct(&prs,
 | 
			
		||||
				SPA_POD_Int(&seq),
 | 
			
		||||
				SPA_POD_Id(&id),
 | 
			
		||||
				SPA_POD_Int(&index),
 | 
			
		||||
				SPA_POD_Int(&num),
 | 
			
		||||
				SPA_POD_Pod(&filter)) < 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return pw_resource_do(resource, struct pw_device_proxy_methods, enum_params, 0, id, index, num, filter);
 | 
			
		||||
	return pw_resource_do(resource, struct pw_device_proxy_methods, enum_params, 0,
 | 
			
		||||
			seq, id, index, num, filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int device_marshal_set_param(void *object, uint32_t id, uint32_t flags,
 | 
			
		||||
| 
						 | 
				
			
			@ -870,8 +877,8 @@ static int node_demarshal_info(void *object, void *data, size_t size)
 | 
			
		|||
	return pw_proxy_notify(proxy, struct pw_node_proxy_events, info, 0, &info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next,
 | 
			
		||||
		const struct spa_pod *param)
 | 
			
		||||
static int node_marshal_param(void *object, uint32_t seq, uint32_t id,
 | 
			
		||||
		uint32_t index, uint32_t next, const struct spa_pod *param)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_resource *resource = object;
 | 
			
		||||
	struct spa_pod_builder *b;
 | 
			
		||||
| 
						 | 
				
			
			@ -879,6 +886,7 @@ static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_
 | 
			
		|||
	b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_PARAM, NULL);
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_add_struct(b,
 | 
			
		||||
			SPA_POD_Int(seq),
 | 
			
		||||
			SPA_POD_Id(id),
 | 
			
		||||
			SPA_POD_Int(index),
 | 
			
		||||
			SPA_POD_Int(next),
 | 
			
		||||
| 
						 | 
				
			
			@ -891,29 +899,33 @@ static int node_demarshal_param(void *object, void *data, size_t size)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_proxy *proxy = object;
 | 
			
		||||
	struct spa_pod_parser prs;
 | 
			
		||||
	uint32_t id, index, next;
 | 
			
		||||
	uint32_t seq, id, index, next;
 | 
			
		||||
	struct spa_pod *param;
 | 
			
		||||
 | 
			
		||||
	spa_pod_parser_init(&prs, data, size);
 | 
			
		||||
	if (spa_pod_parser_get_struct(&prs,
 | 
			
		||||
				SPA_POD_Int(&seq),
 | 
			
		||||
				SPA_POD_Id(&id),
 | 
			
		||||
				SPA_POD_Int(&index),
 | 
			
		||||
				SPA_POD_Int(&next),
 | 
			
		||||
				SPA_POD_Pod(¶m)) < 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return pw_proxy_notify(proxy, struct pw_node_proxy_events, param, 0, id, index, next, param);
 | 
			
		||||
	return pw_proxy_notify(proxy, struct pw_node_proxy_events, param, 0,
 | 
			
		||||
			seq, id, index, next, param);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int node_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num,
 | 
			
		||||
		const struct spa_pod *filter)
 | 
			
		||||
static int node_marshal_enum_params(void *object, uint32_t seq, uint32_t id,
 | 
			
		||||
		uint32_t index, uint32_t num, const struct spa_pod *filter)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_proxy *proxy = object;
 | 
			
		||||
	struct spa_pod_builder *b;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, NULL);
 | 
			
		||||
	b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, &res);
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_add_struct(b,
 | 
			
		||||
			SPA_POD_Int(res),
 | 
			
		||||
			SPA_POD_Id(id),
 | 
			
		||||
			SPA_POD_Int(index),
 | 
			
		||||
			SPA_POD_Int(num),
 | 
			
		||||
| 
						 | 
				
			
			@ -926,18 +938,20 @@ static int node_demarshal_enum_params(void *object, void *data, size_t size)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_resource *resource = object;
 | 
			
		||||
	struct spa_pod_parser prs;
 | 
			
		||||
	uint32_t id, index, num;
 | 
			
		||||
	uint32_t seq, id, index, num;
 | 
			
		||||
	struct spa_pod *filter;
 | 
			
		||||
 | 
			
		||||
	spa_pod_parser_init(&prs, data, size);
 | 
			
		||||
	if (spa_pod_parser_get_struct(&prs,
 | 
			
		||||
				SPA_POD_Int(&seq),
 | 
			
		||||
				SPA_POD_Id(&id),
 | 
			
		||||
				SPA_POD_Int(&index),
 | 
			
		||||
				SPA_POD_Int(&num),
 | 
			
		||||
				SPA_POD_Pod(&filter)) < 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return pw_resource_do(resource, struct pw_node_proxy_methods, enum_params, 0, id, index, num, filter);
 | 
			
		||||
	return pw_resource_do(resource, struct pw_node_proxy_methods, enum_params, 0,
 | 
			
		||||
			seq, id, index, num, filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int node_marshal_set_param(void *object, uint32_t id, uint32_t flags,
 | 
			
		||||
| 
						 | 
				
			
			@ -1050,8 +1064,8 @@ static int port_demarshal_info(void *object, void *data, size_t size)
 | 
			
		|||
	return pw_proxy_notify(proxy, struct pw_port_proxy_events, info, 0, &info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next,
 | 
			
		||||
		const struct spa_pod *param)
 | 
			
		||||
static int port_marshal_param(void *object, uint32_t seq, uint32_t id,
 | 
			
		||||
		uint32_t index, uint32_t next, const struct spa_pod *param)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_resource *resource = object;
 | 
			
		||||
	struct spa_pod_builder *b;
 | 
			
		||||
| 
						 | 
				
			
			@ -1059,6 +1073,7 @@ static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_
 | 
			
		|||
	b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_PARAM, NULL);
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_add_struct(b,
 | 
			
		||||
			SPA_POD_Int(seq),
 | 
			
		||||
			SPA_POD_Id(id),
 | 
			
		||||
			SPA_POD_Int(index),
 | 
			
		||||
			SPA_POD_Int(next),
 | 
			
		||||
| 
						 | 
				
			
			@ -1071,29 +1086,33 @@ static int port_demarshal_param(void *object, void *data, size_t size)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_proxy *proxy = object;
 | 
			
		||||
	struct spa_pod_parser prs;
 | 
			
		||||
	uint32_t id, index, next;
 | 
			
		||||
	uint32_t seq, id, index, next;
 | 
			
		||||
	struct spa_pod *param;
 | 
			
		||||
 | 
			
		||||
	spa_pod_parser_init(&prs, data, size);
 | 
			
		||||
	if (spa_pod_parser_get_struct(&prs,
 | 
			
		||||
				SPA_POD_Int(&seq),
 | 
			
		||||
				SPA_POD_Id(&id),
 | 
			
		||||
				SPA_POD_Int(&index),
 | 
			
		||||
				SPA_POD_Int(&next),
 | 
			
		||||
				SPA_POD_Pod(¶m)) < 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return pw_proxy_notify(proxy, struct pw_port_proxy_events, param, 0, id, index, next, param);
 | 
			
		||||
	return pw_proxy_notify(proxy, struct pw_port_proxy_events, param, 0,
 | 
			
		||||
			seq, id, index, next, param);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int port_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num,
 | 
			
		||||
		const struct spa_pod *filter)
 | 
			
		||||
static int port_marshal_enum_params(void *object, uint32_t seq, uint32_t id,
 | 
			
		||||
		uint32_t index, uint32_t num, const struct spa_pod *filter)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_proxy *proxy = object;
 | 
			
		||||
	struct spa_pod_builder *b;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, NULL);
 | 
			
		||||
	b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, &res);
 | 
			
		||||
 | 
			
		||||
	spa_pod_builder_add_struct(b,
 | 
			
		||||
			SPA_POD_Int(res),
 | 
			
		||||
			SPA_POD_Id(id),
 | 
			
		||||
			SPA_POD_Int(index),
 | 
			
		||||
			SPA_POD_Int(num),
 | 
			
		||||
| 
						 | 
				
			
			@ -1106,18 +1125,20 @@ static int port_demarshal_enum_params(void *object, void *data, size_t size)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_resource *resource = object;
 | 
			
		||||
	struct spa_pod_parser prs;
 | 
			
		||||
	uint32_t id, index, num;
 | 
			
		||||
	uint32_t seq, id, index, num;
 | 
			
		||||
	struct spa_pod *filter;
 | 
			
		||||
 | 
			
		||||
	spa_pod_parser_init(&prs, data, size);
 | 
			
		||||
	if (spa_pod_parser_get_struct(&prs,
 | 
			
		||||
				SPA_POD_Int(&seq),
 | 
			
		||||
				SPA_POD_Id(&id),
 | 
			
		||||
				SPA_POD_Int(&index),
 | 
			
		||||
				SPA_POD_Int(&num),
 | 
			
		||||
				SPA_POD_Pod(&filter)) < 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return pw_resource_do(resource, struct pw_port_proxy_methods, enum_params, 0, id, index, num, filter);
 | 
			
		||||
	return pw_resource_do(resource, struct pw_port_proxy_methods, enum_params, 0,
 | 
			
		||||
			seq, id, index, num, filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int client_marshal_info(void *object, const struct pw_client_info *info)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue