From bcd7cfef8897fad65298170a949dff3de3ed5b9b Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Tue, 22 Oct 2013 13:37:34 +0300 Subject: [PATCH] resource-c: added support for querying resource set id. Also, if there wasn't a server side resource set, make the release operation create one. This is needed so that resource set ids (assigned by server) can be retrieved without acquiring a resource set. --- .../libmurphy-resource/resource-api.h | 25 ++++++++ .../libmurphy-resource/resource-private.h | 8 +++ .../resource-native/libmurphy-resource/resource.c | 21 ++++++- .../resource-native/libmurphy-resource/rset.c | 67 ++++++++++++++++++++-- 4 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/plugins/resource-native/libmurphy-resource/resource-api.h b/src/plugins/resource-native/libmurphy-resource/resource-api.h index 1ead266..1ec95f1 100644 --- a/src/plugins/resource-native/libmurphy-resource/resource-api.h +++ b/src/plugins/resource-native/libmurphy-resource/resource-api.h @@ -257,6 +257,31 @@ int mrp_res_acquire_resource_set(mrp_res_context_t *cx, int mrp_res_release_resource_set(mrp_res_context_t *cx, mrp_res_resource_set_t *rs); + +/** + * Get a resource set unique server-side id. The id information is + * normally available only after mrp_res_acquire_resource_set or + * mrp_res_release_resource_set function callback has been called. + * + * The id is the resource set internal id, available on the resource + * manager side. The client can use this information to associate other + * properties with the resource set. The resource manager can then use + * this extra information to process system events. + * + * An example would be to set an audio stream property to contain the + * resource set id. The resource manager can use the data associated + * with audio streams to find out which streams belong to which resource + * set in the audio domain controller. + * + * @param cx connnection to Murphy resource engine. + * @param rs resource set whose id is queried. + * + * @return resource set id. + **/ +int mrp_res_get_resource_set_id(mrp_res_context_t *cx, + mrp_res_resource_set_t *rs); + + /** * Create new resource by name and init all other fields. * Created resource will be automatically added to diff --git a/src/plugins/resource-native/libmurphy-resource/resource-private.h b/src/plugins/resource-native/libmurphy-resource/resource-private.h index 3f49969..ecf8d6e 100644 --- a/src/plugins/resource-native/libmurphy-resource/resource-private.h +++ b/src/plugins/resource-native/libmurphy-resource/resource-private.h @@ -38,6 +38,12 @@ MRP_CDECL_BEGIN +typedef enum { + MRP_RES_PENDING_OPERATION_NONE = 0, + MRP_RES_PENDING_OPERATION_ACQUIRE, + MRP_RES_PENDING_OPERATION_RELEASE, +} pending_operation_t; + typedef struct { const char *name; mrp_res_attribute_type_t type; /* s:char *, i:int32_t, u:uint32_t, f:double */ @@ -91,6 +97,8 @@ struct mrp_res_resource_set_private_s { uint32_t num_resources; mrp_res_resource_t **resources; + pending_operation_t waiting_for; + mrp_list_hook_t hook; }; diff --git a/src/plugins/resource-native/libmurphy-resource/resource.c b/src/plugins/resource-native/libmurphy-resource/resource.c index 5f528e9..b62852a 100644 --- a/src/plugins/resource-native/libmurphy-resource/resource.c +++ b/src/plugins/resource-native/libmurphy-resource/resource.c @@ -228,8 +228,8 @@ static void resource_event(mrp_msg_t *msg, } /* Check the resource set state. If the set is under construction - * (we are waiting for "acquire" message), do not do the callback - * before that. Otherwise, if this is a real event, call the + * (we are waiting for "acquire" or "release" message), do not do the + * callback before that. Otherwise, if this is a real event, call the * callback right away. */ print_resource_set(rset); @@ -321,7 +321,22 @@ static void recvfrom_msg(mrp_transport_t *transp, mrp_msg_t *msg, mrp_htbl_insert(cx->priv->rset_mapping, u_to_p(rset->priv->id), rset); - if (acquire_resource_set_request(cx, rset) < 0) { + /* TODO: if the operation was "acquire", do that. Otherwise + * release. */ + + if (rset->priv->waiting_for == MRP_RES_PENDING_OPERATION_ACQUIRE) { + rset->priv->waiting_for = MRP_RES_PENDING_OPERATION_NONE; + if (acquire_resource_set_request(cx, rset) < 0) { + goto error; + } + } + else if (rset->priv->waiting_for == MRP_RES_PENDING_OPERATION_RELEASE) { + rset->priv->waiting_for = MRP_RES_PENDING_OPERATION_NONE; + if (release_resource_set_request(cx, rset) < 0) { + goto error; + } + } + else { goto error; } break; diff --git a/src/plugins/resource-native/libmurphy-resource/rset.c b/src/plugins/resource-native/libmurphy-resource/rset.c index 0882044..30c3ec1 100644 --- a/src/plugins/resource-native/libmurphy-resource/rset.c +++ b/src/plugins/resource-native/libmurphy-resource/rset.c @@ -364,6 +364,8 @@ static mrp_res_resource_set_t *create_resource_set( rs->priv->resources = mrp_allocz_array(mrp_res_resource_t *, cx->priv->master_resource_set->priv->num_resources); + rs->priv->waiting_for = MRP_RES_PENDING_OPERATION_NONE; + mrp_list_init(&rs->priv->hook); /* ok, create an library-side resource set that we can compare this one to */ @@ -563,23 +565,60 @@ const mrp_res_resource_set_t * mrp_res_list_resources( int mrp_res_release_resource_set(mrp_res_context_t *cx, - mrp_res_resource_set_t *rset) + mrp_res_resource_set_t *original) { mrp_res_resource_set_t *internal_set = NULL; if (!cx->priv->connected) goto error; - if (!rset->priv->internal_id) + if (!original->priv->internal_id) goto error; internal_set = mrp_htbl_lookup(cx->priv->internal_rset_mapping, - u_to_p(rset->priv->internal_id)); + u_to_p(original->priv->internal_id)); if (!internal_set) goto error; - return release_resource_set_request(cx, internal_set); + update_library_resource_set(cx, original, internal_set); + + if (internal_set->priv->id) { + return release_resource_set_request(cx, internal_set); + } + else { + mrp_list_hook_t *p, *n; + mrp_res_resource_set_private_t *pending_rset; + bool found = FALSE; + + /* Create the resource set if it doesn't already exist on the + * server. The releasing is continued when the set is created. + */ + + /* only append if not already present in the list */ + + mrp_list_foreach(&cx->priv->pending_sets, p, n) { + pending_rset = mrp_list_entry(p, mrp_res_resource_set_private_t, hook); + if (pending_rset == internal_set->priv) { + found = TRUE; + break; + } + } + + if (!found) { + mrp_list_append(&cx->priv->pending_sets, &internal_set->priv->hook); + } + + internal_set->priv->waiting_for = MRP_RES_PENDING_OPERATION_RELEASE; + + if (create_resource_set_request(cx, internal_set) < 0) { + mrp_res_error("creating resource set failed"); + mrp_list_delete(&internal_set->priv->hook); + goto error; + } + + return 0; + } error: mrp_res_error("mrp_release_resources error"); @@ -796,6 +835,8 @@ int mrp_res_acquire_resource_set(mrp_res_context_t *cx, mrp_list_append(&cx->priv->pending_sets, &rset->priv->hook); } + rset->priv->waiting_for = MRP_RES_PENDING_OPERATION_ACQUIRE; + if (create_resource_set_request(cx, rset) < 0) { mrp_res_error("creating resource set failed"); mrp_list_delete(&rset->priv->hook); @@ -809,3 +850,21 @@ error: mrp_log_error("error acquiring a resource set"); return -1; } + + +int mrp_res_get_resource_set_id(mrp_res_context_t *cx, + mrp_res_resource_set_t *rs) +{ + mrp_res_resource_set_t *internal_set; + + if (!rs || !rs->priv) + return 0; + + internal_set = mrp_htbl_lookup(cx->priv->internal_rset_mapping, + u_to_p(rs->priv->internal_id)); + + if (!internal_set || !internal_set->priv) + return 0; + + return internal_set->priv->id; +} -- 2.7.4