#include #include #include #include #include #include #include "mylock.h" #include "resobj.h" #include "utils.h" #include "xstring.h" typedef struct { atomic_ulong refcount; } resobj_private_t; static size_t resobj_datasize(va_list ap) { size_t sz = sizeof(xce_resource_t); return sz; } static int resobj_init(meta_obj_t* obj, va_list ap) { xce_resource_t* dst = RTTI_OBJ_TO_DATA(xce_resource_t, obj); resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); xce_resource_t* src = va_arg(ap, xce_resource_t*); if (src == NULL) { return -EINVAL; } memcpy(dst, src, sizeof(*dst)); dst->name = makeString(src->name); dst->desc = makeString(src->desc); #if 0 if (src->distributions != NULL) { MOVE_PTR(dst->distributions, src->distributions); } #else /* FIXME: */ dst->distributions = NULL; #endif #if 0 MOVE_PTR(dst->hbased_defined, src->hbased_defined); #else /* FIXME: */ dst->hbased_defined = NULL; #endif priv->refcount = 1; return 1; } static void resobj_destroy(meta_obj_t* obj) { xce_resource_t* r = RTTI_OBJ_TO_DATA(xce_resource_t, obj); resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); dereference(r->name); dereference(r->desc); memset(priv, 0x0, sizeof(*priv)); return; } static int resobj_reference(meta_obj_t* obj) { resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); atomic_fetch_add(&(priv->refcount), 1); return 1; } static void resobj_dereference(meta_obj_t* obj) { resobj_private_t* priv = (resobj_private_t*)RTTI_OBJ_TO_PRIV(obj); xce_resource_t* w = RTTI_OBJ_TO_DATA(xce_resource_t, obj); uint64_t count = 0; count = atomic_fetch_sub(&(priv->refcount), 1); if (count == 1) { destroy_(w, (obj_destroy_fn_t)resobj_destroy); } return; } static typeinfo_t resobj_type = { .name = "xce resobj", .privateSize = sizeof(resobj_private_t), .dataSize = (datasize_fn_t)resobj_datasize, .init = (obj_init_fn_t)resobj_init, .destroy = NULL, .interfaces = { .reference = &(intf_reference_t) { .reference = (reference_fn_t)resobj_reference, .dereference = (dereference_fn_t)resobj_dereference } } }; static xce_resource_t* makeResource_(var resmgr, xce_resource_t* r) { xce_resource_t* resobj = NULL; int rc; rc = key_find(resmgr, (void*)r->name, (void**)&resobj); if ((rc < 0) && (rc != -ENOENT)) { errno = -rc; return NULL; } if (rc > 0) { errno = EEXIST; return NULL; } resobj = makeInstance(&resobj_type, r); if (resobj != NULL) { rc = key_add(resmgr, (void*)resobj->name, (void*)resobj); if (rc < 0) { destroy(resobj); errno = -rc; return NULL; } resobj->idx = rc; } return resobj; } xce_resource_t* makeResource(var resmgr, xce_resource_t* r) { xce_resource_t* r1 = NULL; lock(resmgr, RTTI_LOCK_WRITE); r1 = makeResource_(resmgr, r); unlock(resmgr); return r1; }