* 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:
parent
ac3b691a1d
commit
2bbc6df8dc
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user