Avoiding recursion when reading/writing a port syn

2019-03-14 10:11发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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()