[med-svn] [aghermann] 24/31: rk1968: mind reentrancy running lua scripts; avoid longjmp.

andrei zavada hmmr-guest at alioth.debian.org
Sun Nov 10 00:34:18 UTC 2013


This is an automated email from the git hooks/post-receive script.

hmmr-guest pushed a commit to branch WIP
in repository aghermann.

commit d4c00349558d1b975b05ca534629058da77fb548
Author: Andrei Zavada <hmmr at ra>
Date:   Sun Nov 10 01:50:45 2013 +0200

    rk1968: mind reentrancy running lua scripts; avoid longjmp.
---
 upstream/src/aghermann/globals.cc       |   23 -------------
 upstream/src/aghermann/globals.hh       |    5 ---
 upstream/src/aghermann/rk1968/rk1968.cc |   54 ++++++++++++++++++++++++-------
 upstream/src/aghermann/rk1968/rk1968.hh |   18 +++++++++--
 4 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/upstream/src/aghermann/globals.cc b/upstream/src/aghermann/globals.cc
index c727cb9..687b5ba 100644
--- a/upstream/src/aghermann/globals.cc
+++ b/upstream/src/aghermann/globals.cc
@@ -20,12 +20,6 @@
 #include <omp.h>
 #endif
 
-extern "C" {
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-}
-
 #include "common/string.hh"
 
 #if HAVE_CONFIG_H && !defined(VERSION)
@@ -40,8 +34,6 @@ gsl_rng *agh::global::rng = nullptr;
 
 int agh::global::num_procs = 1;
 
-lua_State* agh::global::lua_state = nullptr;
-
 
 void
 agh::global::
@@ -72,18 +64,6 @@ init( const string& lf_fname)
                 num_procs = omp_get_max_threads();
         }
 #endif
-
-      // 3. lua
-        {
-                lua_state = lua_open();
-
-                // lua_baselibopen ( lua_state);
-                // luaopen_table   ( lua_state);
-                // luaopen_io      ( lua_state);
-                // luaopen_string  ( lua_state);
-                // luaopen_math    ( lua_state);
-                luaL_openlibs( lua_state);
-        }
 }
 
 
@@ -94,9 +74,6 @@ fini()
         gsl_rng_free( rng);
         rng = nullptr;
 
-        lua_close( lua_state);
-        lua_state = nullptr;
-
         if ( default_log_facility )
                 delete default_log_facility;
         default_log_facility = nullptr;
diff --git a/upstream/src/aghermann/globals.hh b/upstream/src/aghermann/globals.hh
index 22bcbf8..163332c 100644
--- a/upstream/src/aghermann/globals.hh
+++ b/upstream/src/aghermann/globals.hh
@@ -13,9 +13,6 @@
 #define AGH_AGHERMANN_GLOBALS_H_
 
 #include <gsl/gsl_rng.h>
-extern "C" {
-#include <lua.h>
-}
 #include "common/log-facility.hh"
 
 #if HAVE_CONFIG_H && !defined(VERSION)
@@ -40,8 +37,6 @@ void log( agh::log::TLevel, const char* issuer, const char* fmt, ...) __attribut
 #define APPLOG_ERROR(...) do agh::global::log( agh::log::TLevel::error,   LOG_SOURCE_ISSUER, __VA_ARGS__); while (0)
 
 
-extern lua_State* lua_state;
-
 void init( const string& lf_fname);
 void fini();
 
diff --git a/upstream/src/aghermann/rk1968/rk1968.cc b/upstream/src/aghermann/rk1968/rk1968.cc
index 47dbdae..0e9cfca 100644
--- a/upstream/src/aghermann/rk1968/rk1968.cc
+++ b/upstream/src/aghermann/rk1968/rk1968.cc
@@ -34,15 +34,14 @@ extern "C" {
 using namespace std;
 using namespace agh::rk1968;
 
-using agh::global::lua_state;
-
 
 
 CScoreAssistant::
 CScoreAssistant (const string& name_,
                  TExpDirLevel level_, CExpDesign& ED_, const SExpDirLevelId& level_id_)
       : CStorablePPack (common_subdir, name_, level_, ED_, level_id_),
-        status (0)
+        status (0),
+        lua_state (nullptr)
 {
         if ( load() )
                 APPLOG_WARN ("no script loaded from \"%s\"", path().c_str());
@@ -52,6 +51,8 @@ CScoreAssistant::
 ~CScoreAssistant ()
 {
         save();
+        if ( lua_state )
+                lua_close( lua_state);
 }
 
 
@@ -89,6 +90,17 @@ save() const
 }
 
 
+void
+CScoreAssistant::
+lua_init()
+{
+        if ( !lua_state ) {
+                lua_state = luaL_newstate();
+                luaL_openlibs( lua_state);
+        }
+}
+
+
 int
 CScoreAssistant::
 compile()
@@ -99,6 +111,7 @@ compile()
                 return -1;
         }
 
+        lua_init();
         lua_settop( lua_state, 0);
         int ret1 = luaL_loadbuffer(
                 lua_state,
@@ -130,10 +143,14 @@ score( agh::SEpisode& E, int* n_pages_scored_p)
 {
         sepisodep = &E;
 
-        lua_settop( lua_state, 0);
         if ( compile() )
                 return TScoreErrors::no_script;
 
+        if ( !lua_checkstack( lua_state, 3) ) {
+                APPLOG_WARN ("Failed to grow stack for 3 elements");
+                return TScoreErrors::no_script;
+        }
+
         lua_pushlightuserdata( lua_state, this);
         lua_pushcfunction( lua_state, host_get_data);
         lua_pushcfunction( lua_state, host_mark_page);
@@ -196,8 +213,9 @@ host_get_data( lua_State *L)
 
         auto this_p = (CScoreAssistant*)lua_touserdata( L, 1);
         if ( !this_p ) {
+                lua_pushboolean( L, false);
                 lua_pushfstring( L, "Target CScoreAssistant object is NULL");
-                lua_error(L);
+                return 2;
         }
         auto& E = *this_p->sepisodep;
 
@@ -205,13 +223,15 @@ host_get_data( lua_State *L)
 
         auto make_arity_mismatch_return = [&L, &nargsin, &opcode] ( int correct_nargsin)
                 {
+                        lua_settop( L, 0);  // now we can push
                         lua_pushboolean( L, false);
                         APPLOG_WARN ("Bad arity for opcode %d (need %d, got %d)", opcode, correct_nargsin, nargsin);
                         lua_pushfstring( L, "Bad arity for opcode %d (need %d, got %d)", opcode, correct_nargsin, nargsin);
-                        lua_error(L);
+                        return 2;
                 };
         auto make_error_return = [&L] ( const char* fmt, ...) __attribute__ ((format (printf, 2, 3)))
                 {
+                        lua_settop( L, 0);  // now we can push
                         lua_pushboolean( L, false);
                         va_list ap;
                         va_start (ap, fmt);
@@ -219,7 +239,7 @@ host_get_data( lua_State *L)
                         APPLOG_WARN ("%s", E.c_str());
                         lua_pushstring( L, E.c_str());
                         va_end (ap);
-                        lua_error(L);
+                        return 2;
                 };
 #define NEED_ARITY_ATLEAST(A) \
         if ( nargsin < A ) { make_arity_mismatch_return(A); }
@@ -235,6 +255,8 @@ host_get_data( lua_State *L)
 
                 if ( !lua_checkstack( L, 1 + E.recordings.size()) )
                         make_error_return( "Failed to grow stack for %d elements", 1 + (int)E.recordings.size());
+
+                lua_settop( L, 0);  // now we can push
                 lua_pushinteger( L, E.recordings.size());
                 for ( auto& H : E.recordings )
                         lua_pushstring( L, H.first.c_str());
@@ -246,7 +268,7 @@ host_get_data( lua_State *L)
                 NEED_ARITY_EXACT(1);
 
                 const char* type = lua_tostring( L, 3);
-                lua_settop( L, 0);  // now we can push
+                lua_settop( L, 0);
 
                 size_t hh_of_type = 0;
                 for ( auto& H : E.recordings )
@@ -331,6 +353,7 @@ host_get_data( lua_State *L)
                 NEED_ARITY_EXACT(4);
 
                 const char* channel = lua_tostring( L, 3);
+
                 auto Hi = E.recordings.find( sigfile::SChannel (channel));
                 if ( Hi == E.recordings.end() ) {
                         make_error_return( "No such channel (%s)", channel);
@@ -396,7 +419,7 @@ host_get_data( lua_State *L)
 #undef NEED_ARITY_EXACT
 #undef NEED_ARITY_ATLEAST
 
-        return 0; // unreachable because lua_error has a longjmp
+        return 0;
 }
 
 
@@ -408,8 +431,10 @@ host_mark_page( lua_State *L)
         //int nargsin = lua_gettop(L);
         auto this_p = (CScoreAssistant*)lua_touserdata( L, 1);
         if ( !this_p ) {
+                lua_settop( L, 0);
+                lua_pushboolean( L, false);
                 lua_pushfstring( L, "Target CScoreAssistant object is NULL");
-                lua_error(L);
+                return 2;
         }
 
         int page      = lua_tonumber( L, 2);
@@ -419,12 +444,17 @@ host_mark_page( lua_State *L)
         using namespace sigfile;
         CHypnogram& F1 = E.sources.front();
         if ( page < 0 || (size_t)page >= F1.n_pages() ) {
+                APPLOG_WARN ("Page %d out of valid range (%zu is last)", page, F1.n_pages()-1);
+                lua_settop( L, 0);
+                lua_pushboolean( L, false);
                 lua_pushfstring( L, "Invalid page number (%d)", page);
-                lua_error(L);
+                return 2;
         }
         if ( SPage::score_code((SPage::TScore)scorecode) == '?' ) {
+                lua_settop( L, 0);
+                lua_pushboolean( L, false);
                 lua_pushfstring( L, "Invalid score code (%d)", scorecode);
-                lua_error(L);
+                return 2;
         }
 
         F1[page].mark( (SPage::TScore)scorecode);
diff --git a/upstream/src/aghermann/rk1968/rk1968.hh b/upstream/src/aghermann/rk1968/rk1968.hh
index eb1ae63..5bb04ed 100644
--- a/upstream/src/aghermann/rk1968/rk1968.hh
+++ b/upstream/src/aghermann/rk1968/rk1968.hh
@@ -38,11 +38,13 @@ class CScoreAssistant
         explicit CScoreAssistant (const CScoreAssistant& rv)
               : CStorablePPack (common_subdir, rv.name + " (dup)", TExpDirLevel::transient, rv.ED, rv.level_id),
                 status (0),
-                script_contents (rv.script_contents)
+                script_contents (rv.script_contents),
+                lua_state (nullptr)
                 {}
         explicit CScoreAssistant (CExpDesign& ED_, const SExpDirLevelId& level_id_)
               : CStorablePPack (common_subdir, "(unnamed)", TExpDirLevel::transient, ED_, level_id_),
-                status (0)
+                status (0),
+                lua_state (nullptr)
                 {}
 
        ~CScoreAssistant ();
@@ -50,20 +52,26 @@ class CScoreAssistant
         CScoreAssistant&
         operator=( CScoreAssistant&& rv)
                 {
+                        CStorablePPack::operator=( rv);
                         script_contents = move(rv.script_contents);
+                        lua_state = rv.lua_state;
+                        rv.lua_state = nullptr;
                         return *this;
                 }
         CScoreAssistant&
         operator=( const CScoreAssistant& rv)
                 {
+                        CStorablePPack::operator=( rv);
                         script_contents = rv.script_contents;
+                        lua_state = nullptr;
                         return *this;
                 }
 
         bool
         operator==( const CScoreAssistant& rv)
                 {
-                        return script_contents == rv.script_contents;
+                        return  CStorablePPack::operator==( rv) &&
+                                script_contents == rv.script_contents;
                 }
 
         enum TFlags { enofile = 1 << 0, ecompile = 1 << 1, };
@@ -104,6 +112,10 @@ class CScoreAssistant
         agh::SEpisode*
                 sepisodep;
         string  specific_error;
+
+    private:
+        void lua_init();
+        lua_State* lua_state;  // mind reentrancy
 };
 
 

-- 
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/aghermann.git



More information about the debian-med-commit mailing list