提交 0d0c2f40 编写于 作者: R Rich Felker

fix deadlock race in pthread_once

at the end of successful pthread_once, there was a race window during
which another thread calling pthread_once would momentarily change the
state back from 2 (finished) to 1 (in-progress). in this case, the
status was immediately changed back, but with no wake call, meaning
that waiters which arrived during this short window could block
forever. there are two possible fixes. one would be adding the wake to
the code path where it was missing. but it's better just to avoid
reverting the status at all, by using compare-and-swap instead of
swap.
上级 fcea534e
......@@ -18,7 +18,7 @@ int pthread_once(pthread_once_t *control, void (*init)(void))
* 1 - another thread is running init; wait
* 2 - another thread finished running init; just return */
for (;;) switch (a_swap(control, 1)) {
for (;;) switch (a_cas(control, 0, 1)) {
case 0:
pthread_cleanup_push(undo, control);
init();
......@@ -31,7 +31,6 @@ int pthread_once(pthread_once_t *control, void (*init)(void))
__wait(control, &waiters, 1, 0);
continue;
case 2:
a_store(control, 2);
return 0;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册