aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/compat.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2011-04-27 15:24:19 -0400
committerOleg Nesterov <oleg@redhat.com>2011-04-28 07:01:38 -0400
commitfe0faa005d43bc44c357631d51c273806086caa4 (patch)
tree7977c5ec7c452ed3a0036747b8d8861b742c30b3 /kernel/compat.c
parentbb7efee2ca63b08795ffb3cda96fc89d2e641b79 (diff)
signal: sys_rt_sigtimedwait: simplify the timeout logic
No functional changes, cleanup compat_sys_rt_sigtimedwait() and sys_rt_sigtimedwait(). Calculate the timeout before we take ->siglock, this simplifies and lessens the code. Use timespec_valid() to check the timespec. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com>
Diffstat (limited to 'kernel/compat.c')
-rw-r--r--kernel/compat.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 38b1d2c1cbe8..06cbb0619531 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -893,7 +893,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
893 int sig; 893 int sig;
894 struct timespec t; 894 struct timespec t;
895 siginfo_t info; 895 siginfo_t info;
896 long ret, timeout = 0; 896 long ret, timeout;
897 897
898 if (sigsetsize != sizeof(sigset_t)) 898 if (sigsetsize != sizeof(sigset_t))
899 return -EINVAL; 899 return -EINVAL;
@@ -904,36 +904,30 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
904 sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP)); 904 sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
905 signotset(&s); 905 signotset(&s);
906 906
907 timeout = MAX_SCHEDULE_TIMEOUT;
907 if (uts) { 908 if (uts) {
908 if (get_compat_timespec (&t, uts)) 909 if (get_compat_timespec (&t, uts))
909 return -EFAULT; 910 return -EFAULT;
910 if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 911 if (!timespec_valid(&t))
911 || t.tv_sec < 0)
912 return -EINVAL; 912 return -EINVAL;
913 timeout = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
913 } 914 }
914 915
915 spin_lock_irq(&current->sighand->siglock); 916 spin_lock_irq(&current->sighand->siglock);
916 sig = dequeue_signal(current, &s, &info); 917 sig = dequeue_signal(current, &s, &info);
917 if (!sig) { 918 if (!sig && timeout) {
918 timeout = MAX_SCHEDULE_TIMEOUT; 919 current->real_blocked = current->blocked;
919 if (uts) 920 sigandsets(&current->blocked, &current->blocked, &s);
920 timeout = timespec_to_jiffies(&t) 921 recalc_sigpending();
921 +(t.tv_sec || t.tv_nsec); 922 spin_unlock_irq(&current->sighand->siglock);
922 if (timeout) { 923
923 current->real_blocked = current->blocked; 924 timeout = schedule_timeout_interruptible(timeout);
924 sigandsets(&current->blocked, &current->blocked, &s); 925
925 926 spin_lock_irq(&current->sighand->siglock);
926 recalc_sigpending(); 927 sig = dequeue_signal(current, &s, &info);
927 spin_unlock_irq(&current->sighand->siglock); 928 current->blocked = current->real_blocked;
928 929 siginitset(&current->real_blocked, 0);
929 timeout = schedule_timeout_interruptible(timeout); 930 recalc_sigpending();
930
931 spin_lock_irq(&current->sighand->siglock);
932 sig = dequeue_signal(current, &s, &info);
933 current->blocked = current->real_blocked;
934 siginitset(&current->real_blocked, 0);
935 recalc_sigpending();
936 }
937 } 931 }
938 spin_unlock_irq(&current->sighand->siglock); 932 spin_unlock_irq(&current->sighand->siglock);
939 933
@@ -943,7 +937,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
943 if (copy_siginfo_to_user32(uinfo, &info)) 937 if (copy_siginfo_to_user32(uinfo, &info))
944 ret = -EFAULT; 938 ret = -EFAULT;
945 } 939 }
946 }else { 940 } else {
947 ret = timeout?-EINTR:-EAGAIN; 941 ret = timeout?-EINTR:-EAGAIN;
948 } 942 }
949 return ret; 943 return ret;