From 89df64c56e54842e2194cff74c413d81e5716989 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 11 Apr 2008 03:29:42 +0000 Subject: [PATCH] Added two helper classes for dealing with restarts of ioctl() like syscalls. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24903 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/syscall_restart.h | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/headers/private/kernel/syscall_restart.h b/headers/private/kernel/syscall_restart.h index 1cb0629ba0..4f2eeee1ec 100644 --- a/headers/private/kernel/syscall_restart.h +++ b/headers/private/kernel/syscall_restart.h @@ -113,4 +113,47 @@ syscall_restart_ioctl_handle_post(status_t error) } +struct IoctlSyscallFlagUnsetter { + IoctlSyscallFlagUnsetter() + { + struct thread *thread = thread_get_current_thread(); + fWasSyscall = (atomic_and(&thread->flags, ~THREAD_FLAGS_IOCTL_SYSCALL) + & THREAD_FLAGS_IOCTL_SYSCALL) != 0; + } + + ~IoctlSyscallFlagUnsetter() + { + struct thread *thread = thread_get_current_thread(); + if (fWasSyscall) + atomic_or(&thread->flags, THREAD_FLAGS_IOCTL_SYSCALL); + } + +private: + bool fWasSyscall; +}; + + +template +struct IoctlSyscallRestartWrapper { + IoctlSyscallRestartWrapper(const Type& result) + : fResult(result) + { + struct thread *thread = thread_get_current_thread(); + atomic_or(&thread->flags, THREAD_FLAGS_IOCTL_SYSCALL); + } + + ~IoctlSyscallRestartWrapper() + { + struct thread *thread = thread_get_current_thread(); + atomic_and(&thread->flags, ~THREAD_FLAGS_IOCTL_SYSCALL); + + if (fResult < 0) + syscall_restart_ioctl_handle_post(fResult); + } + +private: + const Type& fResult; +}; + + #endif // _KERNEL_SYSCALL_RESTART_H