mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
device: handle async implementations
This commit is contained in:
parent
bf677d55da
commit
504b2da72b
1 changed files with 60 additions and 11 deletions
|
|
@ -41,10 +41,23 @@ struct impl {
|
|||
#define pw_device_resource_info(r,...) pw_device_resource(r,info,0,__VA_ARGS__)
|
||||
#define pw_device_resource_param(r,...) pw_device_resource(r,param,0,__VA_ARGS__)
|
||||
|
||||
struct result_device_params_data {
|
||||
void *data;
|
||||
int (*callback) (void *data, int seq,
|
||||
uint32_t id, uint32_t index, uint32_t next,
|
||||
struct spa_pod *param);
|
||||
};
|
||||
|
||||
struct resource_data {
|
||||
struct spa_hook resource_listener;
|
||||
struct pw_device *device;
|
||||
struct pw_resource *resource;
|
||||
|
||||
/* for async replies */
|
||||
int seq;
|
||||
int end;
|
||||
struct result_device_params_data data;
|
||||
struct spa_hook listener;
|
||||
};
|
||||
|
||||
struct node_data {
|
||||
|
|
@ -124,20 +137,22 @@ void pw_device_destroy(struct pw_device *device)
|
|||
|
||||
static void device_unbind_func(void *data)
|
||||
{
|
||||
struct pw_resource *resource = data;
|
||||
struct resource_data *d = data;
|
||||
struct pw_resource *resource = d->resource;
|
||||
spa_list_remove(&resource->link);
|
||||
}
|
||||
|
||||
static void device_pong(void *data, int seq)
|
||||
{
|
||||
struct resource_data *d = data;
|
||||
struct pw_resource *resource = d->resource;
|
||||
pw_log_debug("resource %p: got pong %d", resource, seq);
|
||||
}
|
||||
|
||||
static const struct pw_resource_events resource_events = {
|
||||
PW_VERSION_RESOURCE_EVENTS,
|
||||
.destroy = device_unbind_func,
|
||||
};
|
||||
|
||||
struct result_device_params_data {
|
||||
void *data;
|
||||
int (*callback) (void *data, int seq,
|
||||
uint32_t id, uint32_t index, uint32_t next,
|
||||
struct spa_pod *param);
|
||||
.pong = device_pong,
|
||||
};
|
||||
|
||||
static void result_device_params(void *data, int seq, int res, uint32_t type, const void *result)
|
||||
|
|
@ -198,6 +213,20 @@ static int reply_param(void *data, int seq, uint32_t id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void result_device_params_async(void *data, int seq, int res, uint32_t type, const void *result)
|
||||
{
|
||||
struct resource_data *d = data;
|
||||
|
||||
pw_log_debug("async result %d %d (%d/%d)", res, seq, d->seq, d->end);
|
||||
if (seq == d->seq)
|
||||
result_device_params(&d->data, seq, res, type, result);
|
||||
|
||||
if (seq == d->end) {
|
||||
spa_hook_remove(&d->listener);
|
||||
pw_client_set_busy(d->resource->client, false);
|
||||
}
|
||||
}
|
||||
|
||||
static int device_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter)
|
||||
{
|
||||
|
|
@ -206,11 +235,27 @@ static int device_enum_params(void *object, int seq, uint32_t id, uint32_t start
|
|||
struct pw_device *device = data->device;
|
||||
struct pw_client *client = resource->client;
|
||||
int res;
|
||||
static const struct spa_device_events device_events = {
|
||||
SPA_VERSION_DEVICE_EVENTS,
|
||||
.result = result_device_params_async,
|
||||
};
|
||||
|
||||
if ((res = pw_device_for_each_param(device, seq, id, start, num,
|
||||
filter, reply_param, data)) < 0)
|
||||
res = pw_device_for_each_param(device, seq, id, start, num,
|
||||
filter, reply_param, data);
|
||||
|
||||
if (res < 0) {
|
||||
pw_core_resource_error(client->core_resource,
|
||||
resource->id, seq, res, spa_strerror(res));
|
||||
} else if (SPA_RESULT_IS_ASYNC(res)) {
|
||||
data->data.data = data;
|
||||
data->data.callback = reply_param;
|
||||
spa_device_add_listener(device->device, &data->listener,
|
||||
&device_events, data);
|
||||
data->seq = res;
|
||||
data->end = spa_device_sync(device->device, res);
|
||||
pw_client_set_busy(client, true);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +294,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
|||
data = pw_resource_get_user_data(resource);
|
||||
data->device = this;
|
||||
data->resource = resource;
|
||||
pw_resource_add_listener(resource, &data->resource_listener, &resource_events, resource);
|
||||
pw_resource_add_listener(resource, &data->resource_listener, &resource_events, data);
|
||||
|
||||
pw_resource_set_implementation(resource, &device_methods, data);
|
||||
|
||||
|
|
@ -393,6 +438,10 @@ static void device_add(struct pw_device *device, uint32_t id,
|
|||
pw_log_warn("device %p: unknown type %d", device, info->type);
|
||||
return;
|
||||
}
|
||||
if (info->factory == NULL) {
|
||||
pw_log_warn("device %p: missing factory", device);
|
||||
return;
|
||||
}
|
||||
|
||||
pw_log_debug("device %p: add node %d", device, id);
|
||||
support = pw_core_get_support(device->core, &n_support);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue