Xojo Developer Conference
25/27th April 2018 in Denver.
MBS Xojo Conference
6/7th September 2018 in Munich, Germany.

Code Flow: threads call a global method... (Real Studio network user group Mailinglist archive)

Back to the thread list
Previous thread: Webcam on Windows
Next thread: [ANN] ComplexMatrix Plugin 2.8


Re: Using GetFolderItem with wildcards?   -   Garth Hjelte
  Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   Norman Palardy
    Re: Code Flow: threads call a global method...   -   Russ Lunn
     Re: Code Flow: threads call a global method...   -   Metsis
   Re: Code Flow: threads call a global method...   -   Michael Diehr
   Re: Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   Norman Palardy
   Re: Code Flow: threads call a global method...   -   Michael Diehr
   Re: Code Flow: threads call a global method...   -   Michael Diehr
   Re: Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   Norman Palardy
   Re: Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   Norman Palardy
   Re: Code Flow: threads call a global method...   -   Andrew Keller
   Re: Code Flow: threads call a global method...   -   Michael Diehr
   Re: Code Flow: threads call a global method...   -   Charles Yeomans
   Re: Code Flow: threads call a global method...   -   Norman Palardy
   Re: Code Flow: threads call a global method...   -   devmllst yahoo.de
   Re: Code Flow: threads call a global method...   -   Charles Yeomans

Code Flow: threads call a global method...
Date: 01.08.10 15:07 (Sun, 1 Aug 2010 16:07:01 +0200)
From: devmllst yahoo.de
Supposed I have a method "Logit(theMsg)" in a module to log messages to a file. What happens when this method is called by different threads at the "same" time (Logit hasn't finished, but get's again invoked from another thread)?

Dim theAnswer as integer
Select Case theAnswer
Case 1
Global properties are unique always, but global methods are not. They are internally instantiated like new objects if they are not called from the main thread.

Case 2
Global methods are guaranteed to finish their execution, no matter how many other calls are waiting. They are FIFO-style.

Case 3
They are LIFO-style. Your local "theMsg"-variable will be overwritten by the later call - effectively resulting in two identical log messages.

Case 4
Isn't it sunday?
// Yes, but this is THE opportunity to make the shortest answer ever!

End select


Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 22:05 (Sun, 1 Aug 2010 23:05:33 +0200)
From: devmllst yahoo.de
On Aug 1, 2010, at 22:28, Michael Diehr wrote:

> #pragma DisableBackgroundTasks
> and
> #pragma BackgroundTasks FALSE
>
> both disable yields in the *current method only*.
>
> So if your method calls anything else which yields, it will yield.
>
> Norman's suggestion to use semaphores is correct, but in practice it's a PITA and has performance issues too -- it's much more convenient to be able to write methods that guarantee atomic execution. (This is somewhat similar to DBMBS issues : if an operation is guaranteed to be atomic, then it's easy to use, but if it's not than you have to set it up as a Transaction which is generally much more work).
>
> Idea: maybe we need a "super" version of this call, such as
>
> #pragma DisableAllBackgroundTasks
>
> which would prevent yielding in this method *and all sub-methods* until the current method exited, or
> until a call to #pragma EnableAllBackgroundTasks

Enlightening, thanks!
It seems I really should better use a CriticalSection* instead of DisableBackgroundTasks.
I just read the LangRev about it again and I hope I understand correctly how it works:

My calling chain:
ThreadX --> Method1 --> Method2
In Method2 (where the looping may occur and the file writing) I call CriticalSection.Enter()
At the end of Method2 I call CriticalSection.Leave()
The benefit, as I understand it, would be that:
- Log messages are in correct order because another thread would just wait until CriticalSection.Leave().
- Other parts of the app are not dead (quite the opposite because the loop in Method2 gives opportunity for context switch).
Did I get it right?

Kind regards
Christian

* I read the LangRev about the Semaphore not the first time, but I still don't get how exactly it is supposed to work. The description is too abstract, and the example unnecessary complicated.
The CriticalSection documentation is quite short and with no examples.
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 21:47 (Sun, 1 Aug 2010 14:47:18 -0600)
From: Norman Palardy

On Aug 1, 2010, at 2:28 PM, Michael Diehr wrote:

> Norman's suggestion to use semaphores is correct, but in practice
> it's a PITA and has performance issues too -- it's much more
> convenient to be able to write methods that guarantee atomic
> execution. (This is somewhat similar to DBMBS issues : if an
> operation is guaranteed to be atomic, then it's easy to use, but if
> it's not than you have to set it up as a Transaction which is
> generally much more work).

Writing properly behaved multithreaded applications IS hard work
No easy way around that

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 22:34 (Sun, 01 Aug 2010 22:34:37 +0100)
From: Russ Lunn

> Writing properly behaved multithreaded applications IS hard work
> No easy way around that

Amen to that. Just because a multicore/multicpu system costs $€¥ 1000, doesn't mean to say that programming it is easy. I think we (programmers) should stop pretending that what we do is easy. It's getting harder by the day.

I accept that some programs that are single user are not too complicated, but as soon as you have concurrent users and a database it's a minefield
regardless of language.

And once you've written it and the client is happy, the next question is "can we web enable it?". As if that's a trivial matter.

-R

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 03.08.10 20:38 (Tue, 03 Aug 2010 22:38:10 +0300)
From: Metsis
2.8.2010 0.34, Russ Lunn kirjoitti:
> ...the next question is "can we web enable it?". As if that's a trivial matter.

Hey! We have Yuma! As in http://www.yumadev.com/

Metsis


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 21:28 (Sun, 1 Aug 2010 13:28:06 -0700)
From: Michael Diehr
On Aug 1, 2010, at 1:11 PM, <email address removed> wrote:

> On Aug 1, 2010, at 20:07, Michael Diehr wrote:
>
>> On Aug 1, 2010, at 10:42 AM, <email address removed> wrote:
>>>> On Aug 1, 2010, at 19:29, Norman Palardy wrote:
>>>
>>>> disable background tasks in lg_out and that should make that NOT yield to other threads
>>>
>>> I will do so. Thanks to all!
>>
>> Just to be clear: this will work as long as lg_out (and any method it calls) does not use Introspection, StyledText, (per Norman, some Database calls,) and perhaps some other areas of the framework.
> Introspection?? Maybe in five years... ;-)
>
> I start to bang my head. I understand your reply to Norman so that you are not happy that RB yields on undocumented things, and at wrong things.
> Ok, but doesn't DisableBackgroundTasks disables ALL yielding? It is not safe?
> And yes, I use StyledText in the TextArea.

#pragma DisableBackgroundTasks
and
#pragma BackgroundTasks FALSE

both disable yields in the *current method only*.

So if your method calls anything else which yields, it will yield.

Norman's suggestion to use semaphores is correct, but in practice it's a PITA and has performance issues too -- it's much more convenient to be able to write methods that guarantee atomic execution. (This is somewhat similar to DBMBS issues : if an operation is guaranteed to be atomic, then it's easy to use, but if it's not than you have to set it up as a Transaction which is generally much more work).

Idea: maybe we need a "super" version of this call, such as

#pragma DisableAllBackgroundTasks

which would prevent yielding in this method *and all sub-methods* until the current method exited, or
until a call to #pragma EnableAllBackgroundTasks


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 21:11 (Sun, 1 Aug 2010 22:11:15 +0200)
From: devmllst yahoo.de
On Aug 1, 2010, at 20:07, Michael Diehr wrote:

> On Aug 1, 2010, at 10:42 AM, <email address removed> wrote:
>>> On Aug 1, 2010, at 19:29, Norman Palardy wrote:
>>
>>> disable background tasks in lg_out and that should make that NOT yield to other threads
>>
>> I will do so. Thanks to all!
>
> Just to be clear: this will work as long as lg_out (and any method it calls) does not use Introspection, StyledText, (per Norman, some Database calls,) and perhaps some other areas of the framework.
Introspection?? Maybe in five years... ;-)

I start to bang my head. I understand your reply to Norman so that you are not happy that RB yields on undocumented things, and at wrong things.
Ok, but doesn't DisableBackgroundTasks disables ALL yielding? It is not safe?
And yes, I use StyledText in the TextArea.

Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 21:09 (Sun, 1 Aug 2010 14:09:24 -0600)
From: Norman Palardy

On Aug 1, 2010, at 12:07 PM, Michael Diehr wrote:

> On Aug 1, 2010, at 10:42 AM, <email address removed> wrote:
>>> On Aug 1, 2010, at 19:29, Norman Palardy wrote:
>>
>>> disable background tasks in lg_out and that should make that NOT
>>> yield to other threads
>>
>> I will do so. Thanks to all!
>
> Just to be clear: this will work as long as lg_out (and any method
> it calls) does not use Introspection, StyledText, (per Norman, some
> Database calls,) and perhaps some other areas of the framework.

Write the code in a way you make no assumptions about what will /
won't yield, use a semaphore if needed, and you should be safe
regardless of what does / does not yield.

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 19:07 (Sun, 1 Aug 2010 11:07:24 -0700)
From: Michael Diehr
On Aug 1, 2010, at 10:42 AM, <email address removed> wrote:
>> On Aug 1, 2010, at 19:29, Norman Palardy wrote:
>
>> disable background tasks in lg_out and that should make that NOT yield to other threads
>
> I will do so. Thanks to all!

Just to be clear: this will work as long as lg_out (and any method it calls) does not use Introspection, StyledText, (per Norman, some Database calls,) and perhaps some other areas of the framework.
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 19:05 (Sun, 1 Aug 2010 11:05:42 -0700)
From: Michael Diehr
On Aug 1, 2010, at 9:41 AM, Norman Palardy wrote:

>
> On Aug 1, 2010, at 10:16 AM, Michael Diehr wrote:
>
>> Norman says "if it does not contain any loops" -- ahem. One of my pet peeves here is that in an app of any non-trivial complexity, this claim is only true for interesting values of "truth" :)
>>
>> Specifically, there are places in the RB framework where the framework yields and you can't do a thing about it. I've ran into this with StyledText and Introspection, but I suspect there are others too (database?).
>>
>> In fact, when I ran into these issues it was a very similar situation: I had a global "log" command which would log information, and had options to update a log window with info about the objects being logged -- this used both styledText and Introspection of course, and hilarity ensued until I figured out why my threads were all mangled.
>
> IMHO logging should be small fast tight and not involve styled text or introspection.

Well, I simplified (lied) a little bit here -- the introspection was happening in a class object Getter, not directly in the logging code itself. The point remains, however that if you can't rely on a well-documented, consistent, sensible yielding behavior, it's really really hard to write a cooperatively-threaded app.

Yielding inside Introspection... is just wrong. Introspection *must* be atomic by its very definition -- it makes no sense to say "what is the status of this object(class,property...) right now" when "now" is not a point in time. <feedback://showreport?report_id‚91> is proof of this.

> Why ? Not keeping it small fast and tight can introduce timing differences which may be relevant to tracking down an issue.
>
> I've seen this all to often where inserting some code, like a logger, makes things work and when removing it the code being examined fails again.

Agreed, although sometimes those timing differences can *reveal* latent bugs that you might only see on a CPU of different speed or # of processors, etc. I've seen this too. It cuts both ways.

> Yes there are parts of the framework that can and do yield (like database queries so the entire UI wont lock up on big queries)
> And we could alter when the framework normally yields right now it's possible at loop boundaries and I think there's other spots.
> We could make things yield on IF statements, select case evaluation etc.

Sure you could, but why?

Threads need to follow one model: they are either cooperative, or not. Yielding in the middle of an IF statement would be...what? "Half preemptive"...?

It's not like there aren't decades of research on this topic -- threads are hard enough as it is -- they should either be cooperative with well-documented, defined, and controllable yielding behavior, or they should be pre-emptive. And that status should not be something that changes from release to release.

> The net effect would be to make cooperative threads behave more like preemptive threads where you can't predict when a yield might happen and so you code accordingly with semaphores etc.

Again, yes you could, in theory, but that would be *bone-headed*.

Theory is fine, but I'm talking about reality here. The RB framework has some very bad, fundamental threading bugs that have cost me dozens (hundreds?) of hours of my time trying to work around the framework's poor threading behaviors to get an app that is stable.

While I was eventually able to make a stable app, I had to make a lot of compromises (such as not using Introspection in a thread, not using it all on PPC builds, etc.)

My request: REAL should please spend less time discussing the theory of Threading, and more time fixing the existing thread bugs: Introspection is broken. #8291 is a really bad bug (as it its PPC cousin, 11954).

Thanks!
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 18:42 (Sun, 1 Aug 2010 19:42:34 +0200)
From: devmllst yahoo.de
On Aug 1, 2010, at 19:34, <email address removed> wrote:

>>> Quoting myself:
>>>> I have a "preprocessor"-method "lg(theMsg as Variant)" which takes different kind of data and turns it into a string. It then calls another method "lg_out(theMsg as String)" which does the actual output, either to file or to TextArea. The lg_out-method may loop in some cases.
>>>> If I understood all correctly:
>>>> - I'm safe regarding the theMsg variable - not matter what, it will be unique in each thread's own space. I will not get wrong log messages.
>>>> - I'm not safe regarding the order in which the log messages are written, because my second method lg_out may loop.
>>>> Correct?
>>>
>> On Aug 1, 2010, at 18:35, Andrew Keller wrote:
>>
>>> Instruct the compiler to disable background tasks right before you call your shared method (although this is more of a quick fix... If you choose this path, and forget to do this in at least two places, then bad things will happen.
>>
> On Aug 1, 2010, at 19:34, <email address removed> wrote:
>
>> I have two methods in chain - the critical (looping method) the second one. Wouldn't it be early enough to DisableBackgroundTasks in the first method?
>> ThreadX --> Method1 --> Method2
>> ... with DisableBackgroundTasks at the beginning of both methods. As soon as Method1 is entered everything else stops until Method2 has finished. This way I can ensure that the order of log messages is always correct?
>
> On Aug 1, 2010, at 19:29, Norman Palardy wrote:

> disable background tasks in lg_out and that should make that NOT yield to other threads

I will do so. Thanks to all!

Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 18:34 (Sun, 1 Aug 2010 19:34:32 +0200)
From: devmllst yahoo.de
Quoting myself:
> I have a "preprocessor"-method "lg(theMsg as Variant)" which takes different kind of data and turns it into a string. It then calls another method "lg_out(theMsg as String)" which does the actual output, either to file or to TextArea. The lg_out-method may loop in some cases.
> If I understood all correctly:
> - I'm safe regarding the theMsg variable - not matter what, it will be unique in each thread's own space. I will not get wrong log messages.
> - I'm not safe regarding the order in which the log messages are written, because my second method lg_out may loop.
> Correct?

On Aug 1, 2010, at 18:35, Andrew Keller wrote:

> Instruct the compiler to disable background tasks right before you call your shared method (although this is more of a quick fix... If you choose this path, and forget to do this in at least two places, then bad things will happen.

I have two methods in chain - the critical (looping method) the second one. Wouldn't it be early enough to DisableBackgroundTasks in the first method?
ThreadX --> Method1 --> Method2
... with DisableBackgroundTasks at the beginning of both methods. As soon as Method1 is entered everything else stops until Method2 has finished. This way I can ensure that the order of log messages is always correct?

Kind regards
Christian

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 18:29 (Sun, 1 Aug 2010 11:29:53 -0600)
From: Norman Palardy

On Aug 1, 2010, at 10:51 AM, <email address removed> wrote:

> On Aug 1, 2010, at 18:12, Charles Yeomans wrote:
>
>> Local variables are created in the course of method execution, so
>> each thread of execution will have its own local variables.
> Ok, that's good!
>
> On Aug 1, 2010, at 18:16, Michael Diehr wrote:
>
>> In fact, when I ran into these issues it was a very similar
>> situation: I had a global "log" command which would log
>> information, and had options to update a log window with info about
>> the objects being logged (...)
> Quite similar to mine: I have a "preprocessor"-method "lg(theMsg as
> Variant)" which takes different kind of data and turns it into a
> string. It then calls another method "lg_out(theMsg as String)"
> which does the actual output, either to file or to TextArea. The
> lg_out-method may loop in some cases.
> If I understood all correctly:
> - I'm safe regarding the theMsg variable - not matter what, it will
> be unique in each thread's own space. I will not get wrong log
> messages.
> - I'm not safe regarding the order in which the log messages are
> written, because my second method lg_out may loop.
> Correct?

disable background tasks in lg_out and that should make that NOT yield
to other threads

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 17:51 (Sun, 1 Aug 2010 18:51:54 +0200)
From: devmllst yahoo.de
On Aug 1, 2010, at 18:12, Charles Yeomans wrote:

> Local variables are created in the course of method execution, so each thread of execution will have its own local variables.
Ok, that's good!

On Aug 1, 2010, at 18:16, Michael Diehr wrote:

> In fact, when I ran into these issues it was a very similar situation: I had a global "log" command which would log information, and had options to update a log window with info about the objects being logged (...)
Quite similar to mine: I have a "preprocessor"-method "lg(theMsg as Variant)" which takes different kind of data and turns it into a string. It then calls another method "lg_out(theMsg as String)" which does the actual output, either to file or to TextArea. The lg_out-method may loop in some cases.
If I understood all correctly:
- I'm safe regarding the theMsg variable - not matter what, it will be unique in each thread's own space. I will not get wrong log messages.
- I'm not safe regarding the order in which the log messages are written, because my second method lg_out may loop.
Correct?

Kind regards
Christian

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 17:41 (Sun, 1 Aug 2010 10:41:20 -0600)
From: Norman Palardy

On Aug 1, 2010, at 10:16 AM, Michael Diehr wrote:

> Norman says "if it does not contain any loops" -- ahem. One of my
> pet peeves here is that in an app of any non-trivial complexity,
> this claim is only true for interesting values of "truth" :)
>
> Specifically, there are places in the RB framework where the
> framework yields and you can't do a thing about it. I've ran into
> this with StyledText and Introspection, but I suspect there are
> others too (database?).
>
> In fact, when I ran into these issues it was a very similar
> situation: I had a global "log" command which would log information,
> and had options to update a log window with info about the objects
> being logged -- this used both styledText and Introspection of
> course, and hilarity ensued until I figured out why my threads were
> all mangled.

IMHO logging should be small fast tight and not involve styled text or
introspection.
Why ? Not keeping it small fast and tight can introduce timing
differences which may be relevant to tracking down an issue.
I've seen this all to often where inserting some code, like a logger,
makes things work and when removing it the code being examined fails
again.

Yes there are parts of the framework that can and do yield (like
database queries so the entire UI wont lock up on big queries)
And we could alter when the framework normally yields right now it's
possible at loop boundaries and I think there's other spots.
We could make things yield on IF statements, select case evaluation etc.

The net effect would be to make cooperative threads behave more like
preemptive threads where you can't predict when a yield might happen
and so you code accordingly with semaphores etc.

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 17:35 (Sun, 1 Aug 2010 12:35:20 -0400)
From: Andrew Keller
When a thread's Run event calls any method, located anywhere, the method runs as if it were part of the thread.

This has some serious implications on a lot of things. If you have a global method that takes a few steps to execute, then there is a possibility that two threads could be executing that method at the same time. If that global method has variables inside the method itself, then there will be two copies of those variables, one for each copy of the method. If that global method accesses some global or shared properties, then there will still only be one copy of those properties, and thus, problems. There are almost always problems when multiple instances of the same method try to access the same property at the same time.

There are a few ways to make your code more stable, each of which have their own advantages and disadvantages:

Don't use shared properties. Only use variables local to methods.

Use a locking mechanism in your shared method to ensure that any global or shared properties are accessed by only one instance of the method at a time.

Instruct the compiler to disable background tasks right before you call your shared method (although this is more of a quick fix... If you choose this path, and forget to do this in at least two places, then bad things will happen.

Not using shared properties is the simplest, but often cannot do what you need.

Locking mechanisms are generally the best idea, because it ensures that any code calling that method will work properly. Anytime you rely on other code doing something correctly, mysterious bugs will pop up.

~ Andrew Keller

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 17:16 (Sun, 1 Aug 2010 09:16:46 -0700)
From: Michael Diehr
On Aug 1, 2010, at 8:56 AM, Norman Palardy wrote:

>
> On Aug 1, 2010, at 9:08 AM, <email address removed> wrote:
>
>>>
>>>
>>> Threads in REALbasic are cooperative; that is, they yield at well-defined locations. But your Logit method should still use a semaphore to control access and so ensure Case 2.
>>
>> I realize my example was not the best because I will have a problem in all cases with a global thing - the file - except the answer is 2. Then I would be totally safe. I understand you so that the answer is 3?
>>
>> So let's suppose my global method does no file writing, has only local variables, and needs a minute to do it's work.
>> Now Thread #1 calls it, and after some seconds Thread #2 calls it.
>> Are the threads working on it's own copies of the method (especially it's variables)?
>> Or are they using the very same method and variables where the second thread could overwrite the variable values the first thread has just set?
>
> If your writing method never yields (which is possible if it does not contain any loops) then it will work to completion
>
> Threads are not preemptive

Norman says "if it does not contain any loops" -- ahem. One of my pet peeves here is that in an app of any non-trivial complexity, this claim is only true for interesting values of "truth" :)

Specifically, there are places in the RB framework where the framework yields and you can't do a thing about it. I've ran into this with StyledText and Introspection, but I suspect there are others too (database?).

In fact, when I ran into these issues it was a very similar situation: I had a global "log" command which would log information, and had options to update a log window with info about the objects being logged -- this used both styledText and Introspection of course, and hilarity ensued until I figured out why my threads were all mangled.

REAL is on record as saying something like (I'm paraphrasing here) "The framework will yield any damn time it feels like it".

I've therefore created a church of the non-yielding framework, with associated monolog "The Framework Shalt Not Yield " -- I think I have a few followers.

There is also the church of the Optional Framework Yield, e.g. "The Framework Shalt Not Yield, or if it does there must be a non-yielding option".

If you want to join the fervor, please favorite:

<feedback://showreport?report_id965>
and
<feedback://showreport?report_id‚91>


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 17:12 (Sun, 1 Aug 2010 12:12:19 -0400)
From: Charles Yeomans

On Aug 1, 2010, at 11:08 AM, <email address removed> wrote:

>
> On Aug 1, 2010, at 16:19, Charles Yeomans wrote:
>
>>
>> On Aug 1, 2010, at 10:07 AM, <email address removed> wrote:
>>
>>> Supposed I have a method "Logit(theMsg)" in a module to log
>>> messages to a file. What happens when this method is called by
>>> different threads at the "same" time (Logit hasn't finished, but
>>> get's again invoked from another thread)?
>>>
>>> Dim theAnswer as integer
>>> Select Case theAnswer
>>> Case 1
>>> Global properties are unique always, but global methods are not.
>>> They are internally instantiated like new objects if they are not
>>> called from the main thread.
>>>
>>> Case 2
>>> Global methods are guaranteed to finish their execution, no matter
>>> how many other calls are waiting. They are FIFO-style.
>>>
>>> Case 3
>>> They are LIFO-style. Your local "theMsg"-variable will be
>>> overwritten by the later call - effectively resulting in two
>>> identical log messages.
>>>
>>> Case 4
>>> Isn't it sunday?
>>> // Yes, but this is THE opportunity to make the shortest answer
>>> ever!
>>>
>>> End select
>>
>> Threads in REALbasic are cooperative; that is, they yield at well-
>> defined locations. But your Logit method should still use a
>> semaphore to control access and so ensure Case 2.
>
> I realize my example was not the best because I will have a problem
> in all cases with a global thing - the file - except the answer is
> 2. Then I would be totally safe. I understand you so that the answer
> is 3?
>
> So let's suppose my global method does no file writing, has only
> local variables, and needs a minute to do it's work.
> Now Thread #1 calls it, and after some seconds Thread #2 calls it.
> Are the threads working on it's own copies of the method (especially
> it's variables)?
> Or are they using the very same method and variables where the
> second thread could overwrite the variable values the first thread
> has just set?

Local variables are created in the course of method execution, so each
thread of execution will have its own local variables.

Charles Yeomans

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 16:56 (Sun, 1 Aug 2010 09:56:19 -0600)
From: Norman Palardy

On Aug 1, 2010, at 9:08 AM, <email address removed> wrote:

>>
>> Threads in REALbasic are cooperative; that is, they yield at well-
>> defined locations. But your Logit method should still use a
>> semaphore to control access and so ensure Case 2.
>
> I realize my example was not the best because I will have a problem
> in all cases with a global thing - the file - except the answer is
> 2. Then I would be totally safe. I understand you so that the answer
> is 3?
>
> So let's suppose my global method does no file writing, has only
> local variables, and needs a minute to do it's work.
> Now Thread #1 calls it, and after some seconds Thread #2 calls it.
> Are the threads working on it's own copies of the method (especially
> it's variables)?
> Or are they using the very same method and variables where the
> second thread could overwrite the variable values the first thread
> has just set?

If your writing method never yields (which is possible if it does not
contain any loops) then it will work to completion

Threads are not preemptive

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 16:08 (Sun, 1 Aug 2010 17:08:29 +0200)
From: devmllst yahoo.de

On Aug 1, 2010, at 16:19, Charles Yeomans wrote:

>
> On Aug 1, 2010, at 10:07 AM, <email address removed> wrote:
>
>> Supposed I have a method "Logit(theMsg)" in a module to log messages to a file. What happens when this method is called by different threads at the "same" time (Logit hasn't finished, but get's again invoked from another thread)?
>>
>> Dim theAnswer as integer
>> Select Case theAnswer
>> Case 1
>> Global properties are unique always, but global methods are not. They are internally instantiated like new objects if they are not called from the main thread.
>>
>> Case 2
>> Global methods are guaranteed to finish their execution, no matter how many other calls are waiting. They are FIFO-style.
>>
>> Case 3
>> They are LIFO-style. Your local "theMsg"-variable will be overwritten by the later call - effectively resulting in two identical log messages.
>>
>> Case 4
>> Isn't it sunday?
>> // Yes, but this is THE opportunity to make the shortest answer ever!
>>
>> End select
>
> Threads in REALbasic are cooperative; that is, they yield at well-defined locations. But your Logit method should still use a semaphore to control access and so ensure Case 2.

I realize my example was not the best because I will have a problem in all cases with a global thing - the file - except the answer is 2. Then I would be totally safe. I understand you so that the answer is 3?

So let's suppose my global method does no file writing, has only local variables, and needs a minute to do it's work.
Now Thread #1 calls it, and after some seconds Thread #2 calls it.
Are the threads working on it's own copies of the method (especially it's variables)?
Or are they using the very same method and variables where the second thread could overwrite the variable values the first thread has just set?

Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Code Flow: threads call a global method...
Date: 01.08.10 15:19 (Sun, 1 Aug 2010 10:19:08 -0400)
From: Charles Yeomans

On Aug 1, 2010, at 10:07 AM, <email address removed> wrote:

> Supposed I have a method "Logit(theMsg)" in a module to log messages
> to a file. What happens when this method is called by different
> threads at the "same" time (Logit hasn't finished, but get's again
> invoked from another thread)?
>
> Dim theAnswer as integer
> Select Case theAnswer
> Case 1
> Global properties are unique always, but global methods are not.
> They are internally instantiated like new objects if they are not
> called from the main thread.
>
> Case 2
> Global methods are guaranteed to finish their execution, no matter
> how many other calls are waiting. They are FIFO-style.
>
> Case 3
> They are LIFO-style. Your local "theMsg"-variable will be
> overwritten by the later call - effectively resulting in two
> identical log messages.
>
> Case 4
> Isn't it sunday?
> // Yes, but this is THE opportunity to make the shortest answer ever!
>
> End select

Threads in REALbasic are cooperative; that is, they yield at well-
defined locations. But your Logit method should still use a semaphore
to control access and so ensure Case 2.

Charles Yeomans

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>