Avoiding recursion when reading/writing a port synchronously?

AsynchronousIoRebolRebol3

Asynchronous Problem Overview


All port operations in Rebol 3 are asynchronous. The only way I can find to do synchronous communication is calling wait.

But the problem with calling wait in this case is that it will check events for all open ports (even if they are not in the port block passed to wait). Then they call their responding event handlers, but a read/write could be done in one of those event handlers. That could result in recursive calls to "wait".

How do I get around this?

Asynchronous Solutions


Solution 1 - Asynchronous

Why don´t you create a kind of "Buffer" function to receive all messages from assyncronous entries and process them as FIFO (first-in, first-out)?

This way you may keep the Assync characteristics of your ports and process them in sync mode.

Solution 2 - Asynchronous

in cases where there are only asynchronous events and we are in need on synchronous reply, start a timer or sleep for timeout, if the handler or required objective is met then say true, else false and make sure the event gets cancelled /reset for the same if critical.

Solution 3 - Asynchronous

I think that there are 2 design problems (maybe intrinsic to the tools / solutions at hand).

  1. Wait is doing too much - it will check events for all open ports. In a sound environment, waiting should be implemented only where it is needed: per device, per port, per socket... Creating unnecessary inter-dependencies between shared resources cannot end well - especially knowing that shared resources (even without inter-dependencies) can create a lot of problems.

  2. The event handlers may do too much. An event handler should be as short as possible, and it should only handle the event. If is does more, then the handler is doing too much - especially if involves other shared resources. In many situations, the handler just saves the data which will be lost otherwise; and an asynchronous job will do the more complex things.

Solution 4 - Asynchronous

You can just use a lock. Cummunication1 can set some global lock state i.e. with a variable (be sure that it's thread safe). locked = true. Then Communication2 can wait until it's unlocked.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShixin ZengView Question on Stackoverflow
Solution 1 - AsynchronousDavid BSView Answer on Stackoverflow
Solution 2 - AsynchronousmkumarView Answer on Stackoverflow
Solution 3 - AsynchronousvirolinoView Answer on Stackoverflow
Solution 4 - AsynchronousRivenfallView Answer on Stackoverflow