* The kernel now remembers the signal that killed a thread (if it was killed).

* As suggested by Korli, the signal is now encoded in the "reason" field of
  wait_for_child().
* waitpid() now sets the status passed in so that the signal can be read out
  (but it still doesn't do it's full job).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17338 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-05-05 15:33:34 +00:00
parent ac3b691a1d
commit 2bbc6df8dc
5 changed files with 27 additions and 17 deletions
+4 -6
View File
@@ -30,10 +30,6 @@ extern spinlock team_spinlock;
#define RELEASE_TEAM_LOCK() release_spinlock(&team_spinlock) #define RELEASE_TEAM_LOCK() release_spinlock(&team_spinlock)
enum additional_thread_state { enum additional_thread_state {
// THREAD_STATE_READY = 0, // ready to run
// THREAD_STATE_RUNNING, // running right now somewhere
// THREAD_STATE_WAITING, // blocked on something
// THREAD_STATE_SUSPENDED, // suspended, not in queue
THREAD_STATE_FREE_ON_RESCHED = 7, // free the thread structure upon reschedule THREAD_STATE_FREE_ON_RESCHED = 7, // free the thread structure upon reschedule
// THREAD_STATE_BIRTH // thread is being created // THREAD_STATE_BIRTH // thread is being created
}; };
@@ -55,7 +51,8 @@ struct death_entry {
team_id team; team_id team;
thread_id thread; thread_id thread;
status_t status; status_t status;
uint32 reason; uint16 reason;
uint16 signal;
}; };
struct process_session { struct process_session {
@@ -174,7 +171,8 @@ struct thread {
struct { struct {
sem_id sem; sem_id sem;
status_t status; status_t status;
uint32 reason; uint16 reason;
uint16 signal;
struct list waiters; struct list waiters;
} exit; } exit;
+5 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2005, Axel Dörfler, [email protected]. * Copyright 2002-2006, Axel Dörfler, [email protected].
* Copyright 2002, Angelo Mottola, [email protected]. * Copyright 2002, Angelo Mottola, [email protected].
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -161,8 +161,11 @@ handle_signals(struct thread *thread)
case SIGKILL: case SIGKILL:
case SIGKILLTHR: case SIGKILLTHR:
default: default:
if (thread->exit.reason != THREAD_RETURN_EXIT) // if the thread exited normally, the exit reason is already set
if (thread->exit.reason != THREAD_RETURN_EXIT) {
thread->exit.reason = THREAD_RETURN_INTERRUPTED; thread->exit.reason = THREAD_RETURN_INTERRUPTED;
thread->exit.signal = (uint16)signal;
}
// notify the debugger // notify the debugger
if (debugSignal && signal != SIGKILL && signal != SIGKILLTHR if (debugSignal && signal != SIGKILL && signal != SIGKILLTHR
+2 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. * Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@@ -1648,7 +1648,6 @@ get_death_entry(struct team *team, pid_t child, struct death_entry *death,
* to the reason why a thread has died than waitpid() can be. * to the reason why a thread has died than waitpid() can be.
*/ */
static thread_id static thread_id
wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnCode) wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnCode)
{ {
@@ -1715,7 +1714,7 @@ wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnC
// when we got here, we have a valid death entry, and // when we got here, we have a valid death entry, and
// already got unregistered from the team or group // already got unregistered from the team or group
*_returnCode = death.status; *_returnCode = death.status;
*_reason = death.reason; *_reason = (death.signal << 16) | death.reason;
return death.thread; return death.thread;
+3
View File
@@ -207,6 +207,7 @@ create_thread_struct(const char *name, thread_id threadID)
thread->last_time = 0; thread->last_time = 0;
thread->exit.status = 0; thread->exit.status = 0;
thread->exit.reason = 0; thread->exit.reason = 0;
thread->exit.signal = 0;
list_init(&thread->exit.waiters); list_init(&thread->exit.waiters);
sprintf(temp, "thread_0x%lx_retcode_sem", thread->id); sprintf(temp, "thread_0x%lx_retcode_sem", thread->id);
@@ -957,6 +958,7 @@ thread_exit(void)
death->thread = thread->id; death->thread = thread->id;
death->status = thread->exit.status; death->status = thread->exit.status;
death->reason = thread->exit.reason; death->reason = thread->exit.reason;
death->signal = thread->exit.signal;
} }
} }
@@ -1038,6 +1040,7 @@ thread_exit(void)
while ((death = list_get_next_item(&thread->exit.waiters, death)) != NULL) { while ((death = list_get_next_item(&thread->exit.waiters, death)) != NULL) {
death->status = thread->exit.status; death->status = thread->exit.status;
death->reason = thread->exit.reason; death->reason = thread->exit.reason;
death->signal = thread->exit.signal;
} }
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
+13 -6
View File
@@ -1,10 +1,11 @@
/* /*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the Haiku License. * Distributed under the terms of the MIT License.
*/ */
#include <syscalls.h> #include <syscalls.h>
#include <thread_types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <stdio.h> #include <stdio.h>
@@ -30,8 +31,14 @@ waitpid(pid_t pid, int *_status, int options)
thread_id thread = _kern_wait_for_child(pid, options, &reason, &returnCode); thread_id thread = _kern_wait_for_child(pid, options, &reason, &returnCode);
if (_status != NULL) { if (_status != NULL) {
// ToDo: fill in _status! int status = returnCode & 0xff;
*_status = 0;
// ToDo: fill in _status correctly!
// See kernel's wait_for_child() for how the return information is encoded
if (reason & THREAD_RETURN_INTERRUPTED)
status = (reason >> 8) & 0xff00;
*_status = status;
} }
if (thread < B_OK) { if (thread < B_OK) {