• A fileevent question

    From Helmut Giese@hgiese@ratiosoft.com to comp.lang.tcl on Tue Feb 27 22:29:16 2024
    From Newsgroup: comp.lang.tcl

    Hello out there,
    just asking for inspiration.
    I have a simulation which executes commands - everything ok.
    But now the program should also communicate with external hardware via
    a serial connection and that is the problem:
    - I don't want to block waiting for an answer since I also have a GUI.
    - Turning to file events I now have the problem that the simulation
    cannot continue before a particular call to the hardware is complete:
    It may ask the hardware for a particular value which is to be used in
    the next command.

    So my question is: How do I block execution of the simulation part
    until an answer arrives /without/ blocking the whole app?
    - An attempt to use 'vwait' resulted in the whole app freezing.
    - A separate thread would probably solve this problem.
    - A coroutine would instinctively be a "lighter" solution but I have
    so far never used coroutines and didn't find an example which seemed
    to "fit" my situation.
    - Any other way ...

    Any idea, tip or link will be greatly appreciated
    Helmut
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Gerald Lester@Gerald.Lester@gmail.com to comp.lang.tcl on Tue Feb 27 16:05:40 2024
    From Newsgroup: comp.lang.tcl

    On 2/27/24 15:29, Helmut Giese wrote:
    Hello out there,
    just asking for inspiration.
    I have a simulation which executes commands - everything ok.
    But now the program should also communicate with external hardware via
    a serial connection and that is the problem:
    - I don't want to block waiting for an answer since I also have a GUI.
    - Turning to file events I now have the problem that the simulation
    cannot continue before a particular call to the hardware is complete:
    It may ask the hardware for a particular value which is to be used in
    the next command.

    So my question is: How do I block execution of the simulation part
    until an answer arrives /without/ blocking the whole app?
    - An attempt to use 'vwait' resulted in the whole app freezing.
    - A separate thread would probably solve this problem.
    - A coroutine would instinctively be a "lighter" solution but I have
    so far never used coroutines and didn't find an example which seemed
    to "fit" my situation.
    - Any other way ...

    Any idea, tip or link will be greatly appreciated
    Helmut

    vwait is the correct answer when used correctly.

    The simulation should:
    1) set a global variable.
    2) set up the file event.
    3) vwait on the global variable.
    4) remove the file event.

    The file event handler should set the global variable if appropriate.
    It should no call update or update idle task.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Wed Feb 28 09:11:57 2024
    From Newsgroup: comp.lang.tcl

    Am 27.02.2024 um 22:29 schrieb Helmut Giese:
    Hello out there,
    just asking for inspiration.
    I have a simulation which executes commands - everything ok.
    But now the program should also communicate with external hardware via
    a serial connection and that is the problem:
    - I don't want to block waiting for an answer since I also have a GUI.
    - Turning to file events I now have the problem that the simulation
    cannot continue before a particular call to the hardware is complete:
    It may ask the hardware for a particular value which is to be used in
    the next command.

    So my question is: How do I block execution of the simulation part
    until an answer arrives /without/ blocking the whole app?
    - An attempt to use 'vwait' resulted in the whole app freezing.
    - A separate thread would probably solve this problem.
    - A coroutine would instinctively be a "lighter" solution but I have
    so far never used coroutines and didn't find an example which seemed
    to "fit" my situation.
    - Any other way ...

    Any idea, tip or link will be greatly appreciated
    Helmut

    What about a program within a coroutine?
    It is suspended until the condition arises.
    You may link the coroutine to the fileevent.

    That is black magic.

    I try to get all vwaits out of my programs. They nest and block each other.

    Take care,
    Harald


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Ralf Fassel@ralfixx@gmx.de to comp.lang.tcl on Wed Feb 28 10:48:12 2024
    From Newsgroup: comp.lang.tcl

    * Helmut Giese <hgiese@ratiosoft.com>
    | So my question is: How do I block execution of the simulation part
    | until an answer arrives /without/ blocking the whole app?
    | - An attempt to use 'vwait' resulted in the whole app freezing.

    This is strange, since vwait should process events.

    I usually split up the task at hand in 2 parts:

    - send command to device
    - code to run when answer arrives via fileevent

    # assuming line oriented communication
    set chan [open $device w+]
    fconfigure $chan -blocking 0 -buffering line/none
    fileevent $chan readable [list device_answer $chan]

    proc send_cmd {chan} {
    puts $chan "Answer me!"
    # probably set up a timeout timer for the answer to arrive if appropriate
    }

    proc device_answer {chan} {
    set answer [gets $chan]
    if {$answer ne ""} {
    # handle answer, do all that is necessary
    }
    if {[eof $chan]} {
    close $chan
    # diagnostics?
    }
    }

    Then send_cmd just sends the command, and device_answer is called when
    the answer from the device arrives.

    HTH
    R'
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Rich@rich@example.invalid to comp.lang.tcl on Wed Feb 28 20:11:36 2024
    From Newsgroup: comp.lang.tcl

    Harald Oehlmann <wortkarg3@yahoo.com> wrote:
    Am 27.02.2024 um 22:29 schrieb Helmut Giese:
    Hello out there,
    just asking for inspiration.
    I have a simulation which executes commands - everything ok.
    But now the program should also communicate with external hardware via
    a serial connection and that is the problem:
    - I don't want to block waiting for an answer since I also have a GUI.
    - Turning to file events I now have the problem that the simulation
    cannot continue before a particular call to the hardware is complete:
    It may ask the hardware for a particular value which is to be used in
    the next command.

    So my question is: How do I block execution of the simulation part
    until an answer arrives /without/ blocking the whole app?
    - An attempt to use 'vwait' resulted in the whole app freezing.
    - A separate thread would probably solve this problem.
    - A coroutine would instinctively be a "lighter" solution but I have
    so far never used coroutines and didn't find an example which seemed
    to "fit" my situation.
    - Any other way ...

    Any idea, tip or link will be greatly appreciated
    Helmut

    What about a program within a coroutine?

    The general architecture you describe is one that would 'fit' nicely
    into a coroutine design. But, when one is 'new' to coroutines, it is
    harder to wrap one's mind around how to structure things. And most of
    us are 'new' to thinking in "coroutine" style.

    It is suspended until the condition arises.
    You may link the coroutine to the fileevent.

    You can read an example of converting an otherwise sequential, wait
    (note, not vwait, just blocking I/O waits) style program into event
    driven coroutine style here on the wiki:

    https://wiki.tcl-lang.org/page/Coroutines+for+event%2Dbased+programming

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Helmut Giese@hgiese@ratiosoft.com to comp.lang.tcl on Wed Feb 28 23:56:13 2024
    From Newsgroup: comp.lang.tcl

    Hello,
    many thanks to all of you who responded.
    Rich was right with his comment: Although I read the manual on
    coroutines and several pages on the use of and examples with
    coroutines I still could not 'grasp' how they work. (But I tuck Rich's
    link away for further reference).

    So
    - I created a very simple example involving 2 Tcl programs: one
    sending, the other receiving
    - I slowly moved them somewhat into the direction of my app and
    - what do you know: 'vwait' is working !

    Now I "only" have to find the bug in my first attempt, sigh.
    But thanks to you I am at least on track again
    Helmut
    --- Synchronet 3.20a-Linux NewsLink 1.114