Global semaphore

Post your questions and help other users.

Moderator: Martin

Post Reply
clive.pottinger
Posts: 21
Joined: 16 May 2014 13:18

Global semaphore

Post by clive.pottinger » 23 Feb 2015 20:55

Hello,

I have several flows which may run simultaneously. Each of these flows is trying to manipulate the value of a single global variable. I can see that they are "stepping on each other's toes" by overwriting each other's changes.

I would like to set up some sort of semaphore so that I can be reasonably assured that only one of the flows can update the global variable at a time. I can certainly code something up in a script, but I was wondering if android has something available that Automagic would be able to access. Or if Automagic itself has some way of halting other executing flows until a condition is met.

Does anything like this exist?

Clive

User avatar
MURTUMA
Posts: 697
Joined: 05 Mar 2013 22:43

Re: Global semaphore

Post by MURTUMA » 24 Feb 2015 01:53

clive.pottinger wrote:Or if Automagic itself has some way of halting other executing flows until a condition is met.
Would it be safe to assume you're familiar with Automagic conditions?

There are several action and conditions which with you can control other flows or check if they're enabled, etc. Also setting boolean vars in one flow and checking the value (true/false) in the other might help.

It's hard to give you an exact solution when not knowing how your flows are set up. Also, sometimes simply making the flows differently helps.

clive.pottinger
Posts: 21
Joined: 16 May 2014 13:18

Re: Global semaphore

Post by clive.pottinger » 24 Feb 2015 18:39

Hello Murtuma.

I am familiar with conditions and how to use them. That is not quite the issue here. Perhaps a simplified example of the problem might help.

Imaging a script that performs the following (where global_flowOrder is a list):

Code: Select all

x = global_flowOrder;
y = flow_name;
if (containsElement(x, flow_name))
{
   y = y + " again";
}
global_flowOrder = List addElement(global_flowOrder, y);
Now, we have two flows (FlowA and FlowB) that use this script. The idea is that if we execute FlowA, then FlowB, then FlowA, we should see:

Code: Select all

global_flowOrder = { "FlowA", "FlowB", "FlowA again" }
But, if FlowB and the 2nd FlowA execute the script at the same time, they may both pick up the same value for x ({ "FlowA" }). Assume that the 2nd FlowA gets to last line just a hair ahead of FlowB. Then the final value for global_flowOrder will end up being

Code: Select all

global_flowOrder = { "FlowA", "FlowB" }
FlowA's recording of it's activity was wiped out by FlowB.
To prevent this, I need to make sure that once this script starts, no other instance of this script attempts to get the value of global_flowOrder until the first instance is complete.
This is not easily solved by setting conditions for other scripts to check. Doing that has the same problem: how do I know that 2 scripts didn't check the condition at the same time and both think it is okay to proceed?. To solve this requires a global semaphore.
As I said, I can code a global semaphore - I know how to do that. I just wanted to know if there was some equivalent already built into Android or Automagic that I could use instead. If there is, it would probably be more reliable and require less code than a home-grown solution.

User avatar
Martin
Posts: 4468
Joined: 09 Nov 2012 14:23

Re: Global semaphore

Post by Martin » 24 Feb 2015 20:02

Hi,

A script action itself acquires a global lock when the script is executed so two script actions should not interfere in general.
When multiple actions and conditions are required, you could move the critical part of the flow to its own flow and enable flow option Wait until the currently executing instance has finished. You can use action Execute Flows to execute the sub-flow from your other two flows.

Regards,
Martin

clive.pottinger
Posts: 21
Joined: 16 May 2014 13:18

Re: Global semaphore

Post by clive.pottinger » 24 Feb 2015 20:28

Thanks for the reply, Martin
Martin wrote:A script action itself acquires a global lock when the script is executed so two script actions should not interfere in general.
Hmmm. If that is the case, then I should not see any overwriting of values. Perhaps, then, my issue isn't due to a race condition. I will have to investigate further.

Thanks for the info. It is useful to know that scripts execute under a lock. Now, is that one lock per action script, or a single lock for all action scripts?
FlowAlpha calls action A
FlowBeta calls action A
FlowGamma call action B
If all three flows hit the actions at once, will they execute one at a time (e.g. A then A then B) or can A and B execute at the same time (A & B, then A)?

User avatar
Martin
Posts: 4468
Joined: 09 Nov 2012 14:23

Re: Global semaphore

Post by Martin » 25 Feb 2015 19:22

It's one single lock for all script actions. It's a fair lock so script actions should execute in the same order like they tried to execute a script.
In your example it's A then A then B (not A & B at the same time since this would likely cause problems when different scripts access the same global variables).
It's not really defined which flow arrives first at the script action but let's assume FlowAlpha tries to execute the script first, Beta is second and Gamma comes last. This means FlowAlpha does not have to wait but can execute the script A immediately. FlowBeta will wait with executing the script A until FlowAlpha has finished executing its script A, FlowGamma waits until FlowBeta has finished the script.

clive.pottinger
Posts: 21
Joined: 16 May 2014 13:18

Re: Global semaphore

Post by clive.pottinger » 26 Feb 2015 17:24

Thanks Martin. That answers my questions nicely.

Clive

Post Reply