コード例 #1
0
static int l_node_index(lua_State *L)
{
	struct laura_node *lnode = lua_touserdata(L, 1);
	const char *name = lua_tostring(L, -1);
	struct aura_object *o;

	TRACE();
	/* FixMe: Can this get gc-d by the time we actually use it? */
	lnode->current_call = name;

	if (AURA_STATUS_ONLINE != aura_get_status(lnode->node))
		return luaL_error(L, "Attempt to call remote method %s when node offline",
				  lnode->current_call);

	o = aura_etable_find(lnode->node->tbl, lnode->current_call);
	if (!o)
		return luaL_error(L, "Internal aura bug: failed to lookup object: %s",
				  lnode->current_call);

	if (strcmp("__", name) == 0)
		lua_pushcfunction(L, laura_do_async_call);
	else if (object_is_method(o))
		lua_pushcfunction(L, laura_do_sync_call);
	else
		lua_pushnil(L);
	return 1;
}
コード例 #2
0
ファイル: aura.c プロジェクト: RC-MODULE/matlab
/* This one is small, but tricky */
static void aura_handle_inbound(struct aura_node *node)
{
    while(1) {
        struct aura_buffer *buf;
        struct aura_object *o;

        buf = aura_dequeue_buffer(&node->inbound_buffers);
        if (!buf)
            break;

        o = buf->object;
        node->current_object = o;
        aura_buffer_rewind(buf);

        slog(4, SLOG_DEBUG, "Handling %s id %d (%s) sync_call_running=%d",
             object_is_method(o) ? "response" : "event",
             o->id, o->name, node->sync_call_running);

        if (object_is_method(o) && !o->pending) {
            slog(0, SLOG_WARN, "Dropping orphan call result %d (%s)",
                 o->id, o->name);
            aura_buffer_release(node, buf);
        } else if (o->calldonecb) {
            slog(4, SLOG_DEBUG, "Callback for method/event %d (%s)",
                 o->id, o->name);
            o->calldonecb(node, AURA_CALL_COMPLETED, buf, o->arg);
            aura_buffer_release(node, buf);
        } else if (object_is_method(o) && (node->sync_call_running)) {
            slog(4, SLOG_DEBUG, "Completing call for method %d (%s)",
                 o->id, o->name);
            node->sync_call_result = AURA_CALL_COMPLETED;
            node->sync_ret_buf = buf;
            o->pending--;
            if (o->pending < 0)
                BUG(node, "Internal BUG: pending evt count lesser than zero");
        } else {
            /* This one is tricky. We have an event with no callback */
            if (node->sync_event_max > 0) { /* Queue it up into event_queue if it's enabled */
                /* If we have an overrun - drop the oldest event to free up space first*/
                if (node->sync_event_max <= node->sync_event_count) {
                    struct aura_buffer *todrop;
                    const struct aura_object *dummy;
                    int ret = aura_get_next_event(node, &dummy, &todrop);
                    if (ret != 0)
                        BUG(node, "Internal bug, no next event");
                    aura_buffer_release(node, todrop);
                }

                /* Now just queue the next one */
                aura_queue_buffer(&node->event_buffers, buf);
                node->sync_event_count++;
                slog(4, SLOG_DEBUG, "Queued event %d (%s) for sync readout",
                     o->id, o->name);
            } else {
                /* Last resort - try the catch-all event callback */
                if (node->unhandled_evt_cb)
                    node->unhandled_evt_cb(node, buf, node->unhandled_evt_arg);
                else /* Or just drop it with a warning */
                    slog(0, SLOG_WARN, "Dropping event %d (%s)",
                         o->id, o->name);
                aura_buffer_release(node, buf);
            }
        }
    }

    node->current_object = NULL;
}
コード例 #3
0
static int laura_do_async_call(lua_State *L)
{
	struct laura_node *lnode = NULL;
	const char *name;
	struct aura_buffer *buf;
	struct aura_object *o;
	int ret;
	int callback_ref;

	TRACE();

	/* Sanity */
	lnode = lua_fetch_node(L, 1);
	if (!lnode) {
		lua_stackdump(L);
		return aura_typeerror(L, 1, "userdata (node)");
	}

	if (!lua_isstring(L, 2)) {
		lua_stackdump(L);
		return aura_typeerror(L, 2, "string (object name)");
	}

	if (!lua_isfunction(L, 3)) {
		lua_stackdump(L);
		return aura_typeerror(L, 3, "function (callback)");
	}

	name = lua_tostring(L, 2);

	o = aura_etable_find(lnode->node->tbl, name);
	if (!o)
		return luaL_error(L, "Attempt to call non-existend method");

	if (!object_is_method(o)) {
		lua_stackdump(L);
		return luaL_error(L, "Attempt to call an event");
	}


	/* Now we're sane! */
	buf = lua_to_buffer(L, lnode->node, 5, o);
	if (!buf)
		return luaL_error(L, "Serializer failed!");

	/* Let's create a table to store our callback and arg */
	lua_newtable(L);

	/* Push the callback function there */
	lua_pushnumber(L, 1);
	lua_pushvalue(L, 3);
	lua_settable(L, -3);

	/* And the user argument */
	lua_pushnumber(L, 2);
	lua_pushvalue(L, 4);
	lua_settable(L, -3);

	/* And fetch the reference to out table that we'll use in callback */
	callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);
	slog(4, SLOG_DEBUG, "Callback tbl reference: %d", callback_ref);

	ret = aura_core_start_call(lnode->node, o, calldone_cb, (void *)(long)callback_ref, buf);
	if (ret != 0) {
		aura_buffer_release(buf);
		return luaL_error(L, "Async call for %s failed: %s code (%d)", o->name, strerror(-ret), ret);
	}

	return 0;
}