示例#1
0
void event_cb(uint32_t request_id, mrp_resource_set_t *resource_set, void *user_data)
{
    resource_set_lua_t *rset = (resource_set_lua_t *) user_data;
    mrp_resource_mask_t grant, advice;
    int                 top;

    MRP_UNUSED(request_id);
    MRP_UNUSED(resource_set);

    mrp_debug("> event_cb");

    top = lua_gettop(rset->L);

    grant = mrp_get_resource_set_grant(rset->resource_set);
    advice = mrp_get_resource_set_advice(rset->resource_set);

    /* update resource set */
    rset->acquired = !!grant;
    rset->available = !!advice;

    if (mrp_lua_object_deref_value(rset, rset->L, rset->callback, false)) {
        mrp_lua_push_object(rset->L, rset);

        if (lua_pcall(rset->L, 1, 0, 0) != 0)
            mrp_log_error("failed to invoke Lua resource set callback: %s",
                    lua_tostring(rset->L, -1));
    }

    lua_settop(rset->L, top);
}
示例#2
0
static int resource_set_get_resources(void *data, lua_State *L, int member, mrp_lua_value_t *v)
{
    resource_set_lua_t *rset;
    void *iter = NULL;
    mrp_resource_t *resource;
    mrp_resource_mask_t grant, advice;

    MRP_UNUSED(member);
    MRP_UNUSED(v);

    mrp_debug("> resource_set_get_resources");

    rset = (resource_set_lua_t *) data;

    if (!rset)
        return luaL_error(L, "internal error");

    grant = mrp_get_resource_set_grant(rset->resource_set);
    advice = mrp_get_resource_set_advice(rset->resource_set);

    lua_newtable(L);

    /* push all resource objects to a table and return it */

    while ((resource = mrp_resource_set_iterate_resources(rset->resource_set, &iter))) {
        const char *name = mrp_resource_get_name(resource);
        mrp_resource_mask_t mask = mrp_resource_get_mask(resource);

        /* fetch and update the resource object */

        resource_lua_t *res =
                (resource_lua_t *) mrp_htbl_lookup(rset->resources,
                (void *) name);

        if (!res) {
            mrp_log_error("resources out of sync: %s not found", name);
            continue;
        }

        /* mrp_lua_object_ref_value(res, L, 0); */

        res->acquired = !!(mask & grant);
        res->available = !!(mask & advice);

        /* TODO: update attributes */

        /* push the resource to the table */
        lua_pushstring(L, res->resource_name);
        mrp_lua_push_object(L, res);
        lua_settable(L, -3);
    }

    return 1;
}
示例#3
0
static int resource_get_attributes(void *data, lua_State *L, int member, mrp_lua_value_t *v)
{
    resource_lua_t *res = (resource_lua_t *) data;

    MRP_UNUSED(member);
    MRP_UNUSED(v);

    mrp_debug("> resource_get_attributes");

    mrp_lua_push_object(L, res->real_attributes);

    return 1;
}
示例#4
0
static int timer_lua_create(lua_State *L)
{

    mrp_context_t *ctx    = mrp_lua_get_murphy_context();
    char           e[128] = "";
    timer_lua_t   *t;
    int            narg;

    if (ctx == NULL)
        luaL_error(L, "failed to get murphy context");

    narg = lua_gettop(L);

    t = (timer_lua_t *)mrp_lua_create_object(L, TIMER_LUA_CLASS, NULL, 0);

    t->L        = L;
    t->ctx      = ctx;
    t->callback = LUA_NOREF;
    t->data     = LUA_NOREF;

    switch (narg) {
    case 1:
        break;
    case 2:
        if (mrp_lua_init_members(t, L, -2, e, sizeof(e)) != 1)
            return luaL_error(L, "failed to initialize timer members (%s)", e);
        break;
    default:
        return luaL_error(L, "expecting 0 or 1 constructor arguments, "
                          "got %d", narg);
    }

    if (t->callback != LUA_NOREF && t->t == NULL) {
        t->t = mrp_add_timer(t->ctx->ml, t->msecs, timer_lua_cb, t);

        if (t->t == NULL) {
            mrp_lua_destroy_object(L, NULL, 0, t);
            return luaL_error(L, "failed to create Murphy timer");
        }
    }

    mrp_lua_push_object(L, t);

    return 1;
}
示例#5
0
static void timer_lua_cb(mrp_timer_t *timer, void *user_data)
{
    timer_lua_t *t   = (timer_lua_t *)user_data;
    int          one = t->oneshot;

    MRP_UNUSED(timer);

    if (mrp_lua_object_deref_value(t, t->L, t->callback, false)) {
        mrp_lua_push_object(t->L, t);
        mrp_lua_object_deref_value(t, t->L, t->data, true);

        if (lua_pcall(t->L, 2, 0, 0) != 0)
            mrp_log_error("failed to invoke Lua timer callback");
    }

    if (one) {
        mrp_del_timer(t->t);
        t->t = NULL;
    }
}
示例#6
0
static int resource_set_lua_create(lua_State *L)
{
    char e[128] = "";
    resource_set_lua_t *rset;
    int narg;
    mrp_htbl_config_t conf;

    mrp_debug("create");

    narg = lua_gettop(L);

    rset = (resource_set_lua_t *) mrp_lua_create_object(L,
            RESOURCE_SET_LUA_CLASS, NULL, 0);

    if (!rset)
        return luaL_error(L, "could not create Lua object");

    rset->L = L;

    /* user can affect these values */
    rset->zone = mrp_strdup("default");
    rset->application_class = NULL;
    rset->autorelease = FALSE;
    rset->dont_wait = FALSE;
    rset->priority = 0;
    rset->committed = FALSE;
    rset->initialized = FALSE;

    switch (narg) {
    case 2:
        /* argument table */
        if (mrp_lua_init_members(rset, L, -2, e, sizeof(e)) != 1)
            return luaL_error(L, "failed to initialize resource members (%s)",
                    e);
        break;
    default:
        return luaL_error(L, "expecting a constructor argument, "
                          "got %d", narg);
    }

    if (rset->application_class == NULL)
        return luaL_error(L, "application_class is a mandatory parameter");

    if (rset->priority < 0)
        rset->priority = 0;

    /* initial state, these cannot be set by user */
    rset->available = FALSE;
    rset->acquired = FALSE;

    /* initialize resource map */
    conf.nbucket = 0;
    conf.nentry = 10;
    conf.comp = mrp_string_comp;
    conf.hash = mrp_string_hash;
    conf.free = htbl_free_resource;

    rset->resources = mrp_htbl_create(&conf);
    if (!rset->resources)
        goto error;

    /* do the actual resource work */

    if (!client) {
        /* create the resource client */

        client = mrp_resource_client_create("lua", NULL);

        if (!client)
            goto error;
    }

    rset->resource_set = mrp_resource_set_create(client, rset->autorelease,
            rset->dont_wait, rset->priority, event_cb, rset);

    if (rset->resource_set)
        n_sets++;
    else
        goto error;

    rset->initialized = TRUE;

    mrp_lua_push_object(L, rset);

    return 1;

error:
    return luaL_error(L, "internal resource library error");
}
示例#7
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;
}