From 984df35414fdfb05cc02e6140ba511747134f8ab Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Mon, 9 Jul 2007 06:03:04 +0000 Subject: [PATCH] Fixed amb581 - reentrancy problems with Call_Finish() --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401088 --- core/smn_functions.cpp | 5 ++- plugins/testsuite/callfunctest.sp | 69 ++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/core/smn_functions.cpp b/core/smn_functions.cpp index cc20016f..dd336f63 100644 --- a/core/smn_functions.cpp +++ b/core/smn_functions.cpp @@ -75,6 +75,7 @@ inline void ResetCall() { s_CallStarted = false; s_pFunction = NULL; + s_pForward = NULL; s_pCallable = NULL; } @@ -542,14 +543,14 @@ static cell_t sm_CallFinish(IPluginContext *pContext, const cell_t *params) if (s_pFunction) { IPluginFunction *pFunction = s_pFunction; + ResetCall(); err = pFunction->Execute(result); } else if (s_pForward) { IForward *pForward = s_pForward; + ResetCall(); err = pForward->Execute(result, NULL); } - ResetCall(); - return err; } diff --git a/plugins/testsuite/callfunctest.sp b/plugins/testsuite/callfunctest.sp index 93bc379b..e983d9a1 100644 --- a/plugins/testsuite/callfunctest.sp +++ b/plugins/testsuite/callfunctest.sp @@ -12,6 +12,7 @@ public Plugin:myinfo = public OnPluginStart() { RegServerCmd("test_callfunc", Command_CallFunc); + RegServerCmd("test_callfunc_reentrant", Command_ReentrantCallFunc); } public OnCallFuncReceived(num, Float:fnum, String:str[], String:str2[], &val, &Float:fval, array[], array2[], size, hello2[1]) @@ -40,9 +41,9 @@ public OnCallFuncReceived(num, Float:fnum, String:str[], String:str2[], &val, &F } /* This shouldn't get copied back */ - StrCopy(str, strlen(str) + 1, "Yeti"); + strcopy(str, strlen(str) + 1, "Yeti"); /* This should get copied back */ - StrCopy(str2, strlen(str2) + 1, "Gaben is fat."); + strcopy(str2, strlen(str2) + 1, "Gaben is fat."); /* This should get copied back */ array[0] = 5; @@ -53,6 +54,45 @@ public OnCallFuncReceived(num, Float:fnum, String:str[], String:str2[], &val, &F return 42; } +public OnReentrantCallReceived(num, String:str[]) +{ + new err, ret; + + PrintToServer("Inside OnReentrantCallReceived..."); + + PrintToServer("num = %d (expected: %d)", num, 7); + PrintToServer("str[] = \"%s\" (expected: \"%s\")", str, "nana"); + + new Function:func = GetFunctionByName(INVALID_HANDLE, "OnReentrantCallReceivedTwo"); + + if (func == INVALID_FUNCTION) + { + PrintToServer("Failed to get the function id of OnReentrantCallReceivedTwo"); + return 0; + } + + PrintToServer("Calling OnReentrantCallReceivedTwo..."); + + Call_StartFunction(INVALID_HANDLE, func); + Call_PushFloat(8.0); + err = Call_Finish(ret); + + PrintToServer("Call to OnReentrantCallReceivedTwo has finished!"); + PrintToServer("Error code = %d (expected: %d)", err, 0); + PrintToServer("Return value = %d (expected: %d)", ret, 707); + + return 11; +} + +public OnReentrantCallReceivedTwo(Float:fnum) +{ + PrintToServer("Inside OnReentrantCallReceivedTwo..."); + + PrintToServer("fnum = %f (expected: %f)", fnum, 8.0); + + return 707; +} + public Action:Command_CallFunc(args) { new a = 62; @@ -102,3 +142,28 @@ public Action:Command_CallFunc(args) return Plugin_Handled; } + +public Action:Command_ReentrantCallFunc(args) +{ + new err, ret; + new Function:func = GetFunctionByName(INVALID_HANDLE, "OnReentrantCallReceived"); + + if (func == INVALID_FUNCTION) + { + PrintToServer("Failed to get the function id of OnReentrantCallReceived"); + return Plugin_Handled; + } + + PrintToServer("Calling OnReentrantCallReceived..."); + + Call_StartFunction(INVALID_HANDLE, func); + Call_PushCell(7); + Call_PushString("nana"); + err = Call_Finish(ret); + + PrintToServer("Call to OnReentrantCallReceived has finished!"); + PrintToServer("Error code = %d (expected: %d)", err, 0); + PrintToServer("Return value = %d (expected: %d)", ret, 11); + + return Plugin_Handled; +}