correct locking semantics for LuaReference (SGameplay commit in a moment)

This commit is contained in:
Glenn Maynard
2005-06-16 03:13:06 +00:00
parent 63eebeb75e
commit 1e02955e63
4 changed files with 80 additions and 50 deletions
+4 -1
View File
@@ -88,6 +88,8 @@ ActorCommands::ActorCommands( const CString &sCommands )
void ActorCommands::Register() void ActorCommands::Register()
{ {
Lua *L = LUA->Get();
CString sError; CString sError;
if( !LUA->RunScript( m_sLuaFunction, "in", sError, 1 ) ) if( !LUA->RunScript( m_sLuaFunction, "in", sError, 1 ) )
{ {
@@ -95,7 +97,8 @@ void ActorCommands::Register()
} }
/* The function is now on the stack. */ /* The function is now on the stack. */
this->SetFromStack(); this->SetFromStack( L );
LUA->Release( L );
} }
+62 -40
View File
@@ -30,8 +30,10 @@ LuaReference::LuaReference( const LuaReference &cpy )
else else
{ {
/* Make a new reference. */ /* Make a new reference. */
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, cpy.m_iReference ); Lua *L = LUA->Get();
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX ); lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference );
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
LUA->Release( L );
} }
} }
@@ -47,18 +49,20 @@ LuaReference &LuaReference::operator=( const LuaReference &cpy )
else else
{ {
/* Make a new reference. */ /* Make a new reference. */
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, cpy.m_iReference ); Lua *L = LUA->Get();
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX ); lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference );
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
LUA->Release( L );
} }
return *this; return *this;
} }
void LuaReference::SetFromStack() void LuaReference::SetFromStack( Lua *L )
{ {
Unregister(); Unregister();
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX ); m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
} }
void LuaReference::SetFromNil() void LuaReference::SetFromNil()
@@ -69,7 +73,7 @@ void LuaReference::SetFromNil()
void LuaReference::PushSelf( lua_State *L ) const void LuaReference::PushSelf( lua_State *L ) const
{ {
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, m_iReference ); lua_rawgeti( L, LUA_REGISTRYINDEX, m_iReference );
} }
bool LuaReference::IsSet() const bool LuaReference::IsSet() const
@@ -84,9 +88,12 @@ bool LuaReference::IsNil() const
int LuaReference::GetLuaType() const int LuaReference::GetLuaType() const
{ {
this->PushSelf( LUA->L ); Lua *L = LUA->Get();
int iRet = lua_type( LUA->L, -1 ); this->PushSelf( L );
lua_pop( LUA->L, 1 ); int iRet = lua_type( L, -1 );
lua_pop( L, 1 );
LUA->Release( L );
return iRet; return iRet;
} }
@@ -95,7 +102,9 @@ void LuaReference::Unregister()
if( LUA == NULL ) if( LUA == NULL )
return; // nothing to do return; // nothing to do
luaL_unref( LUA->L, LUA_REGISTRYINDEX, m_iReference ); Lua *L = LUA->Get();
luaL_unref( L, LUA_REGISTRYINDEX, m_iReference );
LUA->Release( L );
m_iReference = LUA_NOREF; m_iReference = LUA_NOREF;
} }
@@ -134,42 +143,51 @@ void LuaExpression::SetFromExpression( const CString &sExpression )
void LuaExpression::Register() void LuaExpression::Register()
{ {
Lua *L = LUA->Get();
if( !LUA->RunScript( m_sExpression, "expression", 1 ) ) if( !LUA->RunScript( m_sExpression, "expression", 1 ) )
{ {
this->SetFromNil(); this->SetFromNil();
LUA->Release( L );
return; return;
} }
/* Store the result. */ /* Store the result. */
this->SetFromStack(); this->SetFromStack( L );
LUA->Release( L );
} }
CString LuaData::Serialize() const CString LuaData::Serialize() const
{ {
/* Call Serialize(t), where t is our referenced object. */ /* Call Serialize(t), where t is our referenced object. */
lua_pushstring( LUA->L, "Serialize" ); Lua *L = LUA->Get();
lua_gettable( LUA->L, LUA_GLOBALSINDEX ); lua_pushstring( L, "Serialize" );
lua_gettable( L, LUA_GLOBALSINDEX );
ASSERT_M( !lua_isnil(LUA->L, -1), "Serialize() missing" ); ASSERT_M( !lua_isnil(L, -1), "Serialize() missing" );
ASSERT_M( lua_isfunction(LUA->L, -1), "Serialize() not a function" ); ASSERT_M( lua_isfunction(L, -1), "Serialize() not a function" );
/* Arg 1 (t): */ /* Arg 1 (t): */
this->PushSelf( LUA->L ); this->PushSelf( L );
lua_call( LUA->L, 1, 1 ); lua_call( L, 1, 1 );
/* The return value is a string, which we store in m_sSerializedData. */ /* The return value is a string, which we store in m_sSerializedData. */
const char *pString = lua_tostring( LUA->L, -1 ); const char *pString = lua_tostring( L, -1 );
ASSERT_M( pString != NULL, "Serialize() didn't return a string" ); ASSERT_M( pString != NULL, "Serialize() didn't return a string" );
CString sRet = pString; CString sRet = pString;
lua_pop( LUA->L, 1 ); lua_pop( L, 1 );
LUA->Release( L );
return sRet; return sRet;
} }
void LuaData::LoadFromString( const CString &s ) void LuaData::LoadFromString( const CString &s )
{ {
Lua *L = LUA->Get();
/* Restore the serialized data by evaluating it. */ /* Restore the serialized data by evaluating it. */
CString sError; CString sError;
if( !LUA->RunScript( s, "serialization", sError, 1 ) ) if( !LUA->RunScript( s, "serialization", sError, 1 ) )
@@ -180,7 +198,8 @@ void LuaData::LoadFromString( const CString &s )
FAIL_M( "Unserialization failed" ); FAIL_M( "Unserialization failed" );
} }
this->SetFromStack(); this->SetFromStack( L );
LUA->Release( L );
} }
void LuaData::BeforeReset() void LuaData::BeforeReset()
@@ -203,34 +222,37 @@ void LuaData::Register()
LuaTable::LuaTable() LuaTable::LuaTable()
{ {
lua_newtable( LUA->L ); Lua *L = LUA->Get();
this->SetFromStack(); lua_newtable( L );
this->SetFromStack(L);
LUA->Release( L );
} }
void LuaTable::Set( const CString &sKey ) void LuaTable::Set( Lua *L, const CString &sKey )
{ {
int iTop = lua_gettop( LUA->L ); int iTop = lua_gettop( L );
this->PushSelf( LUA->L ); this->PushSelf( L );
lua_pushstring( LUA->L, sKey ); // push the key lua_pushstring( L, sKey ); // push the key
lua_pushvalue( LUA->L, iTop ); // push the value lua_pushvalue( L, iTop ); // push the value
lua_settable( LUA->L, iTop+1 ); lua_settable( L, iTop+1 );
lua_settop( LUA->L, iTop-1 ); // remove all of the above lua_settop( L, iTop-1 ); // remove all of the above
LUA->Release( L );
} }
void LuaTable::Unset( const CString &sKey ) void LuaTable::Unset( Lua *L, const CString &sKey )
{ {
lua_pushnil( LUA->L ); lua_pushnil( L );
Set( sKey ); Set( L, sKey );
} }
void LuaTable::SetKeyAndValue() void LuaTable::SetKeyAndValue( Lua *L )
{ {
int iTop = lua_gettop( LUA->L ); int iTop = lua_gettop( L );
this->PushSelf( LUA->L ); this->PushSelf( L );
lua_pushvalue( LUA->L, iTop-1 ); // push the value after the table lua_pushvalue( L, iTop-1 ); // push the value after the table
lua_pushvalue( LUA->L, iTop ); // push the key after the value lua_pushvalue( L, iTop ); // push the key after the value
lua_settable( LUA->L, iTop+1 ); lua_settable( L, iTop+1 );
lua_settop( LUA->L, iTop-1 ); // remove all of the above lua_settop( L, iTop-1 ); // remove all of the above
} }
/* /*
+6 -5
View File
@@ -4,6 +4,7 @@
#define LUA_REFERENCE_H #define LUA_REFERENCE_H
struct lua_State; struct lua_State;
typedef lua_State Lua;
class LuaReference class LuaReference
{ {
@@ -17,11 +18,11 @@ public:
/* Create a reference pointing to the item at the top of the stack, and pop /* Create a reference pointing to the item at the top of the stack, and pop
* the stack. */ * the stack. */
void SetFromStack(); void SetFromStack( Lua *L );
void SetFromNil(); void SetFromNil();
/* Push the referenced object onto the stack. If not set (or set to nil), push nil. */ /* Push the referenced object onto the stack. If not set (or set to nil), push nil. */
virtual void PushSelf( lua_State *L ) const; virtual void PushSelf( Lua *L ) const;
/* Return true if set. (SetFromNil() counts as being set.) */ /* Return true if set. (SetFromNil() counts as being set.) */
bool IsSet() const; bool IsSet() const;
@@ -87,14 +88,14 @@ public:
/* Set a key by the given name to a value on the stack, and pop the value /* Set a key by the given name to a value on the stack, and pop the value
* off the stack. */ * off the stack. */
void Set( const CString &sKey ); void Set( Lua *L, const CString &sKey );
/* Unset the given key (set it to nil). */ /* Unset the given key (set it to nil). */
void Unset( const CString &sKey ); void Unset( Lua *L, const CString &sKey );
/* Set a key on the stack to a value on the stack; push the key first. Pop /* Set a key on the stack to a value on the stack; push the key first. Pop
* both the key and the value off the stack. */ * both the key and the value off the stack. */
void SetKeyAndValue(); void SetKeyAndValue( Lua *L );
}; };
#endif #endif
+8 -4
View File
@@ -115,8 +115,10 @@ void Profile::InitGeneralData()
ZERO( m_iNumStagesPassedByPlayMode ); ZERO( m_iNumStagesPassedByPlayMode );
ZERO( m_iNumStagesPassedByGrade ); ZERO( m_iNumStagesPassedByGrade );
lua_newtable( LUA->L ); Lua *L = LUA->Get();
m_SavedLuaData.SetFromStack(); lua_newtable( L );
m_SavedLuaData.SetFromStack( L );
LUA->Release( L );
} }
void Profile::InitSongScores() void Profile::InitSongScores()
@@ -1099,8 +1101,10 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
if( m_SavedLuaData.GetLuaType() != LUA_TTABLE ) if( m_SavedLuaData.GetLuaType() != LUA_TTABLE )
{ {
LOG->Warn( "Profile data did not evaluate to a table" ); LOG->Warn( "Profile data did not evaluate to a table" );
lua_newtable( LUA->L ); Lua *L = LUA->Get();
m_SavedLuaData.SetFromStack(); lua_newtable( L );
m_SavedLuaData.SetFromStack( L );
LUA->Release( L );
} }
} }
} }