Check-in [61ea8fa199]

Login

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

Overview
Comment:TIP #509: Initial draft complete
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 61ea8fa199ebe88172d0e8df9a3342566b2b52c977f62ae3f52d5e011b0a9c0c
User & Date: fbonnet 2018-05-25 21:51:45.548
Context
2018-05-26
09:49
Fixed typo in JO's name (SHAME!) check-in: 22823b2821 user: fbonnet tags: trunk
2018-05-25
21:51
TIP #509: Initial draft complete check-in: 61ea8fa199 user: fbonnet tags: trunk
09:44
Add more examples to 500 check-in: ca2e14f744 user: dkf tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to tip/509.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
# TIP 509: Implement reentrant mutexes on all platforms
	Author:         Frédéric Bonnet <[email protected]>
	State:          Draft
	Type:           Project
	Vote:           
	Created:        24-May-2018
	Post-History:   
	Keywords:       Tcl,threads
	Tcl-Version:	8.7
-----

# Abstract

TODO


# Context





TODO

# Rationale


TODO


















# Specifications


TODO









# Portability issues


TODO










































# Related Bugs

TODO







# Implementation

The proposed implementation is available on branch
[tip-509](https://core.tcl.tk/tcl/timeline?r=tip-509) in the Tcl Fossil
repository.














|
>



>
>
>
>
|



>
|
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
|
>
>
|
>
>
>
>
>
>


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



<
>
>
>
>
>
>







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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
# TIP 509: Implement reentrant mutexes on all platforms
	Author:         Frédéric Bonnet <[email protected]>
	State:          Draft
	Type:           Project
	Vote:           
	Created:        24-May-2018
	Post-History:   
	Keywords:       Tcl,threads
	Tcl-Version:	8.7
-----

# Abstract

This TIP proposes to improve the `Tcl_Mutex` API by enforcing a consistent
behavior on all core-supported platforms regarding reentrancy.

# Context

This TIP is inspired by a [request from
FlightAware](https://github.com/flightaware/Tcl-bounties#make-tclxs-signal-trap-handlers-safe-to-use-with-threaded-tcl)
to fix deadlock issues with TclX signal handling. A specific issue has been
opened to discuss the proposed implementation [here](https://github.com/flightaware/Tcl-bounties/issues/32).


# Rationale

As of Tcl 8.6, the man page for thread support `Thread.3` states that:

> The result of locking a mutex twice from the same thread is undefined. On some
> platforms it will result in a deadlock.

On Windows platforms, mutexes are implemented using Win32 critical sections,
which are reentrant. `Tcl_Mutex` are just plain `CRITICAL_SECTION *`.

On Unix platforms (this includes MacOS X), Tcl relies on the **pthread** library
for multithreading and synchronization primitives such as mutexes. `Tcl_Mutex`
are just plain `pthread_mutex_t *`. **pthread** mutexes are not reentrant by
default, though the `PTHREAD_MUTEX_RECURSIVE` attribute can be used at creation
time to make them so, but this possibility is not available on older systems.

The Tcl philosophy has always been to erase platform-specific peculiarities in
favor of overall multi-platform consistency, sometimes to the point of
implementing or emulating commonly available features on less capable platforms.
Therefore it feels natural to pursue this goal by making `Tcl_Mutex` reentrant
on all platforms and achieving a consistent behavior on both Windows and Unix.

# Specifications

This TIP proposes to replace the following text from the `Thread.3` man page:

> The result of locking a mutex twice from the same thread is undefined. On some
> platforms it will result in a deadlock.
 
by the following text:

> Mutexes are reentrant: they can be locked several times from the same thread.
> However there must be exactly one call to **Tcl_MutexUnlock** for each call to
> **Tcl_MutexLock** in order for a thread to release a mutex completely.

# Portability issues

## Windows

Mutexes are naturally reentrant on Windows systems, so no special work is
required.

## Unix

On **pthread**-based Unix systems that support the `PTHREAD_MUTEX_RECURSIVE`
attribute, all `pthread_mutex_t` made available as `Tcl_Mutex` will be created
using this attribute. This includes all but the oldest variants of Unix.

On **pthread**-based Unix systems that do not support the
`PTHREAD_MUTEX_RECURSIVE` attribute, reentrancy will be achieved by combining a
regular, non-reentrant `pthread_mutex_t`, with a thread-specific lock counter
accessible through a `pthread_key_t` data key. This counter keeps track of the
number of calls to `Tcl_MutexLock` minus the number of calls to
`Tcl_Mutex_Unlock`. `Tcl_MutexLock` increments the counter, but only calls
`pthread_mutex_lock` when the initial value is zero. `Tcl_Mutex_Unlock` behaves
symmetrically: it decrements the counter, and only calls `pthread_mutex_lock`
when it reaches zero. This ensures that a thread never calls 
`pthread_mutex_lock` twice on the same mutex, and only calls 
`pthread_mutex_unlock` when the thread no longer holds it.

Detection of `PTHREAD_MUTEX_RECURSIVE` availability is done at configure time
thanks to the `AC_CHECK_DECLS` autoconf macro in `tcl.m4`.

# Potential incompatibilities

Although this TIP introduces a major change to `Tcl_Mutex` behavior on Unix, it
is very unlikely that this will break any existing code: 

- Windows-only code will see no change in behavior.
- Unix-only code with reentrant mutexes is fatally flawed in the current state
  of the Tcl core, since this results in a deadlock. At best, this TIP will fix
  such hard-to-reproduce situations (case in point: TclX signals), and the code
  will transition from the nonworking state to the working state (which,
  according to Dr. John Ousterhoot, is the best performance improvement). At
  worst, this change will trigger a new class of reentrancy-related bugs on
  already broken code.
- Multiplatform code in its current form behaves either inconsistently or
  consistently, depending on whether it uses reentrant mutexes or not.
  Consistent code will remain consistent, inconsistent code will become
  consistent as the Unix version aligns with the Windows version.

# Related Bugs


[Bug #f4f44174](https://core.tcl.tk/tcl/tktview/f4f44174) demonstrates the
deadlock issue with a script based on TclX. The root cause is the asynchronous
event handler's `Tcl_Mutex` being locked twice from the same thread when a
signal handler interrupts a thread in the middle of a mutex-protected section,
which on Unix platforms results in a deadlock. The proposed implementation fixes
this issue.

# Implementation

The proposed implementation is available on branch
[tip-509](https://core.tcl.tk/tcl/timeline?r=tip-509) in the Tcl Fossil
repository.