Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
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 */
Ejemplo n.º 9
0
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;
}