C++ object creation and thread safety

Programming, for all ages and all languages.
Post Reply
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

C++ object creation and thread safety

Post by durand »

I just saw something very interesting and I wanted to tell someone.

I have a class hierarchy: Thread -> Looper -> Window (ancestor to descendant). And the Looper implements the Thread so that it can run itself (waiting on IPC) in a separate context and the main Application can continue. So, if the Looper thread receives an IPC, it can immediately respond to it while the Application is unaware and doing something else.

My instantiation goes like this:

Window() : Looper() : Thread()

And the Thread is set running before Looper() has finished Constructing.

If a context switch occurs before the Looper() constructor is finished, the actual object is still regarded as only a Thread (with a pure virtual run()) method which Looper was supposed to be overriding.

So, when my Thread stub calls (object)->run()), it looks up in the vtable (which is still only set up to be a Thread) and calls run.. the pure virtual function.

Basically, this means that the object must be fully constructed before anything starts using it.

... err ... which actually sounds very obvious now that I think about it.

But anyway...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C++ object creation and thread safety

Post by distantvoices »

are you going to instantiate the looper as a blocked thread object and unblock it after each and everything is fine and up?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:C++ object creation and thread safety

Post by durand »

Yup, I suppose that's the only way to go.

My threads are created in a suspended state and they have to be manually resumed. However, I was trying to be fancy and do away with the need of Start()'ing Windows.

I guess I'll just have to start the Window as well. It just doesn't seem right to have to start a Window.

My code will now change from:

new Window( Rect(50,50,150,150) );

to:

(new Window( Rect(50,50,150,150) ))->Start();

Nothing fancy. But at least I can be 100% sure that the Thread is calling the Window->run() implementation as opposed to the Looper or Thread implementation.

By the way, this is also the reason why you can't call descendent overridden virtual functions in a base constructor.

So, if all of my classes had a Init() virtual function for which they all provided a implementation, then when Looper() called Init(), it would only call Looper::Init() and not the Window::Init() as you would expect. (Because it's not actually a Window object yet.)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:C++ object creation and thread safety

Post by Solar »

durand wrote: Basically, this means that the object must be fully constructed before anything starts using it.

... err ... which actually sounds very obvious now that I think about it.
;D ;D ;D

That's correct. Neither constructors nor destructors should throw exceptions, since not-quite-constructed and not-quite-destructed objects can't be handled correctly. Throw an exception from a constructor and the object will never get cleaned up. Catching exceptions from a destructor is a tricky thing most people don't know about (or have you ever used [tt]uncaught_exception[/tt]?)

Try to move all "tricky stuff" into plain member functions, and handle constructors / destructors as atomics (i.e., nothing must go wrong).
Every good solution is obvious once you've found it.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C++ object creation and thread safety

Post by distantvoices »

Hm. I'm starting the looper with an explicit ui_start(bool ab_threaded) call. It's rather associated with the appliction than with the window - because one application can of course different windows...

oh - this scheme of things makes popping up windows (other than dialog boxen) a bit complicated once the application s up and running. Well --> no problem, gonna do some tricks! ;-)
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Post Reply