I’m not saying that you have to. But for a given timer you are very likely to have something that configures and starts the timer and elsewhere something that stops and resets it. That code needs to be atomic, ie all parts of that configuration and initiation operate together.
In my case that’s all done in the Constructor for the socket when the thread instantiates the socket it needs.
Which is fine if it is outside of a preemptive thread. If it is within a preemptive thread then code could be interrupted by other threads or the main thread.
Sure, but they’re not going to steal my timer, are they? This stuff is all supposed to be re-entrant.
Only if they are both using the same timer.
Well, I’m not. The Constructor for the socket instantiates its own timer.
Yes, but Jon, who is having crashes could be. So it could help him.
OK. But the whole point here, then, is that if you use statics in a multi-threaded environment, you’re asking for trouble. In that situation, I would view using semphores to protect something like a timer, an item which is two-a-penny, as a bodge. Much better just have the thread own its own resources and not have the problem in the first place.
No, the whole point is that a timer can be a resource and may require protection just like any other resource. It just depends on how you are using them.
It may do, I agree. I’m just arguing that that would be poor design. IMO.
I’m not here to judge someone’s design. I’m only pointing out that if you have used timers in certain ways it could be causing issues with preemptive threads.
Can’t argue with that.
The actions with my timers are on the main thread. The timer I am executing and manipulating is a property of the object, created in the constructor. The timer is started when I send data to the URLConnection or Socket - This is on the main thread. The timer is stopped in the ContentReceived or DataAvailable even - also on the main thread.
The thread is not touching the timers.
Knock on wood, but I may have found my issue or one of them. The I was using WeakAddress Of for adding the delegate methods for the URLConnection events. I switched to AddressOf and things seem to be more stable. Seems like the URLConnections may be taken down/rebuilt by the OS framework and using WeakAddress seems to cause problems… It’s a guess right now but so far I have not seen a crash since making this change and that was about 8 hours ago.
Timers : fair enough.
That kinda makes sense, if the object is destroyed then the weakref could go back to nil and the object be destructed.
Actually consider this.
Say you have a URLConnection. You have sent a command to a remote server. The server delays sending the connection for a short bit but then sends the data back. In the mean time you have set the URLConnection to NIL and your WeakAddressOf delegate has now been destroyed. However, the OS framework is in the process of sending the data to your URLConnection object but the delegate method is now NIL and BOOM! Crash goes your app.
See this thread I started back in 2015:
Sounds like you did not have any removeHandler ? Which is basicly a requirement.
Actually, Derk I do have RemoveHandlers statements.
So some updates on this after trying multiple different experiments, application runs, etc.
1.) There is definitely a problem with Listbox CellTextPaint Event and preemptive threads. If I allow my Listbox to do painting while my threads are running, I fairly quickly get a “Thread Accessing UI Exception.” And as explained above, the thread is touching nothing in the listbox. The object running the thread however, is touched and utilized in the Listbox CellTextPaint event but other properties are being accessed and nothing in that code touches anything that is working with the thread.
2.) If you create a picture object in a thread and pass it to the main thread to be painted on canvases, it’s best to make a copy of that picture object in the main thread and pass that copy. Or alternatively, make sure you semaphore the picture in the thread and all your canvases. If I don’t do this, I get random crashes in my canvas draw methods.
3.) If you are using URLConnections or TCPSockets in an object (and I think this goes for both threaded and non-threaded apps as all my socket work is on the main thread), don’t use WeakAddressOf when adding handlers for things like ContentRecieved or DataAvailable. Use AddressOf. Then properly remove them when you deconstruct the socket. I can’t validate why but from looking at crash logs, it seems the underlying OS sometimes will destruct the socket or some part of it (the OS - not Xojo) and when this happens the handling method goes away with a WeakRef. This can cause crashes. I can’t properly explain this but after moving to AddressOf, I no longer have the com.apple.CFNetwork.Connection crashes.
After doing these things, my app seems to be running pretty well.
I’m glad to read that your app is now running pretty well. I hope you won’t find other pitfalls.
In my case I always use WeakAddressOf but not with AddHandler. Each socket has a delegate property and invokes that delegate from ContentReceived or Error events.
The delegate property is then set to nil.
I recently discovered that URLConnection already uses a pre-emptive thread (on macOS and iOS) under the hood when calling URLConnection.Send
.
This can be verified by running a pool of N URLConnections and opening macOS Instruments. Multiple CPU cores will be used while multiple sockets are running.
There’s another “less messy” way to do this. Subclass the sockets and convert all of the events to delegates. Once you do that, you don’t have to keep track of how many Add/RemoveHandler calls you have.