Advertisement
Guest User

Critical Section Test

a guest
Apr 29th, 2014
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.62 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement