Win32ComponentPeer::setTitle blocks forever


#1

Hello, Jucers.

I did in fact get my program working nicely for the Mac, mod the problems I’ve related before.

I went back and rebuild it for Windows - it starts - but then appears to be deadlocked. An earlier build worked fine on Windows. It seems that Win32ComponentPeer::setTitle calls the Windows functions SetWindowText - and this function never returns (and therefore the MessageManagerLock is held forever) - at least, when I use the “Break All” command in Visual Studio 2010, my startup thread always seems to be stuck right there.

Unfortunately, we don’t have a Windows developer in-house any more and I haven’t managed to figure out how this could be - I’m a Windows newbie.

Any hints on how to debug this very gratefully accepted. The application isn’t terminally broken, because it works fine on Mac, and an earlier incarnation with a very similar codebase worked fine on Visual Studio 2010. Of course, a deadlock due to my bad code could easily appear in one system and never in another…


#2

Odd. Win32 can be quite fussy about the fact that all window functions must be called on the message thread, could that be it?


#3

So, wait, it has to be called on the message thread, not just with a MessageManagerLock held??

Oh, dear! If this is true, what other features have this property? I just tend to hold the MessageManagerLock to make these changes, if I know no other locks are held.

Thank goodness I have an easy to way defer method calls to the message manager thread, if so.


#4

Yeah, there are some very old bits of the win32 system that mean only the thread which created a window can be used to manipulate it. Not sure what happens if you fail to comply with that. There are a few places in my code where I’ve worked around this using async callbacks, but I’ve not done that for every possible situation.


#5

That was it, indeed!

Fscking brilliant. I don’t think I never would have gotten it without the hint, I get pretty resourceful when desperate, but it would have been days and at a great cost to my equanimity.

  1. What about a warning in the documentation?
  2. Or, even better, a jassert in the code that makes sure that these calls are, in fact, in the right thread?
  3. Arranging for those calls in Juce to only happen on the right thread might be a lot more work. Also, it means that if you want to do three things, you have to have three asynchronous calls, which is inefficient.

FYI, here’s the code I use to run a function, functor or method in another thread or on the message queue thread. The client code looks like this:rec::thread::callAsync(this, &MyClass::myMethod, myData...);


#6

Glad you fixed it! Good idea about adding some assertions - that’d be easy to do.