mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-06 13:30:01 -05:00
global: pass bind function to _new
Make the bind function a callback instead of an event. We can then get a return value and use that to clean up the pending proxy and generate an error.
This commit is contained in:
parent
f2ff6f393b
commit
245a0d5634
13 changed files with 67 additions and 67 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 1887f17cc8e829c3bca74bc3d4e37c267654b377
|
||||
Subproject commit cc9fd857ad106dcd74327ccfedc334aadd79caaa
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit bf91b8c002b51cf9af1c7be4b0e1e50bcc83cc1a
|
||||
Subproject commit 83b2aca07236cd29a2f6d138cadd324571b1c8d0
|
||||
|
|
@ -176,7 +176,7 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = client_unbind_func,
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -202,13 +202,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
pw_client_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create client resource");
|
||||
pw_core_resource_error(client->core_resource, id, client->seq,
|
||||
-ENOMEM, "can't create client resource: no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -306,7 +304,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
@ -325,6 +322,7 @@ int pw_client_register(struct pw_client *client,
|
|||
client->global = pw_global_new(core,
|
||||
PW_TYPE_INTERFACE_Client, PW_VERSION_CLIENT,
|
||||
properties,
|
||||
global_bind,
|
||||
client);
|
||||
if (client->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ static const struct pw_resource_events core_resource_events = {
|
|||
.destroy = core_unbind_func,
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data,
|
||||
struct pw_client *client,
|
||||
uint32_t permissions,
|
||||
|
|
@ -388,11 +388,11 @@ global_bind(void *_data,
|
|||
|
||||
pw_log_debug("core %p: bound to %d", this, resource->id);
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create core resource");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void global_destroy(void *object)
|
||||
|
|
@ -406,7 +406,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
/** Create a new core object
|
||||
|
|
@ -508,6 +507,7 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop,
|
|||
PW_CORE_PROP_NAME, this->info.name,
|
||||
PW_CORE_PROP_VERSION, this->info.version,
|
||||
NULL),
|
||||
global_bind,
|
||||
this);
|
||||
if (this->global == NULL)
|
||||
goto no_mem;
|
||||
|
|
|
|||
|
|
@ -196,12 +196,10 @@ static int device_set_param(void *object, uint32_t id, uint32_t flags,
|
|||
struct resource_data *data = object;
|
||||
struct pw_resource *resource = data->resource;
|
||||
struct pw_device *device = data->device;
|
||||
struct pw_client *client = resource->client;
|
||||
int res;
|
||||
|
||||
if ((res = spa_device_set_param(device->implementation, id, flags, param)) < 0)
|
||||
pw_core_resource_error(client->core_resource,
|
||||
resource->id, client->seq, res, spa_strerror(res));
|
||||
pw_resource_error(resource, res, spa_strerror(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +209,7 @@ static const struct pw_device_proxy_methods device_methods = {
|
|||
.set_param = device_set_param
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -239,13 +237,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
pw_device_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create device resource");
|
||||
pw_core_resource_error(client->core_resource, id,
|
||||
client->seq, -ENOMEM, "no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void global_destroy(void *object)
|
||||
|
|
@ -259,7 +255,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
@ -286,6 +281,7 @@ int pw_device_register(struct pw_device *device,
|
|||
device->global = pw_global_new(core,
|
||||
PW_TYPE_INTERFACE_Device, PW_VERSION_DEVICE,
|
||||
properties,
|
||||
global_bind,
|
||||
device);
|
||||
if (device->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = factory_unbind_func,
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -118,13 +118,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
pw_factory_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create factory resource");
|
||||
pw_core_resource_error(client->core_resource, id,
|
||||
client->seq, -ENOMEM, "no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void global_destroy(void *object)
|
||||
|
|
@ -138,7 +136,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
@ -165,6 +162,7 @@ int pw_factory_register(struct pw_factory *factory,
|
|||
factory->global = pw_global_new(core,
|
||||
PW_TYPE_INTERFACE_Factory, PW_VERSION_FACTORY,
|
||||
properties,
|
||||
global_bind,
|
||||
factory);
|
||||
if (factory->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ pw_global_new(struct pw_core *core,
|
|||
uint32_t type,
|
||||
uint32_t version,
|
||||
struct pw_properties *properties,
|
||||
pw_global_bind_func_t func,
|
||||
void *object)
|
||||
{
|
||||
struct impl *impl;
|
||||
|
|
@ -85,6 +86,7 @@ pw_global_new(struct pw_core *core,
|
|||
this->core = core;
|
||||
this->type = type;
|
||||
this->version = version;
|
||||
this->func = func;
|
||||
this->object = object;
|
||||
this->properties = properties;
|
||||
this->id = pw_map_insert_new(&core->globals, this);
|
||||
|
|
@ -259,15 +261,24 @@ pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t perm
|
|||
if (global->version < version)
|
||||
goto wrong_version;
|
||||
|
||||
pw_global_emit_bind(global, client, permissions, version, id);
|
||||
if ((res = global->func(global->object, client, permissions, version, id)) < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
|
||||
wrong_version:
|
||||
res = -EINVAL;
|
||||
pw_core_resource_errorf(client->core_resource, id, 0,
|
||||
res = -EPROTO;
|
||||
pw_core_resource_errorf(client->core_resource, id, client->seq,
|
||||
res, "id %d: interface version %d < %d",
|
||||
id, global->version, version);
|
||||
goto exit;
|
||||
error:
|
||||
pw_core_resource_errorf(client->core_resource, id, client->seq,
|
||||
res, "can't bind global %u/%u: %d (%s)", id, version, res, spa_strerror(res));
|
||||
exit:
|
||||
pw_log_error("can't bind global %u/%u: %d (%s)", id, version, res, spa_strerror(res));
|
||||
pw_map_insert_at(&client->objects, id, NULL);
|
||||
pw_core_resource_remove_id(client->core_resource, id);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ struct pw_global;
|
|||
#include <pipewire/client.h>
|
||||
#include <pipewire/properties.h>
|
||||
|
||||
typedef int (*pw_global_bind_func_t) (void *object,
|
||||
struct pw_client *client, /**< client that binds */
|
||||
uint32_t permissions, /**< permissions for the bind */
|
||||
uint32_t version, /**< client interface version */
|
||||
uint32_t id /**< client proxy id */);
|
||||
|
||||
/** Global events, use \ref pw_global_add_listener */
|
||||
struct pw_global_events {
|
||||
#define PW_VERSION_GLOBAL_EVENTS 0
|
||||
|
|
@ -70,13 +76,6 @@ struct pw_global_events {
|
|||
void (*destroy) (void *data);
|
||||
/** The global is freed */
|
||||
void (*free) (void *data);
|
||||
|
||||
/* bind the global */
|
||||
void (*bind) (void *data,
|
||||
struct pw_client *client, /**< client that binds */
|
||||
uint32_t permissions, /**< permissions for the bind */
|
||||
uint32_t version, /**< client interface version */
|
||||
uint32_t id /**< client proxy id */);
|
||||
};
|
||||
|
||||
/** Create a new global object */
|
||||
|
|
@ -85,6 +84,7 @@ pw_global_new(struct pw_core *core, /**< the core */
|
|||
uint32_t type, /**< the interface type of the global */
|
||||
uint32_t version, /**< the interface version of the global */
|
||||
struct pw_properties *properties, /**< extra properties */
|
||||
pw_global_bind_func_t func, /**< function to bind */
|
||||
void *object /**< global object */);
|
||||
|
||||
/** Register a global object to the core registry */
|
||||
|
|
|
|||
|
|
@ -1067,7 +1067,7 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = link_unbind_func,
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -1091,12 +1091,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
pw_link_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create link resource");
|
||||
pw_core_resource_error(client->core_resource, id, client->seq, -ENOMEM, "no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static const struct pw_port_events input_port_events = {
|
||||
|
|
@ -1114,7 +1113,8 @@ static void input_node_result(void *data, int seq, int res, const void *result)
|
|||
struct impl *impl = data;
|
||||
struct pw_node *node = impl->this.input->node;
|
||||
pw_log_debug("link %p: input node %p result %d %d", impl, node, seq, res);
|
||||
pw_work_queue_complete(impl->work, node, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
if (SPA_RESULT_IS_ASYNC(seq))
|
||||
pw_work_queue_complete(impl->work, node, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
}
|
||||
|
||||
static void output_node_result(void *data, int seq, int res, const void *result)
|
||||
|
|
@ -1122,7 +1122,8 @@ static void output_node_result(void *data, int seq, int res, const void *result)
|
|||
struct impl *impl = data;
|
||||
struct pw_node *node = impl->this.output->node;
|
||||
pw_log_debug("link %p: output node %p result %d %d", impl, node, seq, res);
|
||||
pw_work_queue_complete(impl->work, node, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
if (SPA_RESULT_IS_ASYNC(seq))
|
||||
pw_work_queue_complete(impl->work, node, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
}
|
||||
|
||||
static const struct pw_node_events input_node_events = {
|
||||
|
|
@ -1362,7 +1363,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
@ -1396,6 +1396,7 @@ int pw_link_register(struct pw_link *link,
|
|||
link->global = pw_global_new(core,
|
||||
PW_TYPE_INTERFACE_Link, PW_VERSION_LINK,
|
||||
properties,
|
||||
global_bind,
|
||||
link);
|
||||
if (link->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ static const struct pw_resource_events resource_events = {
|
|||
.destroy = module_unbind_func,
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -134,13 +134,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
pw_module_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create module resource");
|
||||
pw_core_resource_error(client->core_resource, id,
|
||||
client->seq, -ENOMEM, "no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void global_destroy(void *object)
|
||||
|
|
@ -154,7 +152,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
/** Load a module
|
||||
|
|
@ -247,6 +244,7 @@ pw_module_load(struct pw_core *core,
|
|||
pw_properties_new(
|
||||
PW_MODULE_PROP_NAME, name,
|
||||
NULL),
|
||||
global_bind,
|
||||
this);
|
||||
|
||||
if (this->global == NULL)
|
||||
|
|
|
|||
|
|
@ -286,14 +286,12 @@ static int node_set_param(void *object, uint32_t id, uint32_t flags,
|
|||
struct pw_resource *resource = object;
|
||||
struct resource_data *data = pw_resource_get_user_data(resource);
|
||||
struct pw_node *node = data->node;
|
||||
struct pw_client *client = resource->client;
|
||||
int res;
|
||||
|
||||
if ((res = spa_node_set_param(node->node, id, flags, param)) < 0) {
|
||||
pw_log_error("resource %p: %d error %d (%s)", resource,
|
||||
resource->id, res, spa_strerror(res));
|
||||
pw_core_resource_error(client->core_resource,
|
||||
resource->id, client->seq, res, spa_strerror(res));
|
||||
pw_resource_error(resource, res, spa_strerror(res));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -322,7 +320,7 @@ static const struct pw_node_proxy_methods node_methods = {
|
|||
.send_command = node_send_command
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -349,13 +347,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
this->info.change_mask = ~0;
|
||||
pw_node_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create node resource");
|
||||
pw_core_resource_error(client->core_resource, id,
|
||||
client->seq, -ENOMEM, "no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void global_destroy(void *data)
|
||||
|
|
@ -383,7 +379,6 @@ static const struct pw_global_events global_events = {
|
|||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.registering = global_registering,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
@ -417,6 +412,7 @@ int pw_node_register(struct pw_node *this,
|
|||
this->global = pw_global_new(core,
|
||||
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE,
|
||||
properties,
|
||||
global_bind,
|
||||
this);
|
||||
if (this->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
@ -860,7 +856,10 @@ static int node_result(void *data, int seq, int res, const void *result)
|
|||
pw_log_trace("node %p: result seq:%d res:%d", node, seq, res);
|
||||
impl->last_error = res;
|
||||
spa_pending_queue_complete(&impl->pending, seq, res, result);
|
||||
pw_work_queue_complete(impl->work, &impl->this, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
|
||||
if (SPA_RESULT_IS_ASYNC(seq))
|
||||
pw_work_queue_complete(impl->work, &impl->this, SPA_RESULT_ASYNC_SEQ(seq), res);
|
||||
|
||||
pw_node_emit_result(node, seq, res, result);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ static const struct pw_port_proxy_methods port_methods = {
|
|||
.enum_params = port_enum_params
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
|
|
@ -521,12 +521,11 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
this->info.change_mask = ~0;
|
||||
pw_port_resource_info(resource, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
return;
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
pw_log_error("can't create port resource");
|
||||
pw_core_resource_error(client->core_resource, id, client->seq, -ENOMEM, "no memory");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void global_destroy(void *object)
|
||||
|
|
@ -540,7 +539,6 @@ static void global_destroy(void *object)
|
|||
static const struct pw_global_events global_events = {
|
||||
PW_VERSION_GLOBAL_EVENTS,
|
||||
.destroy = global_destroy,
|
||||
.bind = global_bind,
|
||||
};
|
||||
|
||||
int pw_port_register(struct pw_port *port,
|
||||
|
|
@ -554,6 +552,7 @@ int pw_port_register(struct pw_port *port,
|
|||
port->global = pw_global_new(core,
|
||||
PW_TYPE_INTERFACE_Port, PW_VERSION_PORT,
|
||||
properties,
|
||||
global_bind,
|
||||
port);
|
||||
if (port->global == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -131,7 +131,6 @@ struct pw_client {
|
|||
#define pw_global_emit_registering(g) pw_global_emit(g, registering, 0)
|
||||
#define pw_global_emit_destroy(g) pw_global_emit(g, destroy, 0)
|
||||
#define pw_global_emit_free(g) pw_global_emit(g, free, 0)
|
||||
#define pw_global_emit_bind(g,...) pw_global_emit(g, bind, 0, __VA_ARGS__)
|
||||
|
||||
struct pw_global {
|
||||
struct pw_core *core; /**< the core */
|
||||
|
|
@ -149,6 +148,7 @@ struct pw_global {
|
|||
uint32_t type; /**< type of interface */
|
||||
uint32_t version; /**< version of interface */
|
||||
|
||||
pw_global_bind_func_t func; /**< bind function */
|
||||
void *object; /**< object associated with the interface */
|
||||
|
||||
struct spa_list resource_list; /**< The list of resources of this global */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue