The libpthread fork() wrapper makes two changes to the flags for the 
process: it clears the 'detached' flag and sets the 'original' flag.  I 
now believe those are both wrong and should be left as they are from the 
original process.

For the 'detached' flag, the POSIX spec does *not* mention the detached 
state as changed by fork() and GNU libc doesn't change it across fork().  
A ping to the austin-group mailing list appears to confirm this reading. I 
apparently introduced this bug when I submitted the fork() wrapper before 
I was a committer; about time I fixed it!

The 'original' flag just controls the result of the pthread_main_np() 
function.  The description of that function isn't 100% clear: "identifies 
the main thread", ok, but where is "main thread" defined?  We had 
interpreted it as meaning "the first thread in *this* process", and so 
would return 1 in the thread created by fork().  However it can also be 
interpreted as "this thread's call history traces back to main()", which 
is true of the child of fork() iff it was true in the parent, and is what 
the THREAD_INITIAL_STACK flag already conveys.  So I looked at the ports 
tree and the only code that I can see using pthread_main_np() is 
x11/gnustep/base where the latter semantic appears to be the desired 
behavior.  This diff thus eliminates the separate THREAD_ORIGINAL flag and 
change pthread_main_np() to test THREAD_INITIAL_STACK.

So, any GNUstep users who can test this?

oks?


Philip Guenther


Index: rthread.c
===================================================================
RCS file: /data/src/openbsd/src/lib/librthread/rthread.c,v
retrieving revision 1.90
diff -u -p -r1.90 rthread.c
--- rthread.c   2 Apr 2016 19:56:53 -0000       1.90
+++ rthread.c   11 Apr 2016 04:37:28 -0000
@@ -193,7 +193,7 @@ _rthread_init(void)
        thread->tid = getthrid();
        thread->donesem.lock = _SPINLOCK_UNLOCKED_ASSIGN;
        thread->flags |= THREAD_CANCEL_ENABLE | THREAD_CANCEL_DEFERRED |
-           THREAD_ORIGINAL | THREAD_INITIAL_STACK;
+           THREAD_INITIAL_STACK;
        thread->flags_lock = _SPINLOCK_UNLOCKED_ASSIGN;
        strlcpy(thread->name, "Main process", sizeof(thread->name));
        LIST_INSERT_HEAD(&_thread_list, thread, threads);
Index: rthread.h
===================================================================
RCS file: /data/src/openbsd/src/lib/librthread/rthread.h,v
retrieving revision 1.56
diff -u -p -r1.56 rthread.h
--- rthread.h   2 Apr 2016 19:00:51 -0000       1.56
+++ rthread.h   11 Apr 2016 04:37:39 -0000
@@ -189,7 +189,6 @@ struct pthread {
 #define        THREAD_CANCEL_DEFERRED  0x010
 #define        THREAD_CANCEL_DELAY     0x020
 #define        THREAD_DYING            0x040
-#define        THREAD_ORIGINAL         0x080   /* original thread from fork */
 #define        THREAD_INITIAL_STACK    0x100   /* thread with stack from exec 
*/
 
 #define        IS_CANCELED(thread) \
Index: rthread_fork.c
===================================================================
RCS file: /data/src/openbsd/src/lib/librthread/rthread_fork.c,v
retrieving revision 1.16
diff -u -p -r1.16 rthread_fork.c
--- rthread_fork.c      2 Apr 2016 19:00:51 -0000       1.16
+++ rthread_fork.c      11 Apr 2016 04:31:13 -0000
@@ -99,11 +99,7 @@ _dofork(int is_vfork)
                /* update this thread's structure */
                me->tid = getthrid();
                me->donesem.lock = _SPINLOCK_UNLOCKED_ASSIGN;
-               me->flags &= ~THREAD_DETACHED;
                me->flags_lock = _SPINLOCK_UNLOCKED_ASSIGN;
-
-               /* this thread is the initial thread for the new process */
-               me->flags |= THREAD_ORIGINAL;
 
                /* reinit the thread list */
                LIST_INIT(&_thread_list);
Index: rthread_np.c
===================================================================
mRCS file: /data/src/openbsd/src/lib/librthread/rthread_np.c,v
retrieving revision 1.18
diff -u -p -r1.18 rthread_np.c
--- rthread_np.c        2 Apr 2016 19:00:51 -0000       1.18
+++ rthread_np.c        11 Apr 2016 04:38:09 -0000
@@ -47,8 +47,8 @@ pthread_set_name_np(pthread_t thread, co
 int
 pthread_main_np(void)
 {
-       return (!_threads_ready || (pthread_self()->flags & THREAD_ORIGINAL)
-           ? 1 : 0);
+       return (!_threads_ready ||
+           (pthread_self()->flags & THREAD_INITIAL_STACK) ? 1 : 0);
 }
 
 

Reply via email to