aboutsummaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-10-28 01:08:55 +0000
committerUlrich Drepper <drepper@redhat.com>2007-10-28 01:08:55 +0000
commitad3371fbac6896adc4820434676f35bd44a24cf8 (patch)
tree114d0b6de6e6bd4d52ae386bd4bd1328c9fc56d5 /nptl/sysdeps/unix
parent666aa0201b5e68d13d24d7e9151c7d548d5cbbda (diff)
downloadglibc-ad3371fbac6896adc4820434676f35bd44a24cf8.tar
glibc-ad3371fbac6896adc4820434676f35bd44a24cf8.tar.gz
glibc-ad3371fbac6896adc4820434676f35bd44a24cf8.tar.bz2
glibc-ad3371fbac6896adc4820434676f35bd44a24cf8.zip
[BZ #5208]
2007-10-23 Andreas Jaeger <aj@suse.de> [BZ #5208] * sysdeps/unix/sysv/linux/readahead.c (__readahead): Use __LONG_LONG_PAIR to handle little endian byte order. Suggested by abhishekrai@google.com
Diffstat (limited to 'nptl/sysdeps/unix')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/register-atfork.c12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/unregister-atfork.c13
3 files changed, 27 insertions, 1 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/nptl/sysdeps/unix/sysv/linux/fork.h
index 032b68f083..a00cfabe26 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.h
+++ b/nptl/sysdeps/unix/sysv/linux/fork.h
@@ -55,3 +55,6 @@ extern int __register_atfork (void (*__prepare) (void),
void (*__child) (void),
void *dso_handle);
libc_hidden_proto (__register_atfork)
+
+/* Add a new element to the fork list. */
+extern void __linkin_atfork (struct fork_handler *newp) attribute_hidden;
diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/sysdeps/unix/sysv/linux/register-atfork.c
index 231fc9b091..71abd0fb96 100644
--- a/nptl/sysdeps/unix/sysv/linux/register-atfork.c
+++ b/nptl/sysdeps/unix/sysv/linux/register-atfork.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <fork.h>
+#include <atomic.h>
/* Lock to protect allocation and deallocation of fork handlers. */
@@ -109,6 +110,17 @@ __register_atfork (prepare, parent, child, dso_handle)
libc_hidden_def (__register_atfork)
+void
+attribute_hidden
+__linkin_atfork (struct fork_handler *newp)
+{
+ do
+ newp->next = __fork_handlers;
+ while (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
+ newp, newp->next) != 0);
+}
+
+
libc_freeres_fn (free_mem)
{
/* Get the lock to not conflict with running forks. */
diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
index 56a4f149e1..c738acd0c3 100644
--- a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
+++ b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
@@ -67,10 +67,21 @@ __unregister_atfork (dso_handle)
It's a single linked list so readers are. */
do
{
+ again:
if (runp->dso_handle == dso_handle)
{
if (lastp == NULL)
- __fork_handlers = runp->next;
+ {
+ /* We have to use an atomic operation here because
+ __linkin_atfork also uses one. */
+ if (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
+ runp->next, runp)
+ != 0)
+ {
+ runp = __fork_handlers;
+ goto again;
+ }
+ }
else
lastp->next = runp->next;