kill now sends the signal to the main thread of a process only. To target a specific thread use the new send_signal syscall. Also added set_alarm.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1662 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
#include <kernel.h>
|
||||
#include <debug.h>
|
||||
#include <thread.h>
|
||||
@@ -183,9 +184,26 @@ has_signals_pending(struct thread *t)
|
||||
|
||||
|
||||
int
|
||||
sys_kill(pid_t tid, int sig)
|
||||
sys_kill(pid_t pid, int sig)
|
||||
{
|
||||
return send_signal_etc(tid, sig, 0);
|
||||
struct team *t;
|
||||
int state;
|
||||
thread_id tid = -1;
|
||||
|
||||
// XXX check for permissions
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_THREAD_LOCK();
|
||||
t = team_get_team_struct_locked(pid);
|
||||
if ((t) && (t->main_thread))
|
||||
tid = t->main_thread->id;
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
|
||||
if (sig)
|
||||
return send_signal_etc(tid, sig, 0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -247,3 +265,36 @@ sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Triggers a SIGALRM to the thread that issued the timer and reschedules
|
||||
static int32
|
||||
alarm_event(timer *t)
|
||||
{
|
||||
int tid = *((int *)((void *)t + sizeof(timer)));
|
||||
|
||||
send_signal_etc(tid, SIGALRM, B_DO_NOT_RESCHEDULE);
|
||||
|
||||
return B_INVOKE_SCHEDULER;
|
||||
}
|
||||
|
||||
|
||||
bigtime_t
|
||||
sys_set_alarm(bigtime_t time, uint32 mode)
|
||||
{
|
||||
struct thread *t = thread_get_current_thread();
|
||||
int state;
|
||||
bigtime_t rv = 0;
|
||||
|
||||
state = disable_interrupts();
|
||||
|
||||
if (t->alarm.period)
|
||||
rv = (bigtime_t)t->alarm.entry.key - system_time();
|
||||
cancel_timer(&t->alarm);
|
||||
if (time != B_INFINITE_TIMEOUT)
|
||||
add_timer(&t->alarm, &alarm_event, time, mode);
|
||||
|
||||
restore_interrupts(state);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -395,6 +395,12 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
|
||||
case SYSCALL_SIGACTION:
|
||||
*call_ret = user_sigaction((int)arg0, (const struct sigaction *)arg1, (struct sigaction *)arg2);
|
||||
break;
|
||||
case SYSCALL_SEND_SIGNAL:
|
||||
*call_ret = send_signal_etc((pid_t)arg0, (uint)arg1);
|
||||
break;
|
||||
case SYSCALL_SET_ALARM:
|
||||
*call_ret = sys_set_alarm((bigtime_t)INT32TOINT64(arg0, arg1), (uint32)arg2);
|
||||
break;
|
||||
default:
|
||||
*call_ret = -1;
|
||||
}
|
||||
|
||||
@@ -971,6 +971,9 @@ thread_exit(int retcode)
|
||||
// boost our priority to get this over with
|
||||
thread_set_priority(t->id, B_FIRST_REAL_TIME_PRIORITY);
|
||||
|
||||
// Cancel previously installed alarm timer, if any
|
||||
cancel_timer(&t->alarm);
|
||||
|
||||
// delete the user stack region first
|
||||
if (p->_aspace_id >= 0 && t->user_stack_region_id >= 0) {
|
||||
region_id rid = t->user_stack_region_id;
|
||||
|
||||
Reference in New Issue
Block a user