1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00

Prevent issues with routine slot recycling.

Prevent possible memory leak on object creation exceptions.
Other miscellaneous changes.
This commit is contained in:
Sandu Liviu Catalin 2020-05-01 01:24:06 +03:00
parent 3e7adb8fea
commit 4a53ec8676
2 changed files with 34 additions and 18 deletions

View File

@ -136,12 +136,12 @@ SQInteger Routine::Create(HSQUIRRELVM vm)
// Is the specified environment a null value? // Is the specified environment a null value?
if (use_root) if (use_root)
{ {
// Preserve the stack state
const StackGuard sg(vm);
// Push the root table on the stack // Push the root table on the stack
sq_pushroottable(vm); sq_pushroottable(vm);
// Attempt to retrieve the table object // Attempt to retrieve the table object
res = sq_getstackobj(vm, -1, &env); res = sq_getstackobj(vm, -1, &env);
// Preserve the stack state
sq_poptop(vm);
} }
// Should we treat it as a valid environment object? // Should we treat it as a valid environment object?
else if (etype != OT_STRING) else if (etype != OT_STRING)
@ -192,7 +192,9 @@ SQInteger Routine::Create(HSQUIRRELVM vm)
// Attempt to create a routine instance // Attempt to create a routine instance
try try
{ {
ClassType< Routine >::PushInstance(vm, new Routine()); DeleteGuard< Routine > dg(new Routine());
ClassType< Routine >::PushInstance(vm, dg.Get());
dg.Release();
} }
catch (const Sqrat::Exception & e) catch (const Sqrat::Exception & e)
{ {

View File

@ -39,6 +39,7 @@ private:
bool mSuspended; // Whether this instance is allowed to receive calls. bool mSuspended; // Whether this instance is allowed to receive calls.
bool mQuiet; // Whether this instance is allowed to handle errors. bool mQuiet; // Whether this instance is allowed to handle errors.
bool mEndure; // Whether this instance is allowed to terminate itself on errors. bool mEndure; // Whether this instance is allowed to terminate itself on errors.
bool mTerminated; // Whether this instance is allowed to terminate itself on errors.
Uint8 mArgc; // The number of arguments that the routine must forward. Uint8 mArgc; // The number of arguments that the routine must forward.
Argument mArgv[14]; // The arguments that the routine must forward. Argument mArgv[14]; // The arguments that the routine must forward.
@ -56,6 +57,7 @@ private:
, mSuspended(false) , mSuspended(false)
, mQuiet(GetSilenced()) , mQuiet(GetSilenced())
, mEndure(false) , mEndure(false)
, mTerminated(false)
, mArgc(0) , mArgc(0)
, mArgv() , mArgv()
{ {
@ -96,19 +98,10 @@ private:
void Init(HSQOBJECT & env, HSQOBJECT & func, HSQOBJECT & inst, Interval intrv, Iterator itr) void Init(HSQOBJECT & env, HSQOBJECT & func, HSQOBJECT & inst, Interval intrv, Iterator itr)
{ {
// Initialize the callback objects // Initialize the callback objects
if (!sq_isnull(env)) mEnv = LightObj{env};
{ mFunc = LightObj{func};
mEnv = LightObj(env);
}
if (!sq_isnull(func))
{
mFunc = LightObj(func);
}
// Associate with the routine instance // Associate with the routine instance
if (!sq_isnull(inst)) mInst = LightObj{inst};
{
mInst = LightObj(inst);
}
// Initialize the routine options // Initialize the routine options
mIterations = itr; mIterations = itr;
mInterval = intrv; mInterval = intrv;
@ -167,14 +160,22 @@ private:
if (SQ_FAILED(res)) if (SQ_FAILED(res))
{ {
// Should we endure the errors? // Should we endure the errors?
if (!mEndure) if (!mEndure && !mTerminated)
{ {
Terminate(); // Destroy our self on error Terminate(); // Destroy our self on error
} }
} }
} }
// See if we are using the slot of a previously terminated routine
if (mTerminated)
{
// The old routine was terminated, we're the new routine and we're not
// We don't touch the iterations and return the interval of the new routine
// to take effect on the next frame
mTerminated = false;
}
// Decrease the number of iterations if necessary // Decrease the number of iterations if necessary
if (mIterations && (--mIterations) == 0) else if (mIterations && (--mIterations) == 0)
{ {
Terminate(); // This routine reached the end of it's life Terminate(); // This routine reached the end of it's life
} }
@ -203,6 +204,8 @@ private:
{ {
Release(); Release();
Clear(); Clear();
// Don't attempt to terminate this routine again
mTerminated = true;
} }
}; };
@ -260,6 +263,17 @@ protected:
public: public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
~Routine()
{
if (m_Slot < SQMOD_MAX_ROUTINES)
{
Terminate();
}
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled) * Copy constructor. (disabled)
*/ */