Overview
Artifact ID: | a9b4e19a36f9b7a938549de45776b33dac4cadc0bf99763924f2d02879a6d4bf |
---|---|
Ticket: | b5709ea9060d17f58ba48110351c964b3408e362
[::thread::send -async] posting order not respected when sending to current thread |
User & Date: | adrianmedranocalvo 2018-07-31 11:27:59 |
Changes
- assignee changed to: "nobody"
- closer changed to: "nobody"
- cmimetype changed to: "text/plain"
- comment changed to:
if {0} { When the target thread of [::thread::send -async] is the current thread, the async script is not evaluated in order with respect to other [::thread::send -async] scripts. Let's call a [::thread::send -async] invoked from the current thread and directed to the current thread a local [::thread::send -async], and a [::thread::send -async] invoked from any other thread and directed to the former thread a remote [::thread::send -async]. Current behaviour is that all remote [::thread::send -async] scripts will be evaluated before any local [::thread::send -asinc] scripts are, even in the case where the local scripts have been posted before the remote ones. See the script below for a concise example. Intuitively, [::thread::send -async] scripts should be queued and evaluated in the order they were added to the queue (that is, except if the -head argument was given). The script below demostrates this issue. We append to a global variable in the main thread in four different ways, in order: - An after 0 script - An after idle script - A local [thread::send -async] - A remote [thread::send -async] - Another after 0 script - Another after idle script The printed trace of the script is reproduced below. Contrary to the posting order, the remote [thread::send -async] is evaluated before the local [thread::send -async]. ~~~ REMOTE-THREAD-SEND AFTER0-BEG AFTER0-END IDLE-BEG LOCAL-THREAD-SEND IDLE-END ~~~ Without knowing the details of the Thread package, one would expect the local and remote [thread::send -async] to be evaluated in the order they were posted. Instead, the remote [thread::send -async] are invariably evaluated before the local ones; and the local ones are evaluated as [after idle] commands. The cause for this behaviour is an optimization in threadCmd.c, commented as "Short circuit sends to ourself", where local [thread::send -async] are converted to [after idle], implying that a different queue is used for local [thread::send -async] events as oposed to remote [thread::send -async] events. How important is this optimization? I can't see much performance being lost if we would disable the optimization and would let local [::thread::send -async] be added to the queue along with all others. The benefit from this change would be a more consistent behaviour. The underlying use-case is a server with connection-specific threads. The connection-specific thread uses local [thread::send -async] in order to delay the flushing of responses, so that the application's locks are grabbed for a minimum amount of time. Other threads use remote [thread::send -async] to the connection thread in order to send messages through the connection. The optimization above difficults ensuring the order the responses are flushed. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } 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]] after 0 {lappend ::trace AFTER0-BEG;} after idle {lappend ::trace IDLE-BEG;} ::thread::send -async $t(main) { lappend ::trace LOCAL-THREAD-SEND; } ::thread::send $t(other) { ::thread::send -async $t(main) { lappend ::trace REMOTE-THREAD-SEND; } } after 0 {lappend ::trace AFTER0-END;} after idle {lappend ::trace IDLE-END;} after 100 {set forever now}; vwait forever; puts [join $::trace "\n"]; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- foundin changed to: "2.8.0"
- is_private changed to: "0"
- login: "adrianmedranocalvo"
- priority changed to: "5 Medium"
- private_contact changed to: "219192cc5b7de6cef9c96726d1feb29d0382f2dc"
- resolution changed to: "None"
- severity changed to: "Important"
- status changed to: "Open"
- submitter changed to: "adrianmedranocalvo"
- subsystem changed to: "80. Thread Package"
- title changed to:
[::thread::send -async] posting order not respected when sending to current thread
- type changed to: "Bug"