SHARE
TWEET

Critical Section Test

a guest Apr 29th, 2014 23 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <windows.h>
  3. #include <stdio.h>
  4.  
  5. class CSharpScriptFire{
  6.  
  7. public:
  8.  
  9.         CSharpScriptFire(){
  10.                 ZeroMemory(this, sizeof(CSharpScriptFire));
  11.                 InitializeCriticalSection(&this->CS_Exhange);
  12.         }
  13.         ~CSharpScriptFire(){
  14.                
  15.                 if (CriticalExhange)
  16.                         delete[]CriticalExhange;
  17.                 DeleteCriticalSection(&this->CS_Exhange);
  18.                 ZeroMemory(this, sizeof(CSharpScriptFire));
  19.         }
  20.  
  21.         //Check if the exhange has any data and if so copies it to request
  22.         //If this returns true you MUST run MainLoop_SetReturn
  23.         //If it returns false the mainthread should continue as there was no request
  24.         bool MainLoop_GetRequest( char * request );
  25.         //Set the data to be returned to the caller
  26.         bool MainLoop_SetReturn( const char * CSharpRet );
  27.        
  28.         //Call the mainloop from C#
  29.         //Results are copied back into request
  30.         bool CSharpRequest(char * request);
  31.  
  32. private:
  33.         CRITICAL_SECTION CS_Exhange;
  34.         char * CriticalExhange;
  35.         int Stage;
  36. };
  37.  
  38. bool CSharpScriptFire::MainLoop_GetRequest(char * request){
  39.  
  40.         //Enter critical section
  41.         EnterCriticalSection(&this->CS_Exhange);
  42.  
  43.         if (Stage == 1 && CriticalExhange){    
  44.                 strcpy(request, CriticalExhange);
  45.                 delete[]CriticalExhange;
  46.                 CriticalExhange = NULL;
  47.                 //You have to call MainLoop_SetReturn yourself from here on out
  48.                 return true;
  49.         }
  50.  
  51.         //Nothing, leave the critical section
  52.         LeaveCriticalSection(&this->CS_Exhange);
  53.         return false;
  54. }
  55.  
  56. bool CSharpScriptFire::MainLoop_SetReturn(const char * CSharpRet){
  57.  
  58.         //If this runs we're still in the critical section so we don't need to enter it again
  59.  
  60.         CriticalExhange = new char[strlen(CSharpRet) + 1];
  61.         if (!CriticalExhange)return false;
  62.         strcpy(CriticalExhange, CSharpRet);
  63.         Stage = 2;
  64.         LeaveCriticalSection(&this->CS_Exhange);
  65.  
  66. }
  67.  
  68. bool CSharpScriptFire::CSharpRequest(char * request){
  69.  
  70.         EnterCriticalSection(&this->CS_Exhange);
  71.  
  72.         if (CriticalExhange)
  73.                 delete[]CriticalExhange;
  74.  
  75.         //Set the exhange data and flag stage to 1
  76.         CriticalExhange = new char[strlen(request) + 1];
  77.         if (!CriticalExhange)return false;
  78.         strcpy(CriticalExhange, request);
  79.         Stage = 1;
  80.         LeaveCriticalSection(&this->CS_Exhange);
  81.  
  82.         //wait
  83.         while (true){
  84.  
  85.                 EnterCriticalSection(&this->CS_Exhange);
  86.                 if (Stage == 2){
  87.                         break; //We are still in the critical section here
  88.                 }
  89.                 else if (Stage <= 0 || Stage > 2){
  90.                         LeaveCriticalSection(&this->CS_Exhange);
  91.                         return false;
  92.                 }
  93.                 LeaveCriticalSection(&this->CS_Exhange);
  94.         }
  95.  
  96.         if (!CriticalExhange)
  97.                 return false;
  98.  
  99.         //Get the exhange data
  100.         strcpy(request, CriticalExhange);
  101.  
  102.         //Cleanup
  103.         delete[]CriticalExhange;
  104.         CriticalExhange = NULL;
  105.  
  106.         //Return true and leave the critical section
  107.         LeaveCriticalSection(&this->CS_Exhange);
  108.         return true;
  109. }
  110.  
  111. //NWN Stuff down here
  112.  
  113. //The exhange class has to be global or in a class accessible for your wrapper
  114. CSharpScriptFire * CSSF;
  115.  
  116. //This is the c++ wrapper
  117. void CSharpRunScript(const char * str){
  118.  
  119.         char Buffer[512];
  120.         if (!CSSF)
  121.                 return;
  122.  
  123.         strcpy(Buffer,str);
  124.  
  125.         if (CSSF->CSharpRequest(Buffer)){
  126.                 printf("C#: %s\n", Buffer);
  127.         }
  128.         else{
  129.                 printf("C#: %s\n", "Got nothing from C++");
  130.         }
  131. }
  132.  
  133. //This is our test function its really the csharp thread
  134. DWORD WINAPI Testy(LPVOID lpParam){
  135.  
  136.         char Buffer[512];
  137.  
  138.         while (true){
  139.  
  140.                 //This could just aswell be a C# event
  141.                 //For this test its user input using scanf
  142.                 printf("Your text: ");
  143.                 scanf("%s", Buffer);
  144.  
  145.                 //Call the wrapper
  146.                 CSharpRunScript(Buffer);
  147.  
  148.                 //die is the singal to die
  149.                 if (strcmp(Buffer, "die") == 0)
  150.                         break;
  151.         }
  152.  
  153.         return 0;
  154. }
  155.  
  156. void main(){
  157.  
  158.         DWORD TestyThread;
  159.         HANDLE TestThread = CreateThread(NULL, 0, Testy, NULL, CREATE_SUSPENDED, &TestyThread);
  160.  
  161.         CSSF = new CSharpScriptFire;
  162.         char Buffer[512];
  163.  
  164.         //Start the C# thread here for the test
  165.         ResumeThread(TestThread);
  166.  
  167.         while (true){
  168.  
  169.                 //Check if we got something
  170.                 if (CSSF->MainLoop_GetRequest(Buffer)){
  171.  
  172.                         printf("C++: %s\n", Buffer);
  173.  
  174.                         //If the message is die then kill the mainthread after 5 sec
  175.                         if (strcmp(Buffer, "die") == 0){
  176.  
  177.                                 strcpy(Buffer,"I'll now sleep and die in 5 seconds");
  178.                                 CSSF->MainLoop_SetReturn(Buffer);
  179.                                 Sleep(5000);
  180.                                 break;
  181.                         }
  182.  
  183.                         //We sleep a sec here, you'll notice that the C# thread is actually waiting
  184.                         Sleep(1000);
  185.  
  186.                         //Give C# some data
  187.                         sprintf(Buffer,"The text was %u chars long",strlen(Buffer));
  188.  
  189.                         //We have to return something to the threat which is waiting
  190.                         CSSF->MainLoop_SetReturn(Buffer);
  191.                 }      
  192.  
  193.                 //Here you should call the callback to the mainloop proc since
  194.                 //in nwserver this isnt an actual loop
  195.         }
  196.  
  197.         //Clean up our test, CSSF shoudlnt be deleted until C# is dead
  198.         CloseHandle(TestThread );
  199.         delete CSSF;
  200. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top