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

[12/50] git commit: Better per-thread Lua state

Better 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/f69e100c
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/f69e100c
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/f69e100c

Branch: refs/heads/jpeach/lua
Commit: f69e100c0b6e9c0e3685b5a1dba3f44fab29969d
Parents: eacaaaf
Author: James Peach <jp...@apache.org>
Authored: Thu Apr 19 21:03:38 2012 -0700
Committer: James Peach <jp...@apache.org>
Committed: Tue Jun 12 08:48:37 2012 -0700

----------------------------------------------------------------------
 plugins/lua/lua.cc |   86 +++++++++++++++++++++--------------------------
 1 files changed, 38 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f69e100c/plugins/lua/lua.cc
----------------------------------------------------------------------
diff --git a/plugins/lua/lua.cc b/plugins/lua/lua.cc
index 3ca921a..f967b35 100644
--- a/plugins/lua/lua.cc
+++ b/plugins/lua/lua.cc
@@ -21,10 +21,25 @@
 #include <unistd.h>
 #include <string.h>
 #include <pthread.h>
+#include <string>
+#include <vector>
 #include "lapi.h"
 
 static pthread_key_t LuaStateKey;
 
+struct LuaPluginState
+{
+  typedef std::vector<std::string> pathlist;
+
+  LuaPluginState(unsigned argc, const char ** argv) {
+    for (unsigned i = 0; i < argc; ++i) {
+      paths.push_back(argv[i]);
+    }
+  }
+
+  pathlist paths;
+};
+
 static void *
 LuaAllocate(void * ud, void * ptr, size_t osize, size_t nsize)
 {
@@ -143,7 +158,7 @@ LuaPluginNewState(void)
 }
 
 static lua_State *
-LuaPluginNewState(lua_State * orig)
+LuaPluginNewState(LuaPluginState * remap)
 {
   lua_State * lua;
 
@@ -152,27 +167,19 @@ LuaPluginNewState(lua_State * orig)
     return NULL;
   }
 
-  // Load all the files we loaded to create the original state.
-  lua_getglobal(orig, "__ts_remap_files");
+  for (LuaPluginState::pathlist::const_iterator p = remap->paths.begin(); p < remap->paths.end(); ++p) {
+    if (access(p->c_str(), F_OK) != 0) {
+      continue;
+    }
 
-  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 (luaL_dofile(lua, p->c_str()) != 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));
+      TSDebug("lua", "failed to load Lua file %s: %s", p->c_str(), 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 {
@@ -203,54 +210,37 @@ TSRemapInit(TSRemapInterface * api_info, char * errbuf, int errbuf_size)
 TSReturnCode
 TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errsz)
 {
+  LuaPluginState * remap;
   lua_State * lua;
 
-  lua = LuaPluginNewState();
-  if (lua == NULL) {
-    return TS_ERROR;
-  }
+  // Copy the plugin arguments so that we can use them to allocate a per-thread Lua state. It would be cleaner
+  // to clone a Lua state, but there's no built-in way to do that, and to implement that ourselves would require
+  // locking the template state (we need to manipulate the stack to copy values out).
+  remap = new LuaPluginState((unsigned)argc, (const char **)argv);
 
-  // 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.
-        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;
-  } else {
-    lua_close(lua);
+  // Test whether we can successfully load the Lua program.
+  lua = LuaPluginNewState(remap);
+  if (!lua) {
+    delete remap;
     return TS_ERROR;
   }
+
+  *ih = remap;
+  return TS_SUCCESS;
 }
 
 TSRemapStatus
 TSRemapDoRemap(void * ih, TSHttpTxn txn, TSRemapRequestInfo * 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);
+    LuaPluginState * remap = (LuaPluginState *)ih;
+
+    TSDebug("lua", "allocating new Lua state on thread 0x%llx", (unsigned long long)pthread_self());
+    lua = LuaPluginNewState(remap);
     pthread_setspecific(LuaStateKey, lua);
   }