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:
Wim Taymans 2019-02-25 12:29:57 +01:00
parent 98463b689b
commit d2c18c7b1a
64 changed files with 1298 additions and 1141 deletions

View file

@ -277,24 +277,29 @@ static int impl_set_callbacks(struct spa_device *device,
}
static int impl_enum_params(struct spa_device *device,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
static int impl_enum_params(struct spa_device *device, int seq,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_device_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(device != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
this = SPA_CONTAINER_OF(device, struct impl, device);
spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
result.id = id;
result.next = start;
next:
result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
@ -303,17 +308,17 @@ static int impl_enum_params(struct spa_device *device,
uint32_t list[] = { SPA_PARAM_EnumProfile,
SPA_PARAM_Profile };
if (*index < SPA_N_ELEMENTS(list))
if (result.index < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
else
return 0;
break;
}
case SPA_PARAM_EnumProfile:
{
switch (*index) {
switch (result.index) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamProfile, id,
@ -333,7 +338,7 @@ static int impl_enum_params(struct spa_device *device,
}
case SPA_PARAM_Profile:
{
switch (*index) {
switch (result.index) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamProfile, id,
@ -348,12 +353,16 @@ static int impl_enum_params(struct spa_device *device,
return -ENOENT;
}
(*index)++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_set_param(struct spa_device *device,