Fix untimely delivery of signals during userfs reference count messages.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-08-14 16:24:40 +00:00
parent 8e86952abf
commit 22351d7f72
4 changed files with 27 additions and 4 deletions

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -657,6 +657,10 @@ Unode::Unode(Ref<Server> server, ino_t ino, mode_t type)
this->type = type;
// Let the remote know that the kernel is using this inode.
Thread* thread = CurrentThread();
bool saved = thread->force_no_signals;
thread->force_no_signals = true;
thread->DoUpdatePendingSignal();
if ( Channel* channel = server->Connect(NULL) )
{
struct fsm_req_refer msg;
@ -664,11 +668,17 @@ Unode::Unode(Ref<Server> server, ino_t ino, mode_t type)
SendMessage(channel, FSM_REQ_REFER, &msg, sizeof(msg));
channel->KernelClose();
}
thread->force_no_signals = saved;
thread->DoUpdatePendingSignal();
}
Unode::~Unode()
{
// Let the remote know that the kernel is no longer using this inode.
Thread* thread = CurrentThread();
bool saved = thread->force_no_signals;
thread->force_no_signals = true;
thread->DoUpdatePendingSignal();
if ( Channel* channel = server->Connect(NULL) )
{
struct fsm_req_unref msg;
@ -676,6 +686,8 @@ Unode::~Unode()
SendMessage(channel, FSM_REQ_UNREF, &msg, sizeof(msg));
channel->KernelClose();
}
thread->force_no_signals = saved;
thread->DoUpdatePendingSignal();
}
bool Unode::SendMessage(Channel* channel, size_t type, void* ptr, size_t size,

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -82,12 +82,14 @@ public:
size_t kernelstacksize;
bool kernelstackmalloced;
bool pledged_destruction;
bool force_no_signals;
public:
void HandleSignal(struct interrupt_context* intctx);
void HandleSigreturn(struct interrupt_context* intctx);
bool DeliverSignal(int signum);
bool DeliverSignalUnlocked(int signum);
void DoUpdatePendingSignal();
};

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -97,6 +97,8 @@ void UpdatePendingSignals(Thread* thread) // thread->process->signal_lock held
// Determine whether any signals can be delivered.
unsigned long is_pending = !sigisemptyset(&deliverable_signals) ? 1 : 0;
if ( thread->force_no_signals )
is_pending = 0;
// Store whether a signal is pending in the virtual register.
if ( thread == CurrentThread() )
@ -105,6 +107,12 @@ void UpdatePendingSignals(Thread* thread) // thread->process->signal_lock held
thread->registers.signal_pending = is_pending;
}
void Thread::DoUpdatePendingSignal()
{
ScopedLock lock(&process->signal_lock);
UpdatePendingSignals(this);
}
int sys_sigaction(int signum,
const struct sigaction* user_newact,
struct sigaction* user_oldact)

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -92,6 +92,7 @@ Thread::Thread()
kernelstacksize = 0;
kernelstackmalloced = false;
pledged_destruction = false;
force_no_signals = false;
sigemptyset(&signal_pending);
sigemptyset(&signal_mask);
memset(&signal_stack, 0, sizeof(signal_stack));