Kernel: add Thread::queue_signal()
This commit is contained in:
		
							parent
							
								
									146802fa4c
								
							
						
					
					
						commit
						522aa8e762
					
				|  | @ -40,6 +40,7 @@ namespace Kernel | |||
| 		bool has_signal_to_execute() const; | ||||
| 		void set_signal_done(int signal); | ||||
| 		void handle_next_signal(); | ||||
| 		void queue_signal(int signal); | ||||
| 
 | ||||
| 		void set_return_rsp(uintptr_t& rsp) { m_return_rsp = &rsp; } | ||||
| 		void set_return_rip(uintptr_t& rip) { m_return_rip = &rip; } | ||||
|  | @ -99,10 +100,9 @@ namespace Kernel | |||
| 
 | ||||
| 		BAN::CircularQueue<int, 10>	m_signal_queue; | ||||
| 		uint64_t					m_signal_mask		{ 0 }; | ||||
| 		bool						m_handling_signal	{ false }; | ||||
| 		int							m_handling_signal	{ 0 }; | ||||
| 		static_assert(_SIGMAX < 64); | ||||
| 
 | ||||
| 		friend class Process; | ||||
| 		friend class Scheduler; | ||||
| 	}; | ||||
| 	 | ||||
|  |  | |||
|  | @ -7,7 +7,6 @@ | |||
| #include <kernel/Memory/PageTableScope.h> | ||||
| #include <kernel/Process.h> | ||||
| #include <kernel/Scheduler.h> | ||||
| #include <kernel/Signal.h> | ||||
| #include <LibELF/ELF.h> | ||||
| #include <LibELF/Values.h> | ||||
| 
 | ||||
|  | @ -826,7 +825,7 @@ namespace Kernel | |||
| 			if (process->pid() == pid) | ||||
| 			{ | ||||
| 				if (signal) | ||||
| 					process->m_threads.front()->m_signal_queue.push(signal); | ||||
| 					process->m_threads.front()->queue_signal(signal); | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -841,7 +840,7 @@ namespace Kernel | |||
| 		ASSERT(m_threads.size() == 1); | ||||
| 		CriticalScope _; | ||||
| 		Thread& current = Thread::current(); | ||||
| 		current.m_signal_queue.push(signal); | ||||
| 		current.queue_signal(signal); | ||||
| 		current.handle_next_signal(); | ||||
| 		return 0; | ||||
| 	} | ||||
|  |  | |||
|  | @ -152,14 +152,12 @@ namespace Kernel | |||
| 	void Thread::set_signal_done(int signal) | ||||
| 	{ | ||||
| 		ASSERT(!interrupts_enabled()); | ||||
| 		if (!m_handling_signal) | ||||
| 		if (m_handling_signal == 0) | ||||
| 			derrorln("set_signal_done called while not handling singal"); | ||||
| 		else if (m_signal_queue.empty()) | ||||
| 			derrorln("set_signal_done called and there are no signals in queue"); | ||||
| 		else if (m_signal_queue.front() != signal) | ||||
| 			derrorln("set_signal_done called with wrong signal"); | ||||
| 		if (m_handling_signal != signal) | ||||
| 			derrorln("set_signal_done called with invalid signal"); | ||||
| 		else | ||||
| 			m_signal_queue.pop(); | ||||
| 			m_handling_signal = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	void Thread::handle_next_signal() | ||||
|  | @ -171,6 +169,7 @@ namespace Kernel | |||
| 
 | ||||
| 		int signal = m_signal_queue.front(); | ||||
| 		ASSERT(signal >= _SIGMIN && signal <= _SIGMAX); | ||||
| 		m_signal_queue.pop(); | ||||
| 
 | ||||
| 		uintptr_t& return_rsp = this->return_rsp(); | ||||
| 		uintptr_t& return_rip = this->return_rip(); | ||||
|  | @ -187,7 +186,7 @@ namespace Kernel | |||
| 			// call userspace signal handlers
 | ||||
| 			// FIXME: signal trampoline should take a hash etc
 | ||||
| 			//        to only allow marking signals done from it
 | ||||
| 			m_handling_signal = true; | ||||
| 			m_handling_signal = signal; | ||||
| 			write_to_stack(return_rsp, return_rip); | ||||
| 			write_to_stack(return_rsp, signal); | ||||
| 			write_to_stack(return_rsp, signal_handler); | ||||
|  | @ -228,6 +227,9 @@ namespace Kernel | |||
| 				case SIGPROF: | ||||
| 				case SIGVTALRM: | ||||
| 				{ | ||||
| 					// NOTE: we cannot have schedulers temporary stack when
 | ||||
| 					//       enabling interrupts
 | ||||
| 					asm volatile("movq %0, %%rsp" :: "r"(m_return_rsp)); | ||||
| 					ENABLE_INTERRUPTS(); | ||||
| 					process().exit(128 + signal); | ||||
| 					ASSERT_NOT_REACHED(); | ||||
|  | @ -249,8 +251,19 @@ namespace Kernel | |||
| 					ASSERT_NOT_REACHED(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 		m_signal_queue.pop(); | ||||
| 	void Thread::queue_signal(int signal) | ||||
| 	{ | ||||
| 		ASSERT(!interrupts_enabled()); | ||||
| 		if (m_signal_queue.full()) | ||||
| 		{ | ||||
| 			dwarnln("Signal queue full"); | ||||
| 			return; | ||||
| 		} | ||||
| 		m_signal_queue.push(signal); | ||||
| 		if (this != &Thread::current()) | ||||
| 			Scheduler::get().unblock_thread(tid()); | ||||
| 	} | ||||
| 
 | ||||
| 	void Thread::validate_stack() const | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue