|
-
February 16th, 2010, 07:59 AM
#1
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,
-
February 16th, 2010, 08:29 AM
#2
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.
-
February 16th, 2010, 09:43 AM
#3
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|