Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.
|Comment:||Added TIP 511 for Christian Werner, who is having problems with his fossil login|
|Downloads:||Tarball | ZIP archive | SQL archive|
|Timelines:||family | ancestors | descendants | both | trunk|
|Files:||files | file ages | folders|
|User & Date:||dkf 2018-06-20 12:20:37|
|14:18||Correction from Christian Werner check-in: eadd78dd7f user: dkf tags: trunk|
|12:20||Added TIP 511 for Christian Werner, who is having problems with his fossil login check-in: 063fc0cf1c user: dkf tags: trunk|
|16:52||Got the description of classvariable wrong. check-in: e3243a6107 user: dkf tags: trunk|
Changes to index.json.
cannot compute difference between binary files
Changes to index.md.
102 102 <th>#</th> 103 103 <th>Type</th> 104 104 <th>Tcl Version</th> 105 105 <th>Status</th> 106 106 <th>Title</th> 107 107 </tr></thead><tbody> 108 108 109 +<tr class='project projectdraft projectdraft87 project87'> 110 +<td valign='top'><a href='./tip/511.md'>511</a></td> 111 +<td valign='top'>Project</td> 112 +<td valign='top'>8.7</td> 113 +<td valign='top'>Draft</td> 114 +<td valign='top'># TIP 511: Implement Tcl_AsyncMarkFromSignal()</td> 115 +</tr> 109 116 <tr class='project projectdraft projectdraft87 project87'> 110 117 <td valign='top'><a href='./tip/510.md'>510</a></td> 111 118 <td valign='top'>Project</td> 112 119 <td valign='top'>8.7</td> 113 120 <td valign='top'>Draft</td> 114 121 <td valign='top'># TIP 510: Add Rbc to Tk</td> 115 122 </tr>
1 +# TIP 511: Implement Tcl_AsyncMarkFromSignal() 2 + Author: Christian Werner <[email protected]> 3 + State: Draft 4 + Type: Project 5 + Vote: 6 + Created: 14-June-2018 7 + Post-History: 8 + Keywords: Tcl,threads 9 + Tcl-Version: 8.7 10 +----- 11 + 12 +# Abstract 13 + 14 +This TIP proposes to add a Tcl API for marking `Tcl_AsyncHandlers` ready for 15 +processing from POSIX signal contexts. 16 + 17 +# Context 18 + 19 +This TIP is inspired by a request from FlightAware to fix threading issues 20 +in combination with TclX signal handling. 21 + 22 +# Rationale 23 + 24 +As of Tcl 8.6, the man page for `Tcl_AsyncMark` et.al. states that: 25 + 26 +> "These procedures provide a safe mechanism for dealing with asynchronous 27 +> events such as signals..." 28 + 29 +For the `Tcl_AsyncMark()` function, this claim is only true, when the Tcl 30 +core is built without threading support. Otherwise, the function needs 31 +to lock various mutexes to carry out its operation. But locking mutexes 32 +in a POSIX signal context is plain _verboten_. And even worse, many signals 33 +in POSIX have process context, and delivery to threads is random without 34 +thread-specific masks. 35 + 36 +# Specification 37 + 38 +A new API `Tcl_AsyncMarkFromSignal()` is introduced with the signature 39 + 40 + Tcl_AsyncMarkFromSignal(Tcl_AsyncHandler async, int sigNumber) 41 + 42 +where the sigNumber argument is the POSIX signal number. This function 43 +shall be called from POSIX signal contexts. For non-POSIX systems it 44 +shall be equivalent to calling `Tcl_AsyncMark()`. When called from a 45 +non-signal context, its behaviour is undefined. 46 + 47 +In case of the Tcl 8.6 `select()`-based notifier thread, this or a 48 +subfunction shall test if it runs in the notifier thread. If this is 49 +not the case, it shall resend the signal number to the notifier thread. 50 +If run in the notifier thread the function shall do whatever is necessary 51 +to perform a `Tcl_AsyncMark()` on the respective `Tcl_AsyncHandler`. In the 52 +current implementation of the notifier thread this is a `write()` 53 +of a single byte to the trigger pipe of the notifier thread. 54 +In order to avoid race conditions in the notifier thread it shall be 55 +started with all POSIX signals blocked, unblock all signals only when 56 +going into its `select()` based wait state, and block all signals afterwards. 57 + 58 +In case of epoll and kqueue notifiers, this or a subfunction shall test if it 59 +runs in the target thread of the `Tcl_AsyncHandler`. If this is not the 60 +case, it shall resend the signal number to this target thread. 61 +If run in the target thread the function shall do whatever is necessary 62 +to perform a `Tcl_AsyncMark()` on the respective `Tcl_AsyncHandler`. In the 63 +current implementations of the epoll and kqueue notifiers this is a 64 +`write()` of a single byte to an `event_fd` or a pipe, respectively. 65 + 66 +Independent of the implementation of the notifier, this approach must 67 +not make further assumptions regarding the runtime environment and its 68 +disposition of signals. However, as for the `select()`-based notifier 69 +thread it is allowed for all Tcl related threads to use their own 70 +thread-specific signal mask as required and rely on proper signal 71 +delivery by the OS and `Tcl_AsyncMarkFromSignal()`. 72 + 73 +And independent of signal dispositions this approach shall ensure 74 +that thread-specific `Tcl_AsyncHandlers` are directed to interrupt the 75 +owning target thread of the `Tcl_AsyncHandler`. 76 + 77 +# Related Bugs 78 + 79 +Bug #f4f44174 demonstrates a deadlock issue with a script based on TclX 80 +observed with the Tcl 8.6 `select()`-based notifier. It is caused by the 81 +`posix_mutex_*()` functions not supporting reentrant locking by default and 82 +not being async-signal-safe. 83 + 84 +# Implementation 85 + 86 +Currently, there's a fork/proof of concept available in 87 +https://www.androwish.org/index.html/info/40790af1e8e4ec9f based 88 +on the Tcl 8.6 `select()` notifier. 89 + 90 +# Copyright 91 + 92 +This document has been placed in the public domain.