diff options
author | John Högberg <[email protected]> | 2018-06-27 14:40:18 +0200 |
---|---|---|
committer | John Högberg <[email protected]> | 2018-06-28 08:39:15 +0200 |
commit | a9e579341181ed877379de022a261da81fc7cf8c (patch) | |
tree | a2688aa2f489121e4ff7a02469e274af9021866e /lib/kernel/internal_doc | |
parent | da06fd040775fffee17409ebbd6fa797e34d6f99 (diff) | |
download | otp-a9e579341181ed877379de022a261da81fc7cf8c.tar.gz otp-a9e579341181ed877379de022a261da81fc7cf8c.tar.bz2 otp-a9e579341181ed877379de022a261da81fc7cf8c.zip |
Fix a race condition when generating async operation ids
The counter used for generating async operation ids was a plain int
shared between all ports, which was incorrect but mostly worked
fine since the ids only had to be unique on a per-port basis.
However, some compilers (notably GCC 8.1.1) generated code that
assumed that this value didn't change between reads. Using a
shortened version of enq_async_w_tmo as an example:
int id = async_ref++;
op->id = id; //A
return id; //B
In GCC 7 and earlier, `async_ref` would be read once and assigned
to `id` before being incremented, which kept the values at A and B
consistent. In GCC 8, `async_ref` was read when assigned at A and
read again at B, and then incremented, which made them inconsistent
if we raced with another port.
This commit fixes the issue by removing `async_ref` altogether and
replacing it with a per-port counter which makes it impossible to
race with someone else.
Diffstat (limited to 'lib/kernel/internal_doc')
0 files changed, 0 insertions, 0 deletions