It occurs to me that the apples vs oranges might be using 'delay' and 'flag' (semaphore) interchangeably and they are not the same thing.
Using delays (ex. 'sleep' in VB) is simply a finite pause in execution and using same could cause all of the symptoms described. Based solely on the descriptions provided, I would speculate that delays are being used which cause additional problems wherein use of flags would eliminate the problems altogether. If you are scripting anything, you have access to the method. I have never heard of a 'sync semaphore', or any other specific kind of flag. The programmer makes them up as needed, for the purpose.
In my code, and much of what I have seen of other's code, typically the routine generating the data sets a flag and the routine gathering the data reads the flag. In this way, the routine receiving the data CANNOT act prematurely and there is NO reason to have delays or slow a program to a crawl in an attempt to guarantee the 'race' is won by one contestant or the other.
There are certainly other methods of program control, but unless I encounter some good reason to use an alternate, I stick with flags.
A method to consider in the DRO example is to use a 'comparative change'. If you want to know when a value has changed, just save the old value and compare it with the new until it changes. I use this a lot in MACH3 VB scripts.
OldValue = GetUserDRO(*********x)
NewValue = question "Where do you want to go?" (script will not advance until user answers)
If NewValue != OldValue
do as requested
else
Message ("You are already there")
end
Without an 'event' (user entering data, input going high, etc), you can create a 'flag' on-the-fly
OldValue = GetUserDRO(*********x)
NewValue = Oldvalue
Call routine that will enter new data into the DRO
counter=0
while NewValue == OldValue
NewValue = GetUserDRO(*********x)
counter ++
if counter > 1000 then
break
end
sleep(100) '<- this is a delay
wend
'Blah,blah do other stuff until you need that new DRO number
if counter > 1000 ' routine timed out, so there is no new data
messageText = "Current DRO*********x data unavailable"
DataXReadyFlag = false
else
messageText = "Data X Update verified"
DataXReadyFlag = true
end
' Time to use the data . .
if DataXReadyFlag and AxisEnabled and (whatever else needs to be ready)
do the deed
else
call error handler 'messageText will have the error
end
Note that I have nested 'flags' (not typically a good idea) and that the var 'counter' is actually acting as a flag, but hopefully the method is clear.
This stuff is a PIA and is boring and time consuming, but as has been said, this is the programmer's responsibility.
When I first perused the new API manual, I was pleased and relieved to see that the MACH4 functions have multiple error codes. Most certainly the footprint of professional programming. Yet, I have seen NO code posted since that document was released that actually shows the available error returns being used . . . uh . . including my own

And within that document is fair warning, by function, of which ones do not wait on execution.
the long list on MACH4 functions is in essence, just another of many libraries. The programmer still must write in C and/or Lua to use these routines. The developers of MACH4 cannot dictate how C or Lua work unless they want to write their own compiler. It would seem that writing MACH4 is enough challenge.