I had a hard time figuring out why my code didn't work. I tracked the problem down to the vtable generation/population.
Here is a simplified version of my code:
#include <iostream>
#include <functional>
#include <thread>
using namespace std;
typedef std::function<void (void)> MyCallback;
MyCallback clb = NULL;
void callCallbackFromThread(void){
while(clb == NULL);
clb();
}
int someLongTask(void){
volatile unsigned int i = 0;
cout << "Start someLongTask" << endl;
while(i < 100000000)
i++;
cout << "End someLongTask" << endl;
return i;
}
class Base{
public:
Base(){
clb = std::bind(&Base::_methodToCall, this);
cout << "Base-Constructor" << endl;
}
protected:
virtual void methodToCall(void){
cout << "Base methodToCall got called!" << endl;
};
private:
void _methodToCall(void){
methodToCall();
}
};
class Child: public Base{
public:
Child()
: dummy(someLongTask()){
cout << "Child Constructor" << endl;
}
protected:
void methodToCall(void){
cout << "Child methodToCall got called!" << endl;
}
private:
int dummy;
};
int main()
{
thread t(callCallbackFromThread);
Child child;
t.join();
clb();
return 0;
}
When I run this, I sometimes get the result:
Base-Constructor
Start someLongTask
Child methodToCall got called!
End someLongTask
Child Constructor
Child methodToCall got called!
And sometimes this:
Base-ConstructorBase methodToCall got called!
Start someLongTask
End someLongTask
Child Constructor
Child methodToCall got called!
Can someone explain to me why the base-method is called in one case and the child-method in the other? It surely has something to do with the exact time the thread will be executed. To me, it seems, that the vtable isn't set up properly when the thread calls the callback, but I don't understand why.