1103419Smini//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko) 222315Sjulian/* 322315Sjulian * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>. 422315Sjulian * All rights reserved. 522315Sjulian * 622315Sjulian * Redistribution and use in source and binary forms, with or without 722315Sjulian * modification, are permitted provided that the following conditions 822315Sjulian * are met: 922315Sjulian * 1. Redistributions of source code must retain the above copyright 1022315Sjulian * notice, this list of conditions and the following disclaimer. 1122315Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1222315Sjulian * notice, this list of conditions and the following disclaimer in the 1322315Sjulian * documentation and/or other materials provided with the distribution. 14165967Simp * 3. Neither the name of the author nor the names of any co-contributors 1522315Sjulian * may be used to endorse or promote products derived from this software 1622315Sjulian * without specific prior written permission. 1722315Sjulian * 1822315Sjulian * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 1922315Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2022315Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2149439Sdeischen * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2222315Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2322315Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2422315Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2522315Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2622315Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2722315Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2822315Sjulian * SUCH DAMAGE. 2922315Sjulian * 3050476Speter * $FreeBSD$ 3122315Sjulian */ 32174112Sdeischen 33174112Sdeischen#include "namespace.h" 3422315Sjulian#include <signal.h> 3551816Smarcel#include <sys/param.h> 3651816Smarcel#include <sys/signalvar.h> 3722315Sjulian#include <errno.h> 3822315Sjulian#include <pthread.h> 39174112Sdeischen#include "un-namespace.h" 40103388Smini#include "thr_private.h" 4122315Sjulian 42174112Sdeischenint __sigtimedwait(const sigset_t *set, siginfo_t *info, 43174112Sdeischen const struct timespec *timeout); 44174112Sdeischenint __sigwaitinfo(const sigset_t *set, siginfo_t *info); 45174112Sdeischenint __sigwait(const sigset_t *set, int *sig); 46174112Sdeischenint _sigtimedwait(const sigset_t *set, siginfo_t *info, 47174112Sdeischen const struct timespec *timeout); 48174112Sdeischenint _sigwaitinfo(const sigset_t *set, siginfo_t *info); 49174112Sdeischenint _sigwait(const sigset_t *set, int *sig); 50174112Sdeischen 51116977Sdavidxu__weak_reference(__sigwait, sigwait); 52116977Sdavidxu__weak_reference(__sigtimedwait, sigtimedwait); 53116977Sdavidxu__weak_reference(__sigwaitinfo, sigwaitinfo); 5471581Sdeischen 55116977Sdavidxustatic int 56116977Sdavidxulib_sigtimedwait(const sigset_t *set, siginfo_t *info, 57174112Sdeischen const struct timespec *timeout) 5822315Sjulian{ 59113658Sdeischen struct pthread *curthread = _get_curthread(); 60113658Sdeischen int ret = 0; 61113658Sdeischen int i; 62118075Sdavidxu struct sigwait_data waitdata; 63117706Sdavidxu sigset_t waitset; 64114254Sdeischen kse_critical_t crit; 65116977Sdavidxu siginfo_t siginfo; 66114254Sdeischen 67119063Sdavidxu if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 68116977Sdavidxu if (info == NULL) 69116977Sdavidxu info = &siginfo; 70174112Sdeischen return (__sys_sigtimedwait(set, info, timeout)); 71116977Sdavidxu } 7222315Sjulian 7338539Sjb /* 74113658Sdeischen * Initialize the set of signals that will be waited on: 75113658Sdeischen */ 76113658Sdeischen waitset = *set; 77113658Sdeischen 78113658Sdeischen /* These signals can't be waited on. */ 79116977Sdavidxu SIGDELSET(waitset, SIGKILL); 80116977Sdavidxu SIGDELSET(waitset, SIGSTOP); 81113658Sdeischen 82113658Sdeischen /* 83117706Sdavidxu * POSIX says that the _application_ must explicitly install 84117706Sdavidxu * a dummy handler for signals that are SIG_IGN in order 85117706Sdavidxu * to sigwait on them. Note that SIG_IGN signals are left in 86117706Sdavidxu * the mask because a subsequent sigaction could enable an 87113658Sdeischen * ignored signal. 88113658Sdeischen */ 89117706Sdavidxu 90117706Sdavidxu crit = _kse_critical_enter(); 91117706Sdavidxu KSE_SCHED_LOCK(curthread->kse, curthread->kseg); 92117706Sdavidxu for (i = 1; i <= _SIG_MAXSIG; ++i) { 93116977Sdavidxu if (SIGISMEMBER(waitset, i) && 94117706Sdavidxu SIGISMEMBER(curthread->sigpend, i)) { 95117706Sdavidxu SIGDELSET(curthread->sigpend, i); 96117706Sdavidxu siginfo = curthread->siginfo[i - 1]; 97117706Sdavidxu KSE_SCHED_UNLOCK(curthread->kse, 98117706Sdavidxu curthread->kseg); 99117706Sdavidxu _kse_critical_leave(crit); 100117706Sdavidxu ret = i; 101117706Sdavidxu goto OUT; 102113658Sdeischen } 103113658Sdeischen } 104117706Sdavidxu curthread->timeout = 0; 105117706Sdavidxu curthread->interrupted = 0; 106117706Sdavidxu _thr_set_timeout(timeout); 107117706Sdavidxu /* Wait for a signal: */ 108117706Sdavidxu siginfo.si_signo = 0; 109118075Sdavidxu waitdata.waitset = &waitset; 110118075Sdavidxu waitdata.siginfo = &siginfo; 111118075Sdavidxu curthread->data.sigwait = &waitdata; 112117706Sdavidxu THR_SET_STATE(curthread, PS_SIGWAIT); 113117706Sdavidxu _thr_sched_switch_unlocked(curthread); 114117706Sdavidxu /* 115117706Sdavidxu * Return the signal number to the caller: 116117706Sdavidxu */ 117117706Sdavidxu if (siginfo.si_signo > 0) { 118117706Sdavidxu ret = siginfo.si_signo; 119117706Sdavidxu } else { 120117706Sdavidxu if (curthread->interrupted) 121117706Sdavidxu errno = EINTR; 122117706Sdavidxu else if (curthread->timeout) 123117706Sdavidxu errno = EAGAIN; 124117706Sdavidxu ret = -1; 125113658Sdeischen } 126117706Sdavidxu curthread->timeout = 0; 127117706Sdavidxu curthread->interrupted = 0; 128117706Sdavidxu /* 129117706Sdavidxu * Probably unnecessary, but since it's in a union struct 130117706Sdavidxu * we don't know how it could be used in the future. 131117706Sdavidxu */ 132118075Sdavidxu curthread->data.sigwait = NULL; 133113658Sdeischen 134117216SdavidxuOUT: 135117216Sdavidxu if (ret > 0 && info != NULL) 136117216Sdavidxu *info = siginfo; 137117216Sdavidxu 138116977Sdavidxu return (ret); 139116977Sdavidxu} 140116977Sdavidxu 141116977Sdavidxuint 142116977Sdavidxu__sigtimedwait(const sigset_t *set, siginfo_t *info, 143116977Sdavidxu const struct timespec * timeout) 144116977Sdavidxu{ 145116977Sdavidxu struct pthread *curthread = _get_curthread(); 146116977Sdavidxu int ret; 147116977Sdavidxu 148123312Sdavidxu _thr_cancel_enter(curthread); 149116977Sdavidxu ret = lib_sigtimedwait(set, info, timeout); 150123312Sdavidxu _thr_cancel_leave(curthread, 1); 151116977Sdavidxu return (ret); 152116977Sdavidxu} 153113658Sdeischen 154116977Sdavidxuint _sigtimedwait(const sigset_t *set, siginfo_t *info, 155116977Sdavidxu const struct timespec * timeout) 156116977Sdavidxu{ 157116977Sdavidxu return lib_sigtimedwait(set, info, timeout); 158116977Sdavidxu} 159116977Sdavidxu 160116977Sdavidxuint 161116977Sdavidxu__sigwaitinfo(const sigset_t *set, siginfo_t *info) 162116977Sdavidxu{ 163116977Sdavidxu struct pthread *curthread = _get_curthread(); 164116977Sdavidxu int ret; 165116977Sdavidxu 166123312Sdavidxu _thr_cancel_enter(curthread); 167116977Sdavidxu ret = lib_sigtimedwait(set, info, NULL); 168123312Sdavidxu _thr_cancel_leave(curthread, 1); 169113658Sdeischen return (ret); 17022315Sjulian} 171116977Sdavidxu 172116977Sdavidxuint 173116977Sdavidxu_sigwaitinfo(const sigset_t *set, siginfo_t *info) 174116977Sdavidxu{ 175116977Sdavidxu return lib_sigtimedwait(set, info, NULL); 176116977Sdavidxu} 177116977Sdavidxu 178116977Sdavidxuint 179116977Sdavidxu__sigwait(const sigset_t *set, int *sig) 180116977Sdavidxu{ 181116977Sdavidxu struct pthread *curthread = _get_curthread(); 182116977Sdavidxu int ret; 183116977Sdavidxu 184123312Sdavidxu _thr_cancel_enter(curthread); 185116977Sdavidxu ret = lib_sigtimedwait(set, NULL, NULL); 186116977Sdavidxu if (ret > 0) { 187116977Sdavidxu *sig = ret; 188116977Sdavidxu ret = 0; 189127102Sdavidxu } else { 190127102Sdavidxu ret = errno; 191116977Sdavidxu } 192123312Sdavidxu _thr_cancel_leave(curthread, 1); 193116977Sdavidxu return (ret); 194116977Sdavidxu} 195116977Sdavidxu 196116977Sdavidxuint 197116977Sdavidxu_sigwait(const sigset_t *set, int *sig) 198116977Sdavidxu{ 199116977Sdavidxu int ret; 200116977Sdavidxu 201116977Sdavidxu ret = lib_sigtimedwait(set, NULL, NULL); 202116977Sdavidxu if (ret > 0) { 203116977Sdavidxu *sig = ret; 204116977Sdavidxu ret = 0; 205116977Sdavidxu } else { 206127102Sdavidxu ret = errno; 207116977Sdavidxu } 208116977Sdavidxu return (ret); 209116977Sdavidxu} 210116977Sdavidxu 211