Global methods with preemptive threads question

I am not sure I fully understand what is required in my code to be “thread safe”.

I have an app that currently uses threads. Most all of the methods used in those threads are actually in the thread. But some of those “thread methods” call some “global methods” that are not part of the thread… Mostly those global methods do something very simple like string manipulation. They have a few parameters and return a value.

Can these global methods cause problems if they happen to be called at the same time from two different preemptive threads?

1 Like

It all depends on what your global method does.

In general then method with no side effects and no UI is usually thread safe.

2 Likes

No, because each method uses its own set of variables - Xojo methdods are re-entrant (unless you use Statics).

When I was doing this sort of stuff at the hardware level in the 70s, we wrote a small OS for the PDP-11 which provided preemptive threads. The sort of issue to guard against there was for example, where one had a linked list (with backwards and forwards pointers), and wanted to remove an item from it. You rewrite the forward pointer before the item, and rewrite the backward pointer after the item. Whilst in the middle of this, if another thread was able to access this linked list, you’d have a crash because the list was, briefly, broken. The solution to this was simply to disable interrupts before starting the removal, and re-enabling them after.

So far, I’ve not needed exactly this sort of construct in Xojo, but one an example might be if I have an array of workitems. A thread creating a workitem might do:

app.myArray.Add (workitem)

Another thread that is processing the queue might do:

workitem = app.myArray(0)   // Next item to process
app.myArray.RemoveAt(0)     // Remove from queue

Existing threads can be sure that these two statements will complete without being preempted, but if we are using preemptive threads, there will have to be a way to ensure no interruptions for a sequence of code, analagous to disabling interrupts.

1 Like

Thanks for the replies…

This is a Service app so no UI to worry about.

My “global methods” do not access any data beyond the parameters they were passed. So it sounds like they should work OK.

There are going to be challenges to using preemptive threads that we Xojo users never had to consider before, mostly centered around race conditions. The concept that two things can happen independently at the exact same instant has, until now, been foreign, and we will have to take steps to ensure our code protects itself.

Fortunately there will be ways to do that.

Meanwhile, the best advice I can give is, if you don’t truly need preemptive threads, don’t use them. That is, if your thread is just there to keep your UI responsive, for example, and the speed of your app is just fine, stick with cooperative threads.

And if you do want or need preemptive threads, be ready to deal with hard crashes that will require you to take defensive measures or even rethink your code.

2 Likes

This isn’t even close to being true. Xojo code can access global variables, object properties which are not local, etc etc etc. Only method parameters which are both passed by value and which are intrinsic types (string, integer, boolean, a few others; not any object type) are guaranteed to be local scope. This also applies to variables declared in any particular scope, except if they are Static as you noted.

There’s a lot of code out there that will have to be carefully inspected and possibly refactored to be compatible with preemptive threading. The good news is that it should result in more maintainable, robust code if done properly.