Fixed failed timers leaking dangling plugin references (bug 3381).
authorDavid Anderson <dvander@alliedmods.net>
Wed Oct 29 01:27:56 2008 -0700 (2008-10-29)
changeset 237985c7816b2f08
parent 2378 d812052c5821
child 2381 492af2deed7b
Fixed failed timers leaking dangling plugin references (bug 3381).
core/smn_timers.cpp
     1.1 --- a/core/smn_timers.cpp	Mon Oct 27 02:02:14 2008 -0500
     1.2 +++ b/core/smn_timers.cpp	Wed Oct 29 01:27:56 2008 -0700
     1.3 @@ -160,16 +160,19 @@
     1.4  		}
     1.5  	}
     1.6  
     1.7 -	if ((herr=g_HandleSys.FreeHandle(pInfo->TimerHandle, &sec)) != HandleError_None)
     1.8 +	if (pInfo->TimerHandle != BAD_HANDLE)
     1.9  	{
    1.10 -		g_DbgReporter.GenerateError(pInfo->pContext, 
    1.11 -									pInfo->Hook->GetFunctionID(), 
    1.12 -									SP_ERROR_NATIVE, 
    1.13 -									"Invalid timer handle %x (error %d) during timer end, displayed function is timer callback, not the stack trace", 
    1.14 -									pInfo->TimerHandle, 
    1.15 -									herr);
    1.16 -		return;
    1.17 +		if ((herr=g_HandleSys.FreeHandle(pInfo->TimerHandle, &sec)) != HandleError_None)
    1.18 +		{
    1.19 +			g_DbgReporter.GenerateError(pInfo->pContext, 
    1.20 +				pInfo->Hook->GetFunctionID(), 
    1.21 +				SP_ERROR_NATIVE, 
    1.22 +				"Invalid timer handle %x (error %d) during timer end, displayed function is timer callback, not the stack trace", 
    1.23 +				pInfo->TimerHandle, 
    1.24 +				herr);
    1.25 +		}
    1.26  	}
    1.27 +
    1.28  	DeleteTimerInfo(pInfo);
    1.29  }
    1.30  
    1.31 @@ -206,6 +209,24 @@
    1.32  
    1.33  	hndl = g_HandleSys.CreateHandle(g_TimerType, pInfo, pCtx->GetIdentity(), g_pCoreIdent, NULL);
    1.34  
    1.35 +	/* If we can't get a handle, the timer isn't refcounted against the plugin and 
    1.36 +	 * we need to bail out to prevent a crash.
    1.37 +	 */
    1.38 +	if (hndl == BAD_HANDLE)
    1.39 +	{
    1.40 +		/* Free this for completeness. */
    1.41 +		if (flags & TIMER_HNDL_CLOSE)
    1.42 +		{
    1.43 +			HandleSecurity sec(pCtx->GetIdentity(), g_pCoreIdent);
    1.44 +			g_HandleSys.FreeHandle(params[3], &sec);
    1.45 +		}
    1.46 +		/* Zero everything so there's no conflicts */
    1.47 +		memset(pInfo, 0, sizeof(TimerInfo));
    1.48 +		g_Timers.KillTimer(pTimer);
    1.49 +
    1.50 +		return pCtx->ThrowNativeError("Could not create timer, no more handles");
    1.51 +	}
    1.52 +
    1.53  	pInfo->UserData = params[3];
    1.54  	pInfo->Flags = flags;
    1.55  	pInfo->TimerHandle = hndl;