Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^4: Mixing asynchronous data feed with synchronous program flow control

by jcb (Priest)
on Jan 03, 2020 at 01:02 UTC ( #11110887=note: print w/replies, xml ) Need Help??


in reply to Re^3: Mixing asynchronous data feed with synchronous program flow control
in thread Mixing asynchronous data feed with synchronous program flow control

I admit my precondition was incomplete as well. The actual requirement is that, upon entering or returning to the event loop, all resources must be in some usable idle state. I still maintain that race conditions cannot occur in a program with a single event loop because the program is implicitly serialized on the event loop itself. The error that you cite is "use of uninitialized value" and the bug is obscured by an asynchronous environment, but it is not a result of undefined timing. It is very well defined: an attempt is made to use $TX some time later, even if the I/O required to initialize $TX is still pending.

I am most familiar with writing Tk callbacks where getting back to the event loop quickly is very important, but Tk ensures that all initialization is complete before the first user callback runs. The error you have found occurs when the event loop is started but some resource used in a callback has not yet been fully initialized. If initializing a connection requires the event loop to run, things get more interesting and you must track the "initialization pending" state somewhere and either drop or requeue timer events until the connection is ready. So the "idle state" for the connection includes a "connected" flag that must remain clear until the connection is actually established.

... and so the pristine model starts to get hairy when put into practice ...

Replies are listed 'Best First'.
Re^5: Mixing asynchronous data feed with synchronous program flow control
by haukex (Chancellor) on Jan 03, 2020 at 09:20 UTC
    I still maintain that race conditions cannot occur in a program with a single event loop because the program is implicitly serialized on the event loop itself.

    I agree that of course one event handler cannot interrupt another. However, I'm not sure what definition of "race condition" you're using here, in my book this is indeed a race condition, see e.g. Race condition - the definition is broad enough that it certainly applies here. (I'd even argue that event loops are a form of cooperative multitasking, so even the "shared resource accessed from more than one thread" definition applies.) But even if the quibble is about the terminology used, the bug still exists.

    ... it is not a result of undefined timing. It is very well defined: an attempt is made to use $TX some time later, even if the I/O required to initialize $TX is still pending.

    Sorry, I don't understand what you mean by "undefined timing" compared to the sentence following it. (Replace the sleep 5; with sleep rand 10; and the bug still exists.)

    I am most familiar with writing Tk callbacks where getting back to the event loop quickly is very important, but Tk ensures that all initialization is complete before the first user callback runs. The error you have found occurs when the event loop is started but some resource used in a callback has not yet been fully initialized.

    I have to nitpick here that the error is independent of whether the event loop is running or not* - the error is that the timer is started too soon (or that it fires too soon, however you want to look at it). The model you describe of "set everything up before the event loop starts" doesn't work in network servers for example; resources like client connections, timers associated with those connections, etc. come and go, and in most cases can't be initialized before the event loop starts, and instead have to be dynamically allocated and deallocated.

    * Update: To clarify: of course nothing can happen if the event loop isn't running; the rest of the paragraph above hopefully makes clear what I meant to say.

    If initializing a connection requires the event loop to run, things get more interesting and you must track the "initialization pending" state somewhere and either drop or requeue timer events until the connection is ready. So the "idle state" for the connection includes a "connected" flag that must remain clear until the connection is actually established. ... and so the pristine model starts to get hairy when put into practice ...

    That's one possible solution, but I guess I would also describe it as "hairy". Again, I already showed another that solves the issue, IMO cleanly.

      I agree that of course one event handler cannot interrupt another.

      This is the difference between an event loop and preemptive multi-tasking or true multi-processing. I was thinking of the latter as a comparison.

      I don't understand what you mean by "undefined timing" compared to the sentence following it.

      I consider a race condition to be the situation when events in one system occur in a non-deterministic order — and the exact order in which the events occur matters, which is the bug. Race conditions are solved by either adding additional synchronization to the system to ensure the events occur in a useful order or ensuring that the system operates correctly regardless of the event ordering.

      The model you describe of "set everything up before the event loop starts" doesn't work in network servers for example;

      You are correct, but that is the model I am currently familiar with (I have not yet had need to write any low-level network servers) and explains the blind spot I had that you have helpfully pointed out.

      And your solution is better; I had not noticed the use of a quasi-global lexical variable in the question until now. I agree that getting rid of $TX is an important step in improving this code.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11110887]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2020-05-25 11:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (145 votes). Check out past polls.

    Notices?