Hi,
I played a litte bit with thread groups and found an unexpected?? behaviour
if the parent of a member of a thread group having childs dies.
The child threads are configured to sent a different signal than SIGCHLD to
their parent thread - a rt sig. The following configuration is checked:
init
\_ bash
\_ parent_process
\_ thread_group_leader (created by fork, exit signal 17, tgid==pid)
\_ thread_1 (created by clone(..., flags | CLONE_THREAD| sig33) by
the
| group_leader_thread)
\_ thread_2 (create by clone(..., flags |CLONE_THREAD| sig33)
by thread_1)
Thread_1 or thread_2 or both exits in this situation - a sig 33 is delivered
to the thread_group_leader for every thread as expected.
Suppose the configuration above and the parent process exits. The thread
group
leader thread was converted to a child of init:
init
\_ thread_group_leader (created by fork, exit signal 17, tgid==pid)
\_ thread_1 (created by clone(..., flags | CLONE_THREAD| sig33) by the
| group_leader_thread)
\_ thread_2 (create by clone(..., flags |CLONE_THREAD|CLONE_PARENT|sig33)
by thread_1)
The function forget_original_parent in kernel/exit.c incremented the exec_id
of the thread_group_leader during the exit of the parent process.
A SIGCHLD signal is sent now to the thread_group_leader if one of its
child threads exits because of the queries in the function exit_notify in
the file kernel/exit.c:
if (current->exit_signal != SIGCHLD &&
(current->parent_exec_id != t->self_exec_id ||
current->self_exec_id != current->parent_exec_id))
&& !capable (CAP_KILL))
current->exit_signal = SIGCHLD;
I would expect, that changes of the parent of one member of the thread group
do not affect the interactions between the members of the group.
Corrections are welcome.
(Please cc mails to me, I read only the archives of the
linux-kernel list.)
The patch below keeps the child threads in the same exec_id if they are
childs
of the thread with the changing parent (against 2.4.18-ngpt, but should
apply
also against 2.4.19). For 2.5 series p_opptr has to be renamed real_parent.
Axel
Dr. Axel Zeuner
Consultant e.business D
email: axel.zeuner@systor.com.
--- kernel/exit.c.original Mon Aug 5 09:09:31 2002
+++ kernel/exit.c Mon Aug 5 09:53:22 2002
@@ -174,8 +174,22 @@
for_each_task(p) {
if (p->p_opptr == father) {
+ struct task_struct *tg_member;
/* We dont want people slaying init */
p->exit_signal = SIGCHLD;
+ /* Keep all members of the thread group with
+ p as real parent in the same exec id.
+ This prevents the generation of SIGCHLD
+ instead of the configured signal on exit
+ of slave threads of p
+ */
+ for ( tg_member = next_thread(p); tg_member!=p;
+ tg_member = next_thread(tg_member)) {
+ if ( tg_member->p_opptr == p ) {
+ ++tg_member->self_exec_id;
+ ++tg_member->parent_exec_id;
+ }
+ }
p->self_exec_id++;
/* Make sure we're not reparenting to ourselves */
This archive was generated by hypermail 2b29 : Wed Aug 07 2002 - 22:00:26 EST