Check-in [063fc0cf1c]

Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added TIP 511 for Christian Werner, who is having problems with his fossil login
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 063fc0cf1cf7ae03ccdadb46de30a781994265edc3654d1d294daf62729d89df
User & Date: dkf 2018-06-20 12:20:37.064
Context
2018-06-22
14:18
Correction from Christian Werner check-in: eadd78dd7f user: dkf tags: trunk
2018-06-20
12:20
Added TIP 511 for Christian Werner, who is having problems with his fossil login check-in: 063fc0cf1c user: dkf tags: trunk
2018-06-17
16:52
Got the description of classvariable wrong. check-in: e3243a6107 user: dkf tags: trunk
Changes
Unified Diff Show Whitespace Changes Patch
Changes to index.json.

cannot compute difference between binary files

Changes to index.md.
102
103
104
105
106
107
108







109
110
111
112
113
114
115
<th>#</th>
<th>Type</th>
<th>Tcl Version</th>
<th>Status</th>
<th>Title</th>
</tr></thead><tbody>








<tr class='project projectdraft projectdraft87 project87'>
<td valign='top'><a href='./tip/510.md'>510</a></td>
<td valign='top'>Project</td>
<td valign='top'>8.7</td>
<td valign='top'>Draft</td>
<td valign='top'># TIP 510: Add Rbc to Tk</td>
</tr>







>
>
>
>
>
>
>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<th>#</th>
<th>Type</th>
<th>Tcl Version</th>
<th>Status</th>
<th>Title</th>
</tr></thead><tbody>

<tr class='project projectdraft projectdraft87 project87'>
<td valign='top'><a href='./tip/511.md'>511</a></td>
<td valign='top'>Project</td>
<td valign='top'>8.7</td>
<td valign='top'>Draft</td>
<td valign='top'># TIP 511: Implement Tcl_AsyncMarkFromSignal()</td>
</tr>
<tr class='project projectdraft projectdraft87 project87'>
<td valign='top'><a href='./tip/510.md'>510</a></td>
<td valign='top'>Project</td>
<td valign='top'>8.7</td>
<td valign='top'>Draft</td>
<td valign='top'># TIP 510: Add Rbc to Tk</td>
</tr>
Added tip/511.md.
























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# TIP 511: Implement Tcl_AsyncMarkFromSignal()
	Author:         Christian Werner <[email protected]>
	State:          Draft
	Type:           Project
	Vote:           
	Created:        14-June-2018
	Post-History:   
	Keywords:       Tcl,threads
	Tcl-Version:	8.7
-----

# Abstract

This TIP proposes to add a Tcl API for marking `Tcl_AsyncHandlers` ready for
processing from POSIX signal contexts.

# Context

This TIP is inspired by a request from FlightAware to fix threading issues
in combination with TclX signal handling.

# Rationale

As of Tcl 8.6, the man page for `Tcl_AsyncMark` et.al. states that:

> "These procedures provide a safe mechanism for dealing with asynchronous
> events such as signals..."

For the `Tcl_AsyncMark()` function, this claim is only true, when the Tcl
core is built without threading support. Otherwise, the function needs
to lock various mutexes to carry out its operation. But locking mutexes
in a POSIX signal context is plain _verboten_. And even worse, many signals
in POSIX have process context, and delivery to threads is random without
thread-specific masks.

# Specification

A new API `Tcl_AsyncMarkFromSignal()` is introduced with the signature

    Tcl_AsyncMarkFromSignal(Tcl_AsyncHandler async, int sigNumber)

where the sigNumber argument is the POSIX signal number. This function
shall be called from POSIX signal contexts. For non-POSIX systems it
shall be equivalent to calling `Tcl_AsyncMark()`. When called from a
non-signal context, its behaviour is undefined.

In case of the Tcl 8.6 `select()`-based notifier thread, this or a
subfunction shall test if it runs in the notifier thread. If this is
not the case, it shall resend the signal number to the notifier thread.
If run in the notifier thread the function shall do whatever is necessary
to perform a `Tcl_AsyncMark()` on the respective `Tcl_AsyncHandler`. In the
current implementation of the notifier thread this is a `write()`
of a single byte to the trigger pipe of the notifier thread.
In order to avoid race conditions in the notifier thread it shall be
started with all POSIX signals blocked, unblock all signals only when
going into its `select()` based wait state, and block all signals afterwards.

In case of epoll and kqueue notifiers, this or a subfunction shall test if it
runs in the target thread of the `Tcl_AsyncHandler`. If this is not the
case, it shall resend the signal number to this target thread.
If run in the target thread the function shall do whatever is necessary
to perform a `Tcl_AsyncMark()` on the respective `Tcl_AsyncHandler`. In the
current implementations of the epoll and kqueue notifiers this is a
`write()` of a single byte to an `event_fd` or a pipe, respectively.

Independent of the implementation of the notifier, this approach must
not make further assumptions regarding the runtime environment and its
disposition of signals. However, as for the `select()`-based notifier
thread it is allowed for all Tcl related threads to use their own
thread-specific signal mask as required and rely on proper signal
delivery by the OS and `Tcl_AsyncMarkFromSignal()`.

And independent of signal dispositions this approach shall ensure
that thread-specific `Tcl_AsyncHandlers` are directed to interrupt the
owning target thread of the `Tcl_AsyncHandler`.

# Related Bugs

Bug #f4f44174 demonstrates a deadlock issue with a script based on TclX
observed with the Tcl 8.6 `select()`-based notifier. It is caused by the
`posix_mutex_*()` functions not supporting reentrant locking by default and
not being async-signal-safe.

# Implementation

Currently, there's a fork/proof of concept available in
https://www.androwish.org/index.html/info/40790af1e8e4ec9f based
on the Tcl 8.6 `select()` notifier.

# Copyright

This document has been placed in the public domain.