CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Feb 2010
    Posts
    7

    Suspend Thread when Finished

    Hi,

    I am creating a GUI in Win32 using C-system functions (non-MFC) and would be very grateful for some tips or directions regarding some threading problem i have.

    DESCRIPTION: Just as any Win32 i have a WndProc that controlls the GUI. In this GUI there is a "Thread On/Off"-button that simply starts a thread when pushed, and once pushed again suspends (maybe destroy?) it.

    The Thread is an infinite loop just doing the same procedure over and over again. Because the procedure here is calling some safety critical functions, there is a mutex that is taken and later released.

    QUESTION: The problem is that when the button is pressed to suspend the thread it needs to tell the thread to finish it's current loop (it can't just stop in this procedure) and later release the mutex. When the button is once again pressed the procedure should be starting from the begging. I have some code to show:


    GUI Controller (WndProc):

    Code:
    case WM_COMMAND:
    
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
    
        switch (wmId)
        {
            // The button is pressed
            case IDC_WHEEL_POLL_AND_SEND:
    
                // The Thread doesn't exist
    	    if(pollAndSendThread == NULL)
    	    {
    
    	        // Create the Thread
    	        pollAndSendThread = CreateThread(
    		    NULL,
    		    NULL,
    		    PollnSend,
    		    (LPVOID) hWnd,
    		    0,
    		    NULL);
    
                    // Do some GUI changes
    		SetWindowText(GetDlgItem(hWnd, IDC_WHEEL_POLL_AND_SEND_STATUS_TEXT), "On");
    	    }
    
    	    // ResumeThread returns precious value of suspend count, if 0 then suspend cause it was already running
    	    else if(ResumeThread(pollAndSendThread) == 0 )
    	    {
    	        // Thread was suspended and mutex need to be released and Thread procedure finished
    	    }
    	    else
    	        SetWindowText(GetDlgItem(hWnd, IDC_WHEEL_POLL_AND_SEND_STATUS_TEXT), "On");
    
    	    return TRUE;

    The Thread:

    This is only a simple skeleton for how the thread is going to be. What need to be done is that when the button above is pressed, this thread moves down to the sleep and only then gets suspended, so the procedure is finished and mutex released.

    Code:
    //Poll and send function to be threaded
    DWORD WINAPI PollnSend(LPVOID lpParam){
    
        HRESULT hr;
        DIJOYSTATE2 pJoyState2;
    
        while(true) 
        {
            // "Take" the mutex
            DWORD dwWaitResult = WaitForSingleObject((*g_pJoystick).getMutex(), INFINITE);
    		
    	switch(dwWaitResult)
    	{
    	    //Got access to the mutex
    	    case WAIT_OBJECT_0:
    
    	    try
    	    {
    	        // Simulate critical work that
    		std::cout << "Thread Doing critical work";
    		Sleep(4000);
    	    }
    
    	    // Catch possible errors
    	    catch(...)
    	    {
    	        std::cout << "Catch";
    	    }
    
    	    ReleaseMutex((*g_pJoystick).getMutex());
    
    	    break;
    	    case WAIT_ABANDONED:
    	        std::cout << "Wait abanonded";
    	}
    
            Sleep(5);
        }
        return true;
    }
    I am very grateful for any help! It's possible something quite easy, but i want it to be done in the correct way (Threading can easily be dangerous and our updates every 5 millisecond so if crash is possible it will happen!).

    Regards,

  2. #2
    Join Date
    Dec 2009
    Posts
    161

    Re: Suspend Thread when Finished

    I am not really sure:


    Code:
    #include <windowsx.h>
    
    // Declare
    
    void Cls_OnCommand(HWND hwnd, int message, HWND hwndCtl, UINT codeNotify);
    void method_IDC_WHEEL_POLL_AND_SEND(HWND hwnd);
    
    // Global
    
    volatile bool stopThreadFlag = false;
    HANDLE pollAndSendThread == NULL;
    
    (...)
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch(message)
    	{
    		HANDLE_MSG (hwnd, WM_CREATE, Cls_OnCreate);
    		HANDLE_MSG (hwnd, WM_COMMAND, Cls_OnCommand);
    		HANDLE_MSG (hwnd, WM_DESTROY, Cls_OnDestroy);
    		// ...other messages
    	}
    	return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    (...)
    
    void Cls_OnCommand(HWND hwnd, int message, HWND hwndCtl, UINT codeNotify)
    {
    	switch (message)
    	{
    		case IDC_WHEEL_POLL_AND_SEND:
    			method_IDC_WHEEL_POLL_AND_SEND(hwnd);
    			break;
    
    		case ...
    		break;
    	}
    }
    
    (...)
    
    void method_IDC_WHEEL_POLL_AND_SEND(HWND hWnd)
    {
    	// The Thread doesn't exist
    	if(pollAndSendThread == NULL)
    	{
    		stopThreadFlag = false;
    
    		// Create the Thread
    		pollAndSendThread = CreateThread(NULL,NULL,PollnSend,(LPVOID) hWnd,0,NULL);
    
    		// Do some GUI changes
    		SetWindowText(GetDlgItem(hWnd, IDC_WHEEL_POLL_AND_SEND_STATUS_TEXT), "On");
    	}
    
    	    // ResumeThread
    	else if(ResumeThread(pollAndSendThread) == 0 )
    	{
    		stopThreadFlag = true;
    		// Thread was suspended
    	}
    	else
    	{
    		SetWindowText(GetDlgItem(hWnd, IDC_WHEEL_POLL_AND_SEND_STATUS_TEXT), "On");
    	}
    
    }
    
    (...)
    
    //Poll and send function to be threaded
    DWORD WINAPI PollnSend(LPVOID lpParam){
    
    	HRESULT hr;
    	DIJOYSTATE2 pJoyState2;
    
    	while(1) 
    	{
    
    		if(stopThreadFlag)
    			break;
    
    		// "Take" the mutex
    		DWORD dwWaitResult = WaitForSingleObject((*g_pJoystick).getMutex(), INFINITE);
    		
    		switch(dwWaitResult)
    		{
    			//Got access to the mutex
    			case WAIT_OBJECT_0:
    
    			try
    			{
    				// Simulate critical work that
    				std::cout << "Thread Doing critical work";
    				Sleep(4000);
    			}
    
    			// Catch possible errors
    			catch(...)
    			{
    				std::cout << "Catch";
    			}
    
    			ReleaseMutex((*g_pJoystick).getMutex());
    
    			break;
    
    			case WAIT_ABANDONED:
    			std::cout << "Wait abanonded";
    		}
    
    		Sleep(5);
    	}
    	return true;
    }
    Last edited by THEARTOFWEB; February 16th, 2010 at 08:33 AM.

  3. #3
    Join Date
    Feb 2010
    Posts
    7

    Re: Suspend Thread when Finished

    Thank you for your answer,

    You solution should be working, even if I am somewhat afraid it might have side effects? It also require us to only have one Thread running, which shouldn't be a problem (we only use 1 thread right now) but I don't know what changes will be made in the future. However it's a good solution and I will test it for side effects.

    You also made some really good points in modulating the GUI which I liked (HANDLE_MSG). This makes the GUI more flexible and separated, very nice

    Regards,

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured