Change in osmocom-bb[master]: Allow lua code to register a fd for reading with the runtime

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Fri Aug 24 10:35:22 UTC 2018


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/10439 )

Change subject: Allow lua code to register a fd for reading with the runtime
......................................................................

Allow lua code to register a fd for reading with the runtime

To have bi-directional communication we can pass credentials to the
registry server and now we can register a callback when the registry
is sending data to us.

The callback needs to return if the fd should continue to be selected
as I found no way to push the userdata as parameter on the stack. Lua
code will look like:

  local host, port = "www.osmocom.org", 80
  local tcp = socket.tcp()
  tcp:connect(host, port);
  tcp:send("GET / HTTP/1.0\r\n\r\n");
  local cb = function()
    local s, status, partial = tcp:receive()
    print(s)
    if status == 'closed' then
     tcp:close()
     return 0
    end
    return 1
  end
  local foo = osmo.register_fd(tcp:getfd(), cb)

Change-Id: I8254bdda1df2f8fe0a5eac894b931e7de5b426df
---
M src/host/layer23/src/mobile/script_lua.c
1 file changed, 103 insertions(+), 0 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/src/host/layer23/src/mobile/script_lua.c b/src/host/layer23/src/mobile/script_lua.c
index 088aab3..924ed6e 100644
--- a/src/host/layer23/src/mobile/script_lua.c
+++ b/src/host/layer23/src/mobile/script_lua.c
@@ -28,6 +28,7 @@
 
 #include <osmocom/bb/mobile/primitives.h>
 
+#include <osmocom/core/select.h>
 #include <osmocom/vty/misc.h>
 
 #include <sys/types.h>
@@ -37,6 +38,12 @@
 	int cb_ref;
 };
 
+struct fd_userdata {
+	struct lua_State *state;
+	struct osmo_fd fd;
+	int cb_ref;
+};
+
 static char lua_prim_key[] = "osmocom.org-mobile-prim";
 
 static struct mobile_prim_intf *get_primitive(lua_State *L)
@@ -435,6 +442,100 @@
 	return 1;
 }
 
+static void lua_fd_do_unregister(lua_State *L, struct fd_userdata *fdu) {
+	/* Unregister the fd and forget about the callback */
+	osmo_fd_unregister(&fdu->fd);
+	if (fdu->cb_ref != LUA_NOREF) {
+		luaL_unref(L, LUA_REGISTRYINDEX, fdu->cb_ref);
+		fdu->cb_ref = LUA_NOREF;
+	}
+}
+
+static int lua_fd_cb(struct osmo_fd *fd, unsigned int what) {
+	struct fd_userdata *fdu;
+	lua_State *L;
+	int cb_ref;
+	int err;
+
+	if (!fd->data) {
+		LOGP(DLUA, LOGL_ERROR,
+			"fd callback for fd(%d) but no lua callback\n", fd->fd);
+		return 0;
+	}
+
+	fdu = fd->data;
+	L = fdu->state;
+	cb_ref = fdu->cb_ref;
+	lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref);
+
+	err = lua_pcall(L, 0, 1, 0);
+	if (err) {
+		LOGP(DLUA, LOGL_ERROR, "lua error: %s\n", lua_tostring(L, -1));
+		lua_pop(L, 1);
+	}
+
+	/* Check if we should continue */
+	luaL_argcheck(L, lua_isnumber(L, -1), 1, "needs to be a number");
+	if (lua_tonumber(L, -1) == 1)
+		return 0;
+
+	lua_fd_do_unregister(L, fdu);
+	return 0;
+}
+
+/* Register the fd */
+static int lua_register_fd(lua_State *L)
+{
+	struct fd_userdata *fdu;
+
+	/* fd, cb */
+	luaL_argcheck(L, lua_isnumber(L, -2), 1, "needs to be a filedescriptor");
+	luaL_argcheck(L, lua_isfunction(L, -1), 2, "Callback needs to be a function");
+
+	/* Cretae a table so a user can unregister (and unregister on GC) */
+	fdu = lua_newuserdata(L, sizeof(*fdu));
+	fdu->state = L;
+	fdu->fd.fd = -1;
+	luaL_getmetatable(L, "Fd");
+	lua_setmetatable(L, -2);
+
+	/* Set the filedescriptor */
+	fdu->fd.fd = (int) lua_tonumber(L, -3);
+	fdu->fd.cb = lua_fd_cb;
+	fdu->fd.when = BSC_FD_READ;
+	fdu->fd.data = fdu;
+
+	/* Assuming that an error here will lead to a GC */
+	if (osmo_fd_register(&fdu->fd) != 0) {
+		fdu->cb_ref = LUA_NOREF;
+		lua_pushliteral(L, "Can't register the fd");
+		lua_error(L);
+		return 0;
+	}
+
+	/* Take the callback and keep a reference to it */
+	lua_pushvalue(L, -2);
+	fdu->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+	return 1;
+}
+
+static int lua_fd_unregister(lua_State *L) {
+	struct fd_userdata *fdu;
+
+	luaL_argcheck(L, lua_isuserdata(L, -1), 1, "No userdata");
+	fdu = lua_touserdata(L, -1);
+
+	lua_fd_do_unregister(L, fdu);
+	return 0;
+}
+
+
+static const struct luaL_Reg fd_funcs[] = {
+	{ "unregister", lua_fd_unregister },
+	{ "__gc", lua_fd_unregister },
+};
+
 static const struct luaL_Reg ms_funcs[] = {
 	{ "imsi", lua_ms_imsi },
 	{ "imei", lua_ms_imei },
@@ -452,6 +553,7 @@
 static const struct luaL_Reg osmo_funcs[] = {
 	{ "timeout",	lua_osmo_timeout },
 	{ "unix_passcred", lua_unix_passcred },
+	{ "register_fd", lua_register_fd },
 	{ "ms",	lua_osmo_ms },
 	{ NULL, NULL },
 };
@@ -515,6 +617,7 @@
 	/* Create metatables so we can GC objects... */
 	create_meta_table(L, "Timer", timer_funcs);
 	create_meta_table(L, "MS", ms_funcs);
+	create_meta_table(L, "Fd", fd_funcs);
 
 	/* Remember the primitive pointer... store it in the registry */
 	lua_pushlightuserdata(L, lua_prim_key);

-- 
To view, visit https://gerrit.osmocom.org/10439
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I8254bdda1df2f8fe0a5eac894b931e7de5b426df
Gerrit-Change-Number: 10439
Gerrit-PatchSet: 3
Gerrit-Owner: Holger Freyther <holger at freyther.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180824/210c6e06/attachment.htm>


More information about the gerrit-log mailing list