Structure as parameter in AfxBeginThread - c++

I try to pass a structure as a parameter.
Global structure:
struct ThreadParams
{
HWND window;
LIB::ServiceContainer* mrt;
};
In the main thread:
ThreadParams threadparams;
threadparams.window = (HWND) GetSafeHwnd();
threadparams.mrt = m_rt;
CWinThread* pthread1;
pthread1 = (CWinThread*) AfxBeginThread(Thread1,(LPVOID)&threadparams,THREAD_PRIORITY_NORMAL,0,0,0);
Outside the class:
UINT Thread1(LPVOID lp)
{
ThreadParams* threadparams = (ThreadParams*) lp;
HWND hmainWindow = threadparams->window;
LIB::ServiceContainer* m_rt = threadparams->mrt;
}
Although it compiles fine, I get an error at runtime (it is an unexpected error) and I guess that I mess up with the pointer m_rt. Do you see any obvious mistakes?

ThreadParams threadparams;
Note that if it is a local variable, and the function which declares it returns after creating the thread, then the thread refers to an object which doesn't exist anymore, as the local variable gets destroyed when the function returns. If that is the case, then create a new instance using new instead as:
ThreadParams * pthreadparams = new ThreadParams();
and pass it to the thread, so that it will exist even if the function which creates the thread returns. Of course, when you're done with it, you've to delete it manually.

You cannot safely access a local variable allocated in a different thread in most cases. By the time Thread1 starts up, the structure has likely already gone out of scope in the main thread. You should find another way, such as allocating the parameters with new in the main thread and deleting them when you're done with them in Thread1.

Related

Why is beginthreadex thread argument variable not updating in parent thread

I have a thread which creates a hidden window for the purpose of receiving WinAPI messages based on power state. I need to get the HWND of the created window from the thread so that I can throw a WM_QUIT message to close the window and end the thread gracefully:
Main:
HWND hiddenWindowHandle = NULL;
HANDLE PowerWindowThreadHandle = (HANDLE)_beginthreadex(0, 0, &windowsPowerThread, (void*)&hiddenWindowHandle, 0, 0);
Thread:
unsigned int __stdcall windowsPowerThread(void* data)
{
HWND hiddenWindowHandle = createHiddenWindow();
HWND hwHandle = *(HWND*)data;
hwHandle = hiddenWindowHandle;
...
The problem is that the hiddenWindowHandle is not being updated with the generated HWND.
I have verified in the thread that it's being created, and I've verified that I'm not trying to access the handle before the thread creates it.
What am I missing here?
Your code lacks the necessary synchronization. What you have here is a data race. Thus, what you get is strictly undefined behavior. What will most likely happen is that the compiler simply does not re-fetch the value of hiddenWindowHandle from memory in every iteration of the loop, since it can simply assume that the value does not change. One possible solution would be to make hiddenWindowHandle an std::atomic and have the main thread perform a busy wait until the value changes from NULL. Alternatively, you could put all access to the shared variable into a critical section locked by a mutex, or use a condition variable to wait for the value to be available.
Edit based on comments:
So if I understand your code correctly, the thread that creates the window receives a pointer to the result variable in the form of a void* and then tries to communicate the result like so:
unsigned int __stdcall windowsPowerThread(void* data)
{
…
HWND hwHandle = *(HWND*)data;
hwHandle = hiddenWindowHandle;
…
}
There's two problems here. First of all, data doesn't point to an HWND, it points to an std::atomic<HWND> now, so you already have undefined behavior there. The main problem, and probably the explanation why your original code didn't just happen to work anyways, despite the data race, is that you create a new local HWND called hwHandle. This local variable is initialized with the value of whatever data points to. You then assign your result to that local variable, but never to the actual result variable.
What you want to do is more something along the lines of
unsigned int __stdcall windowsPowerThread(void* data)
{
…
HWND hiddenWindowHandle = createHiddenWindow(…);
*static_cast<std::atomic<HWND>*>(data) = hiddenWindowHandle;
…
}
You may also want to consider using std::thread instead of the raw CRT functions.

Pass an object to another thread with AfxBeginThread

My program has a callback function which is called to handle notifications that are received in the form of objects. Because we can handle hundreds a second, this callback function handles the events by spawning a separate thread to handle each one. This is the callback function:
void _OnEvent(LPCTSTR eventID, CNotification cNotificaton) {
if (_pActiveDoc) {
Param_Event* p = new Param_Event;
p->pDoc = _pActiveDoc;
p->lpszEventID = eventID;
p->cNotification = cNotification;
AfxBeginThread(ProcessEvent,p);
}
}
My query comes from the fact that is passed to the callback method is initially created on the stack, and is therefore (according to my understanding) limited to the scope of the calling method:
void CallingMethod(CString strEventID) {
CNotification cNotification;
// Fill in the details of the notification
_OnEvent(strEventID,cNotification);
}
CNotification has a full copy constructor, and since the Param_Event object is created on the heap, my belief was that this would allow the original CNotification object to fall out of scope safely, with the spawned thread working from its own "private" CNotification object that exists until the Param_Event object is deleted with delete. The fact is, however, that we are getting (rare but occasional) crashing, and I am wondering if perhaps my belief here is incorrect: is it possible that the spawned thread is still accessing the original object somehow? If this was the case, this would explain the crashing by the rare occurrence of the object both falling out of scope and being overwritten in memory, thus creating a memory access exception.
Could I be right? Is there anything actually wrong with the method I am using? Would it be safer create the notification object on the heap initially (this would mean changing a lot of our code), or building a new object on the heap to pass to the spawned thread?
For reference, here is my ProcessEvent() method:
Param_TelephoneEvent *p = (Param_TelephoneEvent*)lParam;
p->pDoc->OnTelephoneEvent(p->lpszEventID,p->cNotification);
delete p;
return 0;
All advice welcome. Thanks in advance!
Edit: Copy constructor:
CNotification& CNotification::operator=(const CNotification &rhs)
{
m_eamspeMostRecentEvent = rhs.m_eamspeMostRecentEvent;
m_eamtcsCallStatusAtEvent = rhs.m_eamtcsCallStatusAtEvent;
m_bInbound = rhs.m_bInbound;
strcpy(m_tcExtension , rhs.m_tcExtension);
strcpy(m_tcNumber, rhs.m_tcNumber);
strcpy(m_tcName,rhs.m_tcName);
strcpy(m_tcDDI,rhs.m_tcDDI);
strcpy(m_tcCallID,rhs.m_tcCallID);
strcpy(m_tcInterTelEvent,rhs.m_tcInterTelEvent);
m_dTimestamp = rhs.m_dTimestamp;
m_dStartTime = rhs.m_dStartTime;
m_nCallID = rhs.m_nCallID;
return *this;
}

Variables overlap when calling thread twice in C++

I'm having a problem calling a thread more than once and the variables messing up. I'm new to threads, so I'm sure I'm missing something simple.
struct PARAMS
{
time_t secondsAtStart;
};
DWORD WINAPI ProcessChange(void* parameter) {
PARAMS* params = (PARAMS*)parameter;
Sleep(3000);
_tprintf(TEXT("Seconds: (%d)\n"), params->secondsAtStart);
return 0;
}
void FileChanged(CString filename, CString action) {
struct PARAMS *params = NULL;
params = (struct PARAMS *)malloc(sizeof(PARAMS)+1);
params->secondsAtStart = time(null);
// I've also tried it this way.
//PARAMS params;
//params.secondsAtStart = time(NULL);
HANDLE hThread = CreateThread(NULL, 0, ProcessChange, &params, 0, NULL);
// If I uncomment this, it works, but just one thread runs at a time.
//WaitForSingleObject(hThread, INFINITE);
}
If I don't uncomment the WaitForSingleObject, then the secondsAtStart variable gets corrupted. The end result I need is that if FileChanged gets called 3 times right after one another, I'm going to have the first two runs do nothing and the last one do the action.
Thanks,
Ben
Passing addresses of (or references to) local variables of a function, i.e. variables of automatic storage, to a thread causes undefined behaviour if the thread lives longer than the function.
In your code, params points to an object of dynamic storage, but the pointer itself is a local variable. You pass its address &params to the thread. This only works if by waiting for the thread to finish you guarantee the pointer lives longer than the thread. Otherwise it causes undefined behaviour, which quite naturally manifests itself in nonsensical values being printed.
Passing params instead of &params should solve the problem. (Also note that the code as written causes a memory leak; you'll need to make sure you actually free the space allocated after the thread has finished.)

How to access AfxGetMainWnd() from CWinThread?

I'm trying to create a worker thread in a class called ClientManager, but I can't get access to AfxGetMainWnd() from the new CWinThread, i.e:
UINT ClientManager::WorkerThreadProc( LPVOID param ){
ClientManager *pThis = reinterpret_cast<ClientManager*>(param);
return pThis -> DoThreadJob();
}
UINT ClientManager::DoThreadJob(){
createClientSession("1");
return 0;
}
void ClientManager::createThread(){
m_clientManagerThread = AfxBeginThread(WorkerThreadProc,this,0,0,0,NULL);
}
void ClientManager::createClientSession(CString clientID){
if (AfxGetMainWnd()->GetSafeHwnd()== NULL){
_cprintf("NULL");
}
}
Output: NULL
AfxGetMainWnd()->GetSafeHwnd() works in the main thread.
Thanks!
AfxGetApp()->GetMainWnd() works in threads.
No need to store the window handle in a member of ClientManager.
The documentation says:
If AfxGetMainWnd is called from the application's primary thread, it returns the application's main window according to the above rules. If the function is called from a secondary thread in the application, the function returns the main window associated with the thread that made the call.
So you need to make the call from the main thread. Do this just before you call AfxBeginThread and store the resulting window handle in a member of ClientManager. Then your thread can gain access to the window handle via its ClientManager reference.

How to pass parameters to a Thread object?

I'm working with a C++ class-library that provides a Thread base-class where the user has to
implement a run() method.
Is there a recommended way on how to pass parameters to that run() method? Right now
I prefer to pass them via the constructor (as pointers).
I'm not sure about C++, but that's how you would do it in Java. You'd have a class that extends Thread (or implements Runnable) and a constructor with the parameters you'd like to pass. Then, when you create the new thread, you have to pass in the arguments, and then start the thread, something like this:
Thread t = new MyThread(args...);
t.start();
Must be the same in your case.
An alternative is to extend this Thread class to accept a functor as only constructor parameter, so that you can bind any call inside it.
Then the class using threads wont need to inherit from Thread, but only have one (or more) Thread member. The functor calls any start point you want ( some method of the class with any parameters )
Here is a typical pattern:
1) Define a data structure that encapsulates all the data your thread needs
2) In the main thread, instantiate a copy of the data structure on the heap using operator new.
3) Fill in the data structure, cast the pointer to void*, pass the void* to the thread procedure by whatever means you are provided by your thread library.
4) When the worker thread gets the void*, it reinterpret_cast's it to the data structure, and then takes ownership of the object. Meaning when the thread is done with the data, the thread deallocates it, as opposed to the main thread deallocating it.
Here is example code you can compile & test in Windows.
#include "stdafx.h"
#include <windows.h>
#include <process.h>
struct ThreadData
{
HANDLE isRunning_;
};
DWORD WINAPI threadProc(void* v)
{
ThreadData* data = reinterpret_cast<ThreadData*>(v);
if( !data )
return 0;
// tell the main thread that we are up & running
SetEvent(data->isRunning_);
// do your work here...
return 1;
}
int main()
{
// must use heap-based allocation here so that we can transfer ownership
// of this ThreadData object to the worker thread. In other words,
// the threadProc() function will own & deallocate this resource when it's
// done with it.
ThreadData * data = new ThreadData;
data->isRunning_ = CreateEvent(0, 1, 0, 0);
// kick off the new thread, passing the thread data
DWORD id = 0;
HANDLE thread = CreateThread(0, 0, threadProc, reinterpret_cast<void*>(data), 0, &id);
// wait for the worker thread to get up & running
//
// in real code, you need to check the return value from WFSO and handle it acordingly.
// Here I assume the retval is WAIT_OBJECT_0, indicating that the data->isRunning_ event
// has become signaled
WaitForSingleObject(data->isRunning_,INFINITE);
// we're done, wait for the thread to die
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
return 0;
}
A common problem with thread startup is that the arguments passed exist on only the stack in the calling function. Thread startup is often deferred, such that the calling function returns and it is only some time later the thread actually starts - by which time the arguments are no longer in existence.
One solution to this is to create an event and then start the thread, passing the event as one of the arguments. The starting function then waits on the event, which is signalled by the thread when it has completed startup.
You can pass the parameters as members of the thread class. The thread which creates the thread can presumably call other methods and/or call member functions before the thread starts. Therefore it can populate whatever members are necessary for it to work. Then when the run method is called, it will have the necessary info to start up.
I am assuming that you will use a separate object for each thread.
You would normally put all the threads you create into an array, vector etc.
It is ok to pass them via constructor. Just be sure that pointers will live longer than the thread.
Well, I'd prefer to put the parameters in the Start() method, so you can have a protected constructor, and doesn't have to cascade the parameters through derived class constructor.
I'd prolly let my decleration look something like this:
class Thread
{
public:
virtual void Start(int parameterCount, void *pars);
protected:
Thread();
virtual void run(int parameterCount, void *pars) = 0;
}
Just make sure that your parameters are somehow contracted, e.g. #1 will be int, #2 will be a double etc. etc. :)