aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_utils.erl
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2018-06-27 14:40:18 +0200
committerJohn Högberg <[email protected]>2018-06-28 08:39:15 +0200
commita9e579341181ed877379de022a261da81fc7cf8c (patch)
treea2688aa2f489121e4ff7a02469e274af9021866e /lib/compiler/src/beam_utils.erl
parentda06fd040775fffee17409ebbd6fa797e34d6f99 (diff)
downloadotp-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/compiler/src/beam_utils.erl')
0 files changed, 0 insertions, 0 deletions