Tcl package Thread source code

Ticket Change Details
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2018 Conference, Houston/TX, US, Oct 15-19
Send your abstracts to
or submit via the online form by Aug 20.

Artifact ID: 6dd7409b18e374fa9325c0d117a684a2dd896b0e04b21aa93689222cb9ae1fb6
Ticket: b5709ea9060d17f58ba48110351c964b3408e362
[::thread::send -async] posting order not respected when sending to current thread
User & Date: adrianmedranocalvo 2018-07-31 16:22:35

  1. Change icomment to:

    Hello sebres,

    there's definitely some misunderstanding. English is not my mother language, it's not the first time I cause a mess...

    I'll try to explain with code.

    One important point is: I don't care about the order of [after idle] events nor [after 0] events with respect to [thread::send -async] events. I only care about the order of [thread::send -async] events.

    Please, try the following script:

    ~~~ package require Thread;

    set t(main) [::thread::id] set t(other) [::thread::create]

    # Let t(other) know the main thread's id, t(main). ::thread::send $t(other) [list array set t [array get t]]

    # Async thread::send to current thread (the main thread). # I expect this script to be inserted at the end of the thread event queue. ::thread::send -async $t(main) { lappend ::trace LOCAL-THREAD-SEND; }

    ::thread::send $t(other) { # Async thread::send to other thread (the main thread). # I expect this script to be inserted at the end of the # thread event queue, after the one above. ::thread::send -async $t(main) { lappend ::trace REMOTE-THREAD-SEND; } }

    after 100 {set forever 1}; vwait forever; puts [join $::trace "\n"]; ~~~

    This is the output:


    This is not expected, because the [thread::send -async] lappending LOCAL-THREAD-SEND ran before the one lappending REMOTE-THREAD-SEND.

    When I remove the following code:

    I obtain the expected output:


    Are there any downsides in removing the following code?


    I'll now try to respond to your points.

    > if you'll do that, the event will be appended directly into the queue of the thread, so in this case it will be not LAST (as by idle) but FIRST event (because timer events coming later via processing of event-sources). > > So again, it cannot be "on the order they were posted", because they are another types of events. It will be not between your timer-events, but either hereafter (like now) or before (if direct appended to event-queue). But definitely not between.

    I think that's what I want and expect, that the [thread::send -async] is appended to the queue of the thread. I don't expect them to be handled between other types of events.

    > For this case "thread::send -async [thread::id]" should be quasi rewritten as "after 0", and I'm definitely against this, because it produces unexpected overhead.

    I'm also against this. In fact that's the precise problem: "thread::send -async [thread::id]" is being rewritten into "after idle". See the part of the code where that happens (

    1. /*
    2. * Short circuit sends to ourself.
    3. */ 2745
    4. if (thrId == Tcl_GetCurrentThread()) {
    5. Tcl_MutexUnlock(&threadMutex);
    6. if ((flags & THREAD_SEND_WAIT)) {
    7. int code = (*send->execProc)(interp, (ClientData)send);
    8. ThreadFreeProc((ClientData)send);
    9. return code;
    10. } else {
    11. send->interp = interp;
    12. Tcl_Preserve((ClientData)send->interp);
    13. Tcl_DoWhenIdle((Tcl_IdleProc*)ThreadIdleProc, (ClientData)send);
    14. return TCL_OK;
    15. }
    16. }

    > Possibly for my another event-branch (that I wrote in tcl-core-repo), where "after 0" have O(1) by changing of timer-queue, does not generate extra overhead as regards time-compare at all (because creates an immediate timer-event), etc. If this will be accepted sometimes...

    More performant event handling is always welcome... thank you for your efforts, I hope it gets merged soon.

  2. Change login to "adrianmedranocalvo"
  3. Change mimetype to "text/plain"
  4. Change username to ""