You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2012/06/12 17:51:36 UTC

[13/50] git commit: First cut at per-thread Lua state

First cut at per-thread Lua state


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/eacaaaf5
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/eacaaaf5
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/eacaaaf5

Branch: refs/heads/jpeach/lua
Commit: eacaaaf58c405d3cad4e251e68b72f10d8827597
Parents: 2c6cca0
Author: James Peach <jp...@apache.org>
Authored: Thu Apr 19 20:32:14 2012 -0700
Committer: James Peach <jp...@apache.org>
Committed: Tue Jun 12 08:48:37 2012 -0700

----------------------------------------------------------------------
 plugins/lua/lua.cc |  126 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 103 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/eacaaaf5/plugins/lua/lua.cc
----------------------------------------------------------------------
diff --git a/plugins/lua/lua.cc b/plugins/lua/lua.cc
index 74a4631..3ca921a 100644
--- a/plugins/lua/lua.cc
+++ b/plugins/lua/lua.cc
@@ -19,9 +19,12 @@
 #include <ts/ts.h>
 #include <ts/remap.h>
 #include <unistd.h>
+#include <string.h>
 #include <pthread.h>
 #include "lapi.h"
 
+static pthread_key_t LuaStateKey;
+
 static void *
 LuaAllocate(void * ud, void * ptr, size_t osize, size_t nsize)
 {
@@ -110,21 +113,14 @@ LuaPluginRemap(lua_State * lua, TSHttpTxn txn, TSRemapRequestInfo * rri)
   return rq->status;
 }
 
-TSReturnCode
-TSRemapInit(TSRemapInterface * api_info, char * errbuf, int errbuf_size)
-{
-  TSDebug("lua", "loading lua plugin");
-  return TS_SUCCESS;
-}
-
-TSReturnCode
-TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errbuf_size)
+static lua_State *
+LuaPluginNewState(void)
 {
   lua_State * lua;
 
   lua = lua_newstate(LuaAllocate, NULL);
   if (lua == NULL) {
-    return TS_ERROR;
+    return NULL;
   }
 
   luaL_openlibs(lua);
@@ -132,27 +128,109 @@ TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errbu
   // Pull up the preload table.
   lua_getglobal(lua, "package");
   lua_getfield(lua, -1, "preload");
+
+  // Pop the 'package' table.
   lua_remove(lua, -2);
 
   // Register LuaApiInit to load the 'ts' package.
   lua_pushcfunction(lua, LuaApiInit);
   lua_setfield(lua, -2, "ts");
 
+  // Pop the 'preload' table.
   lua_pop(lua, -1);
 
-  for (int i = 0; i < argc; ++i) {
+  return lua;
+}
+
+static lua_State *
+LuaPluginNewState(lua_State * orig)
+{
+  lua_State * lua;
+
+  lua = LuaPluginNewState();
+  if (lua == NULL) {
+    return NULL;
+  }
+
+  // Load all the files we loaded to create the original state.
+  lua_getglobal(orig, "__ts_remap_files");
+
+  for (int i = 1; ; ++i) {
+    const char * path;
+    lua_rawgeti(orig, -1, i);
+    path = lua_tostring(orig, -1);
+    if (luaL_dofile(lua, path) != 0) {
+      // If the load failed, it should have pushed an error message.
+      TSError("failed to load Lua file %s: %s", path, lua_tostring(lua, -1));
+      lua_close(lua);
+      lua_pop(orig, 2);
+      return NULL;
+    }
+
+    lua_pop(orig, 1);
+  }
+
+  // Pop the files table.
+  lua_pop(orig, 1);
+
+  if (LuaPluginInit(lua) == TS_SUCCESS) {
+    return lua;
+  } else {
+    lua_close(lua);
+    return NULL;
+  }
+}
+
+void
+TSRemapDeleteInstance(void * ih)
+{
+  lua_State * lua = (lua_State *)ih;
+
+  if (lua) {
+    LuaPluginRelease(lua);
+    lua_close(lua);
+  }
+}
+
+TSReturnCode
+TSRemapInit(TSRemapInterface * api_info, char * errbuf, int errbuf_size)
+{
+  TSDebug("lua", "loading lua plugin");
+  TSReleaseAssert(pthread_key_create(&LuaStateKey, TSRemapDeleteInstance) == 0);
+  return TS_SUCCESS;
+}
+
+TSReturnCode
+TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errsz)
+{
+  lua_State * lua;
+
+  lua = LuaPluginNewState();
+  if (lua == NULL) {
+    return TS_ERROR;
+  }
+
+  // Push a table to save the files that we load.
+  lua_newtable(lua);
+
+  for (int i = 0, j = 0; i < argc; ++i) {
     if (access(argv[i], R_OK) == 0) {
       TSDebug("lua", "%s loading lua file %s", __func__, argv[i]);
       if (luaL_dofile(lua, argv[i]) != 0) {
         // If the load failed, it should have pushed an error message.
-        TSError("error loading %s: %s", argv[i], lua_tostring(lua, -1));
-        lua_pop(lua, 1);
+        strncpy(errbuf, lua_tostring(lua, -1), errsz);
         lua_close(lua);
         return TS_ERROR;
       }
+
+      lua_pushstring(lua, argv[i]);
+      lua_rawseti(lua, -2, ++j);
     }
   }
 
+  // Push the table we loaded into the globals.
+  lua_setglobal(lua, "__ts_remap_files");
+
   if (LuaPluginInit(lua) == TS_SUCCESS) {
     *ih = lua;
     return TS_SUCCESS;
@@ -162,17 +240,19 @@ TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errbu
   }
 }
 
-void
-TSRemapDeleteInstance(void * ih)
-{
-  lua_State * lua = (lua_State *)ih;
-
-  LuaPluginRelease(lua);
-  lua_close(lua);
-}
-
 TSRemapStatus
 TSRemapDoRemap(void * ih, TSHttpTxn txn, TSRemapRequestInfo * rri)
 {
-  return LuaPluginRemap((lua_State *)ih, txn, rri);
+  lua_State * orig;
+  lua_State * lua;
+
+  // Find or clone the per-thread Lua state.
+  orig = (lua_State *)ih;
+  lua = (lua_State *)pthread_getspecific(LuaStateKey);
+  if (!lua) {
+    lua = LuaPluginNewState(orig);
+    pthread_setspecific(LuaStateKey, lua);
+  }
+
+  return LuaPluginRemap(lua, txn, rri);
 }