[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