Author: Armin Rigo <ar...@tunes.org>
Branch: ec-keepalive
Changeset: r81568:18bd10183487
Date: 2016-01-05 08:39 +0000
http://bitbucket.org/pypy/pypy/changeset/18bd10183487/

Log:    After fork(), at least in the __thread case, we need to be careful
        and reinitialize the doubly-linked list. Otherwise, it points to old
        __thread structures, which are silently gone from memory.

diff --git a/rpython/translator/c/src/threadlocal.c 
b/rpython/translator/c/src/threadlocal.c
--- a/rpython/translator/c/src/threadlocal.c
+++ b/rpython/translator/c/src/threadlocal.c
@@ -12,12 +12,16 @@
    manipulation (because such manipulations can occur without the GIL) */
 static long pypy_threadlocal_lock = 0;
 
+static int check_valid(void);
+
 void _RPython_ThreadLocals_Acquire(void) {
     while (!lock_test_and_set(&pypy_threadlocal_lock, 1)) {
         /* busy loop */
     }
+    assert(check_valid());
 }
 void _RPython_ThreadLocals_Release(void) {
+    assert(check_valid());
     lock_release(&pypy_threadlocal_lock);
 }
 
@@ -34,6 +38,43 @@
     &linkedlist_head,       /* prev      */
     &linkedlist_head };     /* next      */
 
+static int check_valid(void)
+{
+    struct pypy_threadlocal_s *prev, *cur;
+    prev = &linkedlist_head;
+    while (1) {
+        cur = prev->next;
+        assert(cur->prev == prev);
+        if (cur == &linkedlist_head)
+            break;
+        assert(cur->ready == 42);
+        assert(cur->next != cur);
+        prev = cur;
+    }
+    assert(cur->ready == -1);
+    return 1;
+}
+
+static void cleanup_after_fork(void)
+{
+    /* assume that at most one pypy_threadlocal_s survived, the current one */
+    struct pypy_threadlocal_s *cur;
+#ifdef USE___THREAD
+    cur = &pypy_threadlocal;
+#else
+    cur = (struct pypy_threadlocal_s *)_RPy_ThreadLocals_Get();
+#endif
+    if (cur && cur->ready == 42) {
+        cur->next = cur->prev = &linkedlist_head;
+        linkedlist_head.next = linkedlist_head.prev = cur;
+    }
+    else {
+        linkedlist_head.next = linkedlist_head.prev = &linkedlist_head;
+    }
+    _RPython_ThreadLocals_Release();
+}
+
+
 struct pypy_threadlocal_s *
 _RPython_ThreadLocals_Enum(struct pypy_threadlocal_s *prev)
 {
@@ -149,7 +190,7 @@
 #ifndef _WIN32
     pthread_atfork(_RPython_ThreadLocals_Acquire,
                    _RPython_ThreadLocals_Release,
-                   _RPython_ThreadLocals_Release);
+                   cleanup_after_fork);
 #endif
 }
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to