I'm trying to write a unit test for my FileWatcher class.
FileWatcher derives from a Thread class and uses WaitForMultipleObjects to wait on two handles in its thread procedure:
The handle returned from FindFirstChangeNotification
A handle for an Event that lets me cancel the above wait.
So basically FileWatcher is waiting for whatever comes first: a file change or I tell it to stop watching.
Now, when trying to write code that tests this class I need to wait for it to start waiting.
Peusdo Code:
FileWatcher.Wait(INFINITE)
ChangeFile()
// Verify that FileWatcher works (with some other event - unimportant...)
Problem is that there's a race condition. I need to first make sure that FileWatcher has started waiting (i.e. that its thread is now blocked on WaitForMultipleObjects) before I can trigger the file change in line #2. I don't want to use Sleeps because, well, it seems hacky and is bound to give me problems when debugging.
I'm familiar with SignalObjectAndWait, but it doesn't really solve my problem, because I need it to "SignalObjectAndWaitOnMultipleObjects"...
Any ideas?
Edit
To clarify a bit, here's a simplified version of the FileWatcher class:
// Inherit from this class, override OnChange, and call Start() to turn on monitoring.
class FileChangeWatcher : public Utils::Thread
{
public:
// File must exist before constructing this instance
FileChangeWatcher(const std::string& filename);
virtual int Run();
virtual void OnChange() = 0;
};
It inherits from Thread and implements the thread function, which looks something like this (very simplified):
_changeEvent = ::FindFirstChangeNotificationW(wfn.c_str(), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
HANDLE events[2] = { _changeEvent, m_hStopEvent };
DWORD hWaitDone = WAIT_OBJECT_0;
while (hWaitDone == WAIT_OBJECT_0)
{
hWaitDone = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
if (hWaitDone == WAIT_OBJECT_0)
OnChange();
else
return Thread::THREAD_ABORTED;
}
return THREAD_FINISHED;
Notice that the thread function waits on two handles, one - the change notification, and the other - the "stop thread" event (inherited from Thread).
Now the code that tests this class looks like this:
class TestFileWatcher : public FileChangeWatcher
{
public:
bool Changed;
Event evtDone;
TestFileWatcher(const std::string& fname) : FileChangeWatcher(fname) { Changed = false; }
virtual void OnChange()
{
Changed = true;
evtDone.Set();
}
};
And is invoked from a CPPUnit test:
std::string tempFile = TempFilePath();
StringToFile("Hello, file", tempFile);
TestFileWatcher tfw(tempFile);
tfw.Start();
::Sleep(100); // Ugly, but we have to wait for monitor to kick in in worker thread
StringToFile("Modify me", tempFile);
tfw.evtDone.Wait(INFINITE);
CPPUNIT_ASSERT(tfw.Changed);
The idea is to get rid of that Sleep in the middle.
There's no race, you don't have to wait for the FileWatcher to enter WaitForMultipleObjects. If you perform the change before the function is called, it will simply return immediately.
Edit: I can see the race now. Why don't you move the following line
_changeEvent = ::FindFirstChangeNotificationW(/*...*/);
from the thread function to the constructor of FileChangeWatcher? That way, you can be certain that by the time the StringToFile function is called, the file is already being watched.
You should call FindFirstChangeNotification() in your watcher's constructor and store the handle that it returns for use in your thread function. This will mean that you will catch change events from the moment of construction onwards.
Once your thread has started it simply calls wait on the two handles. If a change occurred before the thread had started up then the handle that FindFirstChangeNotification() returned will be signalled already and the change will be processed. If you wish for the thread to monitor many changes then it should loop and call FindNextChangeNotification() after processing each notification.
Instead could you use a Mutex? Before a thread could access the resources it desire, it would have to lock the Mutex and unlock it for other threads that need the resource.
Call CreateEvent() to create a non-signaled event. When the watcher thread enters its main loop (or whatever), SetEvent(). Meanwhile, in FileWatcher first WaitForSingleObject() on the event, then once that returns, WFMO as you were doing before.
Related
I have a function foo that is called in the UI thread. Inside it, I call functionA whose return value will determine whether I call functionB or not. Inside functionA, I call funcFromAnotherProject which actually runs in a worker thread. I need to wait for this to end before I can proceed with functionC.
void foo() {
bool succeeded = functionA();
if (succeeded) functionB();
}
bool functionA() {
if (someCondition) {
funcFromAnotherProject();
}
return functionC();
}
Fortunately, funcFromAnotherProject can accept a callback parameter so I can actually pass functionC as a callback so the order is preserved. However, if I do this, I won't be able to get functionC's return value which I need in foo.
I then decided to do the following (the bool variable is actually a shared pointer to a class that wraps around a HANDLE but it's too complicated):
bool functionA() {
bool finishedFuncFromAnotherProject = false;
auto callback = [&finishedFuncFromAnotherProject](){
finishedFuncFromAnotherProject = true;
};
if (someCondition) {
funcFromAnotherProject(callback);
waitUntilAboveFuncFinishes();
}
return functionC();
}
The problem with this is that I am calling wait in the UI thread and funcFromAnotherProject calls the callback in the UI thread as well. The callback is never called because the wait is blocking everything else.
Running foo in the worker thread will solve the above problem, however I need to block the UI thread until functionB finishes.
funcFromAnotherProject will always run in a worker thread so I can't change that. If it comes down to it, what I can do is add a flag for funcFromAnotherProject on whether it should run the callback in the UI thread or not. But since this is a utility in our program, I'd rather not touch it.
Is there another way to go about this? I feel like this should be very simple and I'm just overthinking things.
I am trying to make a timer, so after five minutes something happens. The catch is that while the timer is being checked constantly I need other code to be running. I have created a sample below, of how the actually code looks, the function with the timer is in class, so I did the same thing below. Here is the code:
This code assumes all necessary headers are included
Class.h:
class MyClass
{
public:
void TimerFunc(int MSeconds);
};
void MyClass::TimerFunc(int MSeconds)
{
Sleep(MSeconds); //Windows.h
//Event code
return;
}
Main.cpp:
int main()
{
MyClass myClass;
myClass.TimerFunc(300); //300 is 5 minutes
//Here we do not want to wait for the five minutes to pass,
//instead we want to continue the rest of the code and check
//for user input as below
std::cout << "This should print before the Event Code happens.";
}
The problem here is that the code waits for the five minutes to pass, and then continues. I'm not sure if threading would be a good option here, I haven't done much with it before, if anyone could help me with that, or knows a better way to go about it, any help is appreciated.
If you don't mind your Event executing in a different thread-context, you could have your Timer class spawn a thread to do the waiting and then the event-execution; or (on POSIX OS's) set up a SIGALRM signal and have the signal handler do the Event. The downside of that is that if your event-code does anything non-trivial, you'll need to worry about race conditions with the concurrently executing main thread.
The other approach is to have your main thread check the clock every so often, and if the time-to-execute has passed, have your main thread call your Event routine at that time. That has the advantage of automatic thread-safety, but the disadvantage is that you'll have to add that code into your thread's main event loop; you can't easily hide it away inside a class like the one in your example.
With C++11 threads, this would work like this:
int main()
{
MyClass myClass;
thread ti([](MyClass &m){m.TimerFunc(300); }, ref(myClass)); // create and launch thread
// ... code executed concurrently to threaded code
ti.join(); // wait for the thread to end (or you'll crash !!)
}
Add a private member to your class:
atomic<bool> run=true; // designed to avoid race issue with concurrent access
Update its timer function to loop while this variable is true:
void MyClass::TimerFunc(int MSeconds)
{
while (run) {
this_thread::sleep_for(chrono::milliseconds(MSeconds)); // standard sleep instead of microsoft's one
//Event code
}
return;
}
Foresee within the class a member function to stop the threaded loop:
void Stop() {
run = false;
}
Finally update main() to call myClass.Stop() when the timer function is no longer needed (i.e. before calling ti.join() )
EDIT: attention, nasty error to avoid: be careful to refer to ref(myClass) in the thread constructor. If you would forget this, the thread ti would use a reference to a copy of myClass instead of the original object.
I have two threads, lets say thread "A" and thread "B".
Thread "A" post's custom QEvent to thread "B", and then it should wait till thread "B" processes this event.
What I did so far:
My event class:
class IPCMessageEvent : public QEvent
{
public:
IPCMessageEvent(QWaitCondition* pConditions) : QEvent(IPC_MESSAGE_RECEIVED)
, mpWaitCondition(pConditions)
{ };
~IPCMessageEvent()
{
mpWaitCondition->wakeOne();
};
private:
QWaitCondition* mpWaitCondition;
};
My thread "A":
QWaitCondition recvCondition;
IPCMessageEvent* pEvent = new IPCMessageEvent(&recvCondition);
QCoreApplication::postEvent(gpApp, pEvent);
QMutex mutex;
mutex.lock();
recvCondition.wait(&mutex, IPC_MESSAGE_WAIT_TIMEOUT);
My thread "B": Processes the received event and destroyes it. ~IPCMessageEvent destructor is called and therefore wakeOne() will be initiated for the recvCondition in thread "A".
Everything seems to work just fine, it's just one thing!
It looks like sometimes ~IPCMessageEvent is called sooner then expected...
QCoreApplication::postEvent(gpApp, pEvent);
<---- pEvent is already destroyed here ---->
QMutex mutex;
mutex.lock();
So my recvCondition.wait(&mutex, IPC_MESSAGE_WAIT_TIMEOUT); will be locked and will reach the timeout.
Are there any other ways of doing this kind of synchronization?
Or maybe someone have any suggestions how to fix/overcome this problem?
Well, you have a classical race condition. Your thread A may is interrupted directly after posting the event and thread B then processes and destroys it. Since notifications of condition variables have only an effect if somebody is already waiting, you miss the notification and thus your block infinitely.
So you need to lock the mutex before posting the event. However, this requires that your thread B also needs to lock this mutex when processing the event. Otherwise, you cannot prevent the race condition as thread B has no reason to wait for anything (or to know that it should "wait" until thread A is ready waiting on the condition variable).
Alternative:
If you use a signal/slot connection between the two threads (or the objects living in the two threads), you can use a Qt::BlockingQueuedConnection. This ensures that thread A blocks after emitting the signal until the event loop in thread B processed it.
Thanks Johannes,
I would really need to try and use your suggested alternative with signals/slots.
What I did for now is:
I've created a QMutex and boolean flag that are used between thread "A" and thread "B".
bool mIsProcessingMessage;
QMutex mIsProcessingMessageLock;
In thread "A" I'm posting my event like this:
IPCMessageEvent* pEvent = new IPCMessageEvent();
{ // Inform everyone that we will be processing our message.
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = true;
};
QCoreApplication::postEvent(gpApp, pEvent, Qt::HighEventPriority);
forever // Loop until event will get processed.
{
QMutexLocker locker(&mIsProcessingMessageLock);
if (mIsProcessingMessage == false)
break;
::Sleep(2); // Don't load up the CPU.
};
In thread "B" when my event is processed I just set my "mIsProcessingMessage" flag to true like this:
{
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = false;
};
Maybe it's not the best solution, but it works for now ;)
Maybe there is a really simple solution for my problem, but I'm really confused with all the boosts around me.
Here's my problem:
I want to start a task (calculation, file system operations, etc.), raised by a callback system which calls the CallbackReceived function and I want to pass this operation to a thread, typically represented by a member function of an object. The thread isn't guaranteed to finish, so it should have something to cancel it after some time.
Something like (don't know if this is 100% correct):
// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
boost::thread tThread(&MyObject::calculate, *&object);
boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2));
tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));
tThread.join();
}
Basically, a tThread.join()` waits for the return of the thread. While waiting, my main could not receive any callbacks that may come in because it's blocked and sleeps.
So what can one do, to run the thread and not to block the calling initial program while executing the operation?
You can call join just when you need the result of the calculations.
Something like "Future" pattern. Anyway, you would have to make your thread variable global to the CallBackRecieved function (You can write some wrapper).
Note: you can call join, when thread finished its' work - nothing will be blocked.
What do you want to do with the result of calculate?
Your main thread is blocked in the .join().
If you want to handle other callbacks, you have to return to the normal execution flow, waiting for another call.
Then you have to ask yourself what do you do with the result of calculate when it's finished. Maybe the thread can put the result in a shared resource somewhere and finish gracefully.
You must first sort out all what your code is supposed to do ( processing callbacks, starting threads, what to do with the result ) then you can think of implementing it. There are new constructs in boost and C++11 called promise and future that could suit you but first you have to think about what you want.
Actually you could call the callback while your main thread is sleeping. It would just run on the context (stack) of your thread.
You probably don't want to call join at the point you are at but later or never.
Example (pseudocode):
class Worker {
void doWork(void * mainthread){
Main* main = static_cast<Main*>(mainthread);
while(hasWorkTodo){
//work
//inform main
main->callbackwithinformation(information);
}
}
class Main{
atomi_int filesfound;
void main_part(){
//start worker
boost::thread thread(&Worker::doWork, &object, this);
while(hasworktodo){
//do work
//use filesfound here
}
//About to finish make sure we join our thread
thread.join();
}
void callbackwithinformation(int updatedcount){
//here we set a flag or pass some object
//probably will need an atomic operation
filesfound = updatedcount;
}
}
You would define the implementations in cpp and the interface in a h file so no circular dependency would arise, since you are only using Main as a argument in the interface a forward declaration would suffice.
//worker.h
class mainthread;
class Worker {
void doWork(void * mainthread);
}
//worker.cpp
#include "main.h"
void Worker::doWork(/* and so on*/}
//main.h
class Main{
atomi_int filesfound;
void main_part();
void callbackwithinformation(int updatedcount);
}
//main.cpp
//no need for worker.h here
void Main::main_part() /* implementation and so on */
I'm using a QThread and inside its run method I have a timer invoking a function that performs some heavy actions that take some time. Usually more than the interval that triggers the timer (but not always).
What I need is to protect this method so it can be invoked only if it has completed its previous job.
Here is the code:
NotificationThread::NotificationThread(QObject *parent)
: QThread(parent),
bWorking(false),
m_timerInterval(0)
{
}
NotificationThread::~NotificationThread()
{
;
}
void NotificationThread::fire()
{
if (!bWorking)
{
m_mutex.lock(); // <-- This is not protection the GetUpdateTime method from invoking over and over.
bWorking = true;
int size = groupsMarkedForUpdate.size();
if (MyApp::getInstance()->GetUpdateTime(batchVectorResult))
{
bWorking = false;
emit UpdateNotifications();
}
m_mutex.unlock();
}
}
void NotificationThread::run()
{
m_NotificationTimer = new QTimer();
connect(m_NotificationTimer,
SIGNAL(timeout()),
this,
SLOT(fire(),
Qt::DirectConnection));
int interval = val.toInt();
m_NotificationTimer->setInterval(3000);
m_NotificationTimer->start();
QThread::exec();
}
// This method is invoked from the main class
void NotificationThread::Execute(const QStringList batchReqList)
{
m_batchReqList = batchReqList;
start();
}
You could always have a thread that needs to run the method connected to an onDone signal that alerts all subscribers that it is complete. Then you should not run into the problems associated with double lock check and memory reordering. Maintain the run state in each thread.
I'm assuming you want to protect your thread from calls from another thread. Am I right? If yes, then..
This is what QMutex is for. QMutex gives you an interface to "lock" the thread until it is "unlocked", thus serializing access to the thread. You can choose to unlock the thread until it is done doing its work. But use it at your own risk. QMutex presents its own problems when used incorrectly. Refer to the documentation for more information on this.
But there are many more ways to solve your problem, like for example, #Beached suggests a simpler way to solve the problem; your instance of QThread would emit a signal if it's done. Or better yet, make a bool isDone inside your thread which would then be true if it's done, or false if it's not. If ever it's true then it's safe to call the method. But make sure you do not manipulate isDone outside the thread that owns it. I suggest you only manipulate isDone inside your QThread.
Here's the class documentation: link
LOL, I seriously misinterpreted your question. Sorry. It seems you've already done my second suggestion with bWorking.