Thread and Timer Problems in Windows with ShowModalWithin

I’m having strange crashes and exceptions in my Win32 EXE testing under Windows 10. My app makes heavy use of Timers and Threads. A common operation is for a Thread to need to do something UI related, so it starts a Timer which executes on the main event loop, setting a flag when it’s done. The thread sleeps in a loop waiting for the flag to be set.

The symptoms are:

  • mysterious pauses (e.g. it takes 30+ second for a OpenDialog window to show up)
  • crashes
  • Bogus ThreadAccessingUI exceptions
  • Mixed up stack traces.

The mixed up stack is interesting. I’m currently paused in the debugger and the Main thread is showing:

  cTimer.Event.Action // Instance 2
  Foobar()  // paused on a call to Window1.showModalWithin(Window2)  
  cTimer.Event.Action // Instance 1 (cTimer is a custom Timer subclass I made, which uses Delegates to invoke a method called Foobar()

In other words, it appears that Timer Instance 2 is firing within Timer 1’s action event, which is not supposed to happen.

More info:

  • IDE = Xojo 2014 R2.1 running on Mac OS X 10.10.4
  • Remote Debugging to Windows 10 (build 10240)

I’m intrigued by this feedback case #34387, as it sounds quite similar to what I’m seeing. However this is supposedly fixed in 2014 R2.1:

  • 34387 Windows: Initializing COM to single-threaded apartment always for GUI apps, this fixes several unintended side effects like SelectFolder hanging

Ideas:

  • a new Windows 10 bug
  • a bug with ShowModalWithin
  • a bug with OpenDialog
  • a bug with ShowModalWithin when used with OpenDialog
  • a general threading/timer bug?

I’ll do some tests and see if I can narrow it down…

Can you clarify what you mean by that: thread sleeps in a loop?

Something like this:

Thread1.Run
  while not doneFlag
   me.sleep(100)
  wend

IMO there is no need for a flag. I’d suspend and resume the thread.

Regarding the “mixed up stack trace” this is actually easy to reproduce. <https://xojo.com/issue/40213> Not sure if it’s a bug or just a documentation issue however. And since I see this behavior in Cocoa as well, I don’t think it’s necessarily related to my Win32 crashes.

I’m trying to come up with a toy app which demonstrates the crashes in Windows but not having any luck just yet.

Something along this (this is from memory and not tested):

[code]Sub Timer1.Action()

If done Then
Thread1.Resume()
End

End

Sub Thread1.Run()

Timer1.Enabled = True
Self.Suspend()

End[/code]

More info: I realized that I was creating the OpenDialog inside a thread, and then using it within a timer. I tried creating the OpenDialog outside the thread, but there is no change. In the Debugger, I can step through my code and when I hit this line:

    myFolderItem = MyOpenDialog.ShowModal 

The app locks up for 30 seconds with a “Not responding” message showing. After 30 seconds it comes back to life. Very odd.

[quote=202151:@Michael Diehr]More info: I realized that I was creating the OpenDialog inside a thread, and then using it within a timer. I tried creating the OpenDialog outside the thread, but there is no change. In the Debugger, I can step through my code and when I hit this line:

    myFolderItem = MyOpenDialog.ShowModal 

The app locks up for 30 seconds with a “Not responding” message showing. After 30 seconds it comes back to life. Very odd.[/quote]

Would InitialDirectory be on a network folder ?

Aha! I’m doing this in a VMWare Fusion Virtual Machine, using their “Shared Folders” feature, which shares a folder from your Mac hard drive to Windows. I just noticed that the icon had disappeared, and in fact, I was able to see a 30 second freeze using Windows Explorer (e.g. nothing to do with Xojo at all). I copied my files to the Windows 10 VM’s hard drive, and suddenly no more 30 seconds freeze. So the random lockups may simply be a VMWare bug.

So now I can explain 2 of the 4 mystery behaviors. I still have crashes and bogus ThreadAccessingUI exceptions to track down.

[quote=202157:@Michael Diehr]Aha! I’m doing this in a VMWare Fusion Virtual Machine, using their “Shared Folders” feature, which shares a folder from your Mac hard drive to Windows. I just noticed that the icon had disappeared, and in fact, I was able to see a 30 second freeze using Windows Explorer (e.g. nothing to do with Xojo at all). I copied my files to the Windows 10 VM’s hard drive, and suddenly no more 30 seconds freeze. So the random lockups may simply be a VMWare bug.
[/quote]

Any time you use a network folder, you may expect this kind of delays. I routinely see it accessing network printers attached to a Mac from a PC.

Normally I don’t see much of a delay (if any) when using the VM Shared Folder - which is why this was so tricky.

I believe I’ve figured out the cause of the ThreadAccessingUIExceptions and it’s tricky.

Imagine this code:

Thread1.Run
   me.someWindow = someOtherWindow

This code works on the first run, but fails on the second run.

Why?

Although you are not allowed to manipulate GUI objects from within a thread, you are allowed to store pointers to them.

The problem in my case was that on the first run, someWindow was NIL so assigning another Window to it works.

However, on the Second run, someWindow was not nil - in fact, the window had been closed, but I forgot to set someWindow to nil on the prior invocation.

So, on the second time, when I it hits the line me.someWindow = someOtherWindow, someWindow (which was not NIL) is set to nil. This happened to be the last remaining reference to that window, so its destructor was called. However, we are inside a thread at this point, and closing a window inside a thread is a no-no.

Subtle bug, and now I’m thinking it probably exists on the Cocoa side of my application as well, I just never triggered it. (Or, perhaps Cocoa is more tolerant of Closing a Window inside a thread than is Win32?)

I submitted a Feature Request asking for more debug info in the ThreadAccessingUIException object : <https://xojo.com/issue/40216>