mrp_attr_t *mrp_attribute_get_value(uint32_t idx, mrp_attr_t *value, uint32_t nattr, mrp_attr_def_t *defs, mrp_attr_value_t *attrs) { mrp_attr_t *vdst; mrp_attr_def_t *adef; MRP_ASSERT(!nattr || (nattr > 0 && defs && attrs), "invalid argument"); MRP_ASSERT(idx < nattr, "invalid argument"); if ((vdst = value) || (vdst = mrp_alloc(sizeof(mrp_attr_t)))) { adef = defs + idx; if (!(adef->access & MRP_RESOURCE_READ)) memset(vdst, 0, sizeof(mrp_attr_t)); else { vdst->name = adef->name; vdst->type = adef->type; vdst->value = attrs[idx]; } } return vdst; }
int mrp_attribute_copy_definitions(mrp_attr_def_t *from, mrp_attr_def_t *to) { mrp_attr_def_t *s, *d; MRP_ASSERT(to,"invalid argument"); if (from) { for (s = from, d = to; s->name; s++, d++) { if (!(d->name = mrp_strdup(s->name))) goto no_memory; d->access = s->access; if ((d->type = s->type) != mqi_string) d->value = s->value; else { if (!(d->value.string = mrp_strdup(s->value.string))) { mrp_free((void *)d->name); memset(d, 0, sizeof(*d)); goto no_memory; } } } } return 0; no_memory: mrp_log_error("Memory alloc failure. Can't copy attribute definition"); return -1; }
int mrp_attribute_set_values(mrp_attr_t *values, uint32_t nattr, mrp_attr_def_t *defs, mrp_attr_value_t *attrs) { mrp_attr_def_t *adef; mrp_attr_value_t *vsrc; mrp_attr_value_t *vdst; uint32_t i; MRP_ASSERT(!nattr || (nattr > 0 && defs && attrs), "invalid arguments"); for (i = 0; i < nattr; i++) { adef = defs + i; vdst = attrs + i; if (!(adef->access & MRP_RESOURCE_WRITE) || !(vsrc = get_attr_value_from_list(values, adef->name, adef->type))) vsrc = &adef->value; /* default value */ if (adef->type != mqi_string) *vdst = *vsrc; else if (vdst->string != vsrc->string) { /* if the string is not the same, change it */ mrp_free((void *)vdst->string); if (!(vdst->string = mrp_strdup(vsrc->string))) return -1; } } return 0; }
mrp_attr_t *mrp_attribute_get_all_values(uint32_t nvalue, mrp_attr_t *values, uint32_t nattr, mrp_attr_def_t *defs, mrp_attr_value_t *attrs) { mrp_attr_def_t *adef; mrp_attr_t *vdst, *vend; uint32_t i; MRP_ASSERT((!nvalue || (nvalue > 0 && values)) && (!nattr || (nattr > 0 && defs)), "invalid argument"); if (nvalue) nvalue--; else { for (i = 0; i < nattr; i++) { if (!attrs || (attrs && (defs[i].access & MRP_RESOURCE_READ))) nvalue++; } if (!(values = mrp_allocz(sizeof(mrp_attr_t) * (nvalue + 1)))) { mrp_log_error("Memory alloc failure. Can't get attributes"); return NULL; } } vend = (vdst = values) + nvalue; for (i = 0; i < nattr && vdst < vend; i++) { adef = defs + i; if (!(adef->access && MRP_RESOURCE_READ)) continue; vdst->name = adef->name; vdst->type = adef->type; vdst->value = attrs ? attrs[i] : adef->value; vdst++; } memset(vdst, 0, sizeof(*vdst)); return values; }
static mrp_attr_value_t *get_attr_value_from_list(mrp_attr_t *list, const char *name, mqi_data_type_t type) { mrp_attr_t *attr; MRP_ASSERT(name, "invalid argument"); if (list) { for (attr = list; attr->name; attr++) { if (!strcasecmp(name, attr->name) && type == attr->type) return &attr->value; } } return NULL; }
int mrp_attribute_print(uint32_t nattr, mrp_attr_def_t *adefs, mrp_attr_value_t *avals, char *buf, int len) { #define PRINT(fmt, args...) if (p<e) { p += snprintf(p, e-p, fmt , ##args); } mrp_attr_def_t *adef; mrp_attr_value_t *aval; uint32_t i; char *p, *e; if (len <= 0) return 0; MRP_ASSERT(adefs && avals && buf, "invalid argument"); e = (p = buf) + len; for (i = 0; i < nattr; i++) { adef = adefs + i; aval = avals + i; PRINT(" %s:", adef->name); switch (adef->type) { case mqi_string: PRINT("'%s'", aval->string ); break; case mqi_integer: PRINT("%d" , aval->integer ); break; case mqi_unsignd: PRINT("%u" , aval->unsignd ); break; case mqi_floating: PRINT("%lf" , aval->floating); break; default: PRINT(" <unsupported type>" ); break; } } return p - buf; #undef PRINT }
int mrp_resource_owner_create_database_table(mrp_resource_def_t *rdef) { MQI_COLUMN_DEFINITION_LIST(base_coldefs, MQI_COLUMN_DEFINITION( "zone_id" , MQI_UNSIGNED ), MQI_COLUMN_DEFINITION( "zone_name" , MQI_VARCHAR(NAME_LENGTH) ), MQI_COLUMN_DEFINITION( "application_class", MQI_VARCHAR(NAME_LENGTH) ), MQI_COLUMN_DEFINITION( "resource_set_id" , MQI_UNSIGNED ) ); MQI_INDEX_DEFINITION(indexdef, MQI_INDEX_COLUMN( "zone_id" ) ); static bool initialized = false; char name[256]; mqi_column_def_t coldefs[MQI_COLUMN_MAX + 1]; mqi_column_def_t *col; mrp_attr_def_t *atd; mqi_handle_t table; char c, *p; size_t i,j; if (!initialized) { mqi_open(); for (i = 0; i < MRP_RESOURCE_MAX; i++) owner_tables[i] = MQI_HANDLE_INVALID; initialized = true; } MRP_ASSERT(sizeof(base_coldefs) < sizeof(coldefs),"too many base columns"); MRP_ASSERT(rdef, "invalid argument"); MRP_ASSERT(rdef->id < MRP_RESOURCE_MAX, "confused with data structures"); MRP_ASSERT(owner_tables[rdef->id] == MQI_HANDLE_INVALID, "owner table already exist"); snprintf(name, sizeof(name), "%s_owner", rdef->name); for (p = name; (c = *p); p++) { if (!isascii(c) || (!isalnum(c) && c != '_')) *p = '_'; } j = MQI_DIMENSION(base_coldefs) - 1; memcpy(coldefs, base_coldefs, j * sizeof(mqi_column_def_t)); for (i = 0; i < rdef->nattr && j < MQI_COLUMN_MAX; i++, j++) { col = coldefs + j; atd = rdef->attrdefs + i; col->name = atd->name; col->type = atd->type; col->length = (col->type == mqi_string) ? NAME_LENGTH : 0; col->flags = 0; } memset(coldefs + j, 0, sizeof(mqi_column_def_t)); table = MQI_CREATE_TABLE(name, MQI_TEMPORARY, coldefs, indexdef); if (table == MQI_HANDLE_INVALID) { mrp_log_error("Can't create table '%s': %s", name, strerror(errno)); return -1; } owner_tables[rdef->id] = table; return 0; }
void mrp_resource_owner_update_zone(uint32_t zoneid, mrp_resource_set_t *reqset, uint32_t reqid) { typedef struct { uint32_t replyid; mrp_resource_set_t *rset; bool move; } event_t; mrp_resource_owner_t oldowners[MRP_RESOURCE_MAX]; mrp_resource_owner_t backup[MRP_RESOURCE_MAX]; mrp_zone_t *zone; mrp_application_class_t *class; mrp_resource_set_t *rset; mrp_resource_t *res; mrp_resource_def_t *rdef; mrp_resource_mgr_ftbl_t *ftbl; mrp_resource_owner_t *owner, *old, *owners; mrp_resource_mask_t mask; mrp_resource_mask_t mandatory; mrp_resource_mask_t grant; mrp_resource_mask_t advice; void *clc, *rsc, *rc; uint32_t rid; uint32_t rcnt; bool force_release; bool changed; bool move; mrp_resource_event_t notify; uint32_t replyid; uint32_t nevent, maxev; event_t *events, *ev, *lastev; MRP_ASSERT(zoneid < MRP_ZONE_MAX, "invalid argument"); zone = mrp_zone_find_by_id(zoneid); MRP_ASSERT(zone, "zone is not defined"); if (!(maxev = mrp_get_resource_set_count())) return; nevent = 0; events = mrp_alloc(sizeof(event_t) * maxev); MRP_ASSERT(events, "Memory alloc failure. Can't update zone"); reset_owners(zoneid, oldowners); manager_start_transaction(zone); rcnt = mrp_resource_definition_count(); clc = NULL; while ((class = mrp_application_class_iterate_classes(&clc))) { rsc = NULL; while ((rset=mrp_application_class_iterate_rsets(class,zoneid,&rsc))) { force_release = false; mandatory = rset->resource.mask.mandatory; grant = 0; advice = 0; rc = NULL; switch (rset->state) { case mrp_resource_acquire: while ((res = mrp_resource_set_iterate_resources(rset, &rc))) { rdef = res->def; rid = rdef->id; owner = get_owner(zoneid, rid); backup[rid] = *owner; if (grant_ownership(owner, zone, class, rset, res)) grant |= ((mrp_resource_mask_t)1 << rid); else { if (owner->rset != rset) force_release |= owner->modal; } } owners = get_owner(zoneid, 0); if ((grant & mandatory) == mandatory && mrp_resource_lua_veto(zone, rset, owners, grant, reqset)) { advice = grant; } else { /* rollback, ie. restore the backed up state */ rc = NULL; while ((res=mrp_resource_set_iterate_resources(rset,&rc))){ rdef = res->def; rid = rdef->id; mask = (mrp_resource_mask_t)1 << rid; owner = get_owner(zoneid, rid); *owner = backup[rid]; if ((grant & mask)) { if ((ftbl = rdef->manager.ftbl) && ftbl->free) ftbl->free(zone, res, rdef->manager.userdata); } if (advice_ownership(owner, zone, class, rset, res)) advice |= mask; } grant = 0; if ((advice & mandatory) != mandatory) advice = 0; mrp_resource_lua_set_owners(zone, owners); } break; case mrp_resource_release: while ((res = mrp_resource_set_iterate_resources(rset, &rc))) { rdef = res->def; rid = rdef->id; owner = get_owner(zoneid, rid); if (advice_ownership(owner, zone, class, rset, res)) advice |= ((mrp_resource_mask_t)1 << rid); } if ((advice & mandatory) != mandatory) advice = 0; break; default: break; } changed = false; move = false; notify = 0; replyid = (reqset == rset && reqid == rset->request.id) ? reqid:0; if (force_release) { move = (rset->state != mrp_resource_release); notify = move ? MRP_RESOURCE_EVENT_RELEASE : 0; changed = move || rset->resource.mask.grant; rset->state = mrp_resource_release; rset->resource.mask.grant = 0; } else { if (grant == rset->resource.mask.grant) { if (rset->state == mrp_resource_acquire && !grant && rset->dont_wait.current) { rset->state = mrp_resource_release; rset->dont_wait.current = rset->dont_wait.client; notify = MRP_RESOURCE_EVENT_RELEASE; move = true; } } else { rset->resource.mask.grant = grant; changed = true; if (rset->state != mrp_resource_release && !grant && rset->auto_release.current) { rset->state = mrp_resource_release; rset->auto_release.current = rset->auto_release.client; notify = MRP_RESOURCE_EVENT_RELEASE; move = true; } } } if (notify) { mrp_resource_set_notify(rset, notify); } if (advice != rset->resource.mask.advice) { rset->resource.mask.advice = advice; changed = true; } if (replyid || changed) { ev = events + nevent++; ev->replyid = replyid; ev->rset = rset; ev->move = move; } } /* while rset */ } /* while class */
bool mrp_funcbridge_call_from_c(lua_State *L, mrp_funcbridge_t *fb, const char *signature, mrp_funcbridge_value_t *args, char *ret_type, mrp_funcbridge_value_t *ret_value) { char t; int i; int sp; mrp_funcbridge_value_t *a; int sts; bool success; if (!fb) success = false; else { switch (fb->type) { case MRP_C_FUNCTION: if (!strcmp(signature, fb->c.signature)) success = fb->c.func(L, fb->c.data, signature, args, ret_type, ret_value); else { *ret_type = MRP_FUNCBRIDGE_STRING; ret_value->string = mrp_strdup("mismatching signature " "@ C invocation"); success = false; } break; case MRP_LUA_FUNCTION: sp = lua_gettop(L); mrp_funcbridge_push(L, fb); lua_rawgeti(L, -1, 1); luaL_checktype(L, -1, LUA_TFUNCTION); for (i = 0; (t = signature[i]); i++) { a = args + i; switch (t) { case MRP_FUNCBRIDGE_STRING: lua_pushstring(L, a->string); break; case MRP_FUNCBRIDGE_INTEGER: lua_pushinteger(L, a->integer); break; case MRP_FUNCBRIDGE_FLOATING: lua_pushnumber(L, a->floating); break; case MRP_FUNCBRIDGE_BOOLEAN: lua_pushboolean(L, a->boolean); break; case MRP_FUNCBRIDGE_OBJECT: mrp_lua_push_object(L, a->pointer); break; default: success = false; goto done; } } sts = lua_pcall(L, i, 1, 0); MRP_ASSERT(!sts || (sts && lua_type(L, -1) == LUA_TSTRING), "lua pcall did not return error string when failed"); switch (lua_type(L, -1)) { case LUA_TSTRING: *ret_type = MRP_FUNCBRIDGE_STRING; ret_value->string = mrp_strdup(lua_tolstring(L, -1, NULL)); break; case LUA_TNUMBER: *ret_type = MRP_FUNCBRIDGE_FLOATING; ret_value->floating = lua_tonumber(L, -1); break; case LUA_TBOOLEAN: *ret_type = MRP_FUNCBRIDGE_BOOLEAN; ret_value->boolean = lua_toboolean(L, -1); break; default: *ret_type = MRP_FUNCBRIDGE_NO_DATA; memset(ret_value, 0, sizeof(*ret_value)); break; } success = !sts; done: lua_settop(L, sp); break; default: success = false; break; } } return success; }