* 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

View File

@ -30,10 +30,6 @@ extern spinlock team_spinlock;
#define RELEASE_TEAM_LOCK() release_spinlock(&team_spinlock)
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_BIRTH // thread is being created
};
@ -55,7 +51,8 @@ struct death_entry {
team_id team;
thread_id thread;
status_t status;
uint32 reason;
uint16 reason;
uint16 signal;
};
struct process_session {
@ -174,7 +171,8 @@ struct thread {
struct {
sem_id sem;
status_t status;
uint32 reason;
uint16 reason;
uint16 signal;
struct list waiters;
} exit;

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.
* Copyright 2002, Angelo Mottola, a.mottola@libero.it.
*
* Distributed under the terms of the MIT License.
@ -161,8 +161,11 @@ handle_signals(struct thread *thread)
case SIGKILL:
case SIGKILLTHR:
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.signal = (uint16)signal;
}
// notify the debugger
if (debugSignal && signal != SIGKILL && signal != SIGKILLTHR

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.
*
* 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.
*/
static thread_id
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
// already got unregistered from the team or group
*_returnCode = death.status;
*_reason = death.reason;
*_reason = (death.signal << 16) | death.reason;
return death.thread;

View File

@ -207,6 +207,7 @@ create_thread_struct(const char *name, thread_id threadID)
thread->last_time = 0;
thread->exit.status = 0;
thread->exit.reason = 0;
thread->exit.signal = 0;
list_init(&thread->exit.waiters);
sprintf(temp, "thread_0x%lx_retcode_sem", thread->id);
@ -957,6 +958,7 @@ thread_exit(void)
death->thread = thread->id;
death->status = thread->exit.status;
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) {
death->status = thread->exit.status;
death->reason = thread->exit.reason;
death->signal = thread->exit.signal;
}
RELEASE_THREAD_LOCK();

View File

@ -1,10 +1,11 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
/*
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <syscalls.h>
#include <thread_types.h>
#include <sys/wait.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);
if (_status != NULL) {
// ToDo: fill in _status!
*_status = 0;
int status = returnCode & 0xff;
// 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) {