thr_sigwait.c revision 127102
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. 1422315Sjulian * 3. All advertising materials mentioning features or use of this software 1522315Sjulian * must display the following acknowledgement: 1622315Sjulian * This product includes software developed by John Birrell. 1722315Sjulian * 4. Neither the name of the author nor the names of any co-contributors 1822315Sjulian * may be used to endorse or promote products derived from this software 1922315Sjulian * without specific prior written permission. 2022315Sjulian * 2122315Sjulian * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 2222315Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2322315Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2449439Sdeischen * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2522315Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2622315Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2722315Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2822315Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2922315Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3022315Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3122315Sjulian * SUCH DAMAGE. 3222315Sjulian * 3350476Speter * $FreeBSD: head/lib/libkse/thread/thr_sigwait.c 127102 2004-03-17 02:12:19Z davidxu $ 3422315Sjulian */ 3522315Sjulian#include <signal.h> 3651816Smarcel#include <sys/param.h> 3751816Smarcel#include <sys/signalvar.h> 3822315Sjulian#include <errno.h> 3922315Sjulian#include <pthread.h> 40103388Smini#include "thr_private.h" 4122315Sjulian 42116977Sdavidxu__weak_reference(__sigwait, sigwait); 43116977Sdavidxu__weak_reference(__sigtimedwait, sigtimedwait); 44116977Sdavidxu__weak_reference(__sigwaitinfo, sigwaitinfo); 4571581Sdeischen 46116977Sdavidxustatic int 47116977Sdavidxulib_sigtimedwait(const sigset_t *set, siginfo_t *info, 48116977Sdavidxu const struct timespec * timeout) 4922315Sjulian{ 50113658Sdeischen struct pthread *curthread = _get_curthread(); 51113658Sdeischen int ret = 0; 52113658Sdeischen int i; 53118075Sdavidxu struct sigwait_data waitdata; 54117706Sdavidxu sigset_t waitset; 55114254Sdeischen kse_critical_t crit; 56116977Sdavidxu siginfo_t siginfo; 57114254Sdeischen 58119063Sdavidxu if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 59116977Sdavidxu if (info == NULL) 60116977Sdavidxu info = &siginfo; 61117706Sdavidxu return (__sys_sigtimedwait((sigset_t *)set, info, 62117706Sdavidxu (struct timespec *)timeout)); 63116977Sdavidxu } 6422315Sjulian 6538539Sjb /* 66113658Sdeischen * Initialize the set of signals that will be waited on: 67113658Sdeischen */ 68113658Sdeischen waitset = *set; 69113658Sdeischen 70113658Sdeischen /* These signals can't be waited on. */ 71116977Sdavidxu SIGDELSET(waitset, SIGKILL); 72116977Sdavidxu SIGDELSET(waitset, SIGSTOP); 73113658Sdeischen 74113658Sdeischen /* 75117706Sdavidxu * POSIX says that the _application_ must explicitly install 76117706Sdavidxu * a dummy handler for signals that are SIG_IGN in order 77117706Sdavidxu * to sigwait on them. Note that SIG_IGN signals are left in 78117706Sdavidxu * the mask because a subsequent sigaction could enable an 79113658Sdeischen * ignored signal. 80113658Sdeischen */ 81117706Sdavidxu 82117706Sdavidxu crit = _kse_critical_enter(); 83117706Sdavidxu KSE_SCHED_LOCK(curthread->kse, curthread->kseg); 84117706Sdavidxu for (i = 1; i <= _SIG_MAXSIG; ++i) { 85116977Sdavidxu if (SIGISMEMBER(waitset, i) && 86117706Sdavidxu SIGISMEMBER(curthread->sigpend, i)) { 87117706Sdavidxu SIGDELSET(curthread->sigpend, i); 88117706Sdavidxu siginfo = curthread->siginfo[i - 1]; 89117706Sdavidxu KSE_SCHED_UNLOCK(curthread->kse, 90117706Sdavidxu curthread->kseg); 91117706Sdavidxu _kse_critical_leave(crit); 92117706Sdavidxu ret = i; 93117706Sdavidxu goto OUT; 94113658Sdeischen } 95113658Sdeischen } 96117706Sdavidxu curthread->timeout = 0; 97117706Sdavidxu curthread->interrupted = 0; 98117706Sdavidxu _thr_set_timeout(timeout); 99117706Sdavidxu /* Wait for a signal: */ 100117706Sdavidxu siginfo.si_signo = 0; 101118075Sdavidxu waitdata.waitset = &waitset; 102118075Sdavidxu waitdata.siginfo = &siginfo; 103118075Sdavidxu curthread->data.sigwait = &waitdata; 104117706Sdavidxu THR_SET_STATE(curthread, PS_SIGWAIT); 105117706Sdavidxu _thr_sched_switch_unlocked(curthread); 106117706Sdavidxu /* 107117706Sdavidxu * Return the signal number to the caller: 108117706Sdavidxu */ 109117706Sdavidxu if (siginfo.si_signo > 0) { 110117706Sdavidxu ret = siginfo.si_signo; 111117706Sdavidxu } else { 112117706Sdavidxu if (curthread->interrupted) 113117706Sdavidxu errno = EINTR; 114117706Sdavidxu else if (curthread->timeout) 115117706Sdavidxu errno = EAGAIN; 116117706Sdavidxu ret = -1; 117113658Sdeischen } 118117706Sdavidxu curthread->timeout = 0; 119117706Sdavidxu curthread->interrupted = 0; 120117706Sdavidxu /* 121117706Sdavidxu * Probably unnecessary, but since it's in a union struct 122117706Sdavidxu * we don't know how it could be used in the future. 123117706Sdavidxu */ 124118075Sdavidxu curthread->data.sigwait = NULL; 125113658Sdeischen 126117216SdavidxuOUT: 127117216Sdavidxu if (ret > 0 && info != NULL) 128117216Sdavidxu *info = siginfo; 129117216Sdavidxu 130116977Sdavidxu return (ret); 131116977Sdavidxu} 132116977Sdavidxu 133116977Sdavidxuint 134116977Sdavidxu__sigtimedwait(const sigset_t *set, siginfo_t *info, 135116977Sdavidxu const struct timespec * timeout) 136116977Sdavidxu{ 137116977Sdavidxu struct pthread *curthread = _get_curthread(); 138116977Sdavidxu int ret; 139116977Sdavidxu 140123312Sdavidxu _thr_cancel_enter(curthread); 141116977Sdavidxu ret = lib_sigtimedwait(set, info, timeout); 142123312Sdavidxu _thr_cancel_leave(curthread, 1); 143116977Sdavidxu return (ret); 144116977Sdavidxu} 145113658Sdeischen 146116977Sdavidxuint _sigtimedwait(const sigset_t *set, siginfo_t *info, 147116977Sdavidxu const struct timespec * timeout) 148116977Sdavidxu{ 149116977Sdavidxu return lib_sigtimedwait(set, info, timeout); 150116977Sdavidxu} 151116977Sdavidxu 152116977Sdavidxuint 153116977Sdavidxu__sigwaitinfo(const sigset_t *set, siginfo_t *info) 154116977Sdavidxu{ 155116977Sdavidxu struct pthread *curthread = _get_curthread(); 156116977Sdavidxu int ret; 157116977Sdavidxu 158123312Sdavidxu _thr_cancel_enter(curthread); 159116977Sdavidxu ret = lib_sigtimedwait(set, info, NULL); 160123312Sdavidxu _thr_cancel_leave(curthread, 1); 161113658Sdeischen return (ret); 16222315Sjulian} 163116977Sdavidxu 164116977Sdavidxuint 165116977Sdavidxu_sigwaitinfo(const sigset_t *set, siginfo_t *info) 166116977Sdavidxu{ 167116977Sdavidxu return lib_sigtimedwait(set, info, NULL); 168116977Sdavidxu} 169116977Sdavidxu 170116977Sdavidxuint 171116977Sdavidxu__sigwait(const sigset_t *set, int *sig) 172116977Sdavidxu{ 173116977Sdavidxu struct pthread *curthread = _get_curthread(); 174116977Sdavidxu int ret; 175116977Sdavidxu 176123312Sdavidxu _thr_cancel_enter(curthread); 177116977Sdavidxu ret = lib_sigtimedwait(set, NULL, NULL); 178116977Sdavidxu if (ret > 0) { 179116977Sdavidxu *sig = ret; 180116977Sdavidxu ret = 0; 181127102Sdavidxu } else { 182127102Sdavidxu ret = errno; 183116977Sdavidxu } 184123312Sdavidxu _thr_cancel_leave(curthread, 1); 185116977Sdavidxu return (ret); 186116977Sdavidxu} 187116977Sdavidxu 188116977Sdavidxuint 189116977Sdavidxu_sigwait(const sigset_t *set, int *sig) 190116977Sdavidxu{ 191116977Sdavidxu int ret; 192116977Sdavidxu 193116977Sdavidxu ret = lib_sigtimedwait(set, NULL, NULL); 194116977Sdavidxu if (ret > 0) { 195116977Sdavidxu *sig = ret; 196116977Sdavidxu ret = 0; 197116977Sdavidxu } else { 198127102Sdavidxu ret = errno; 199116977Sdavidxu } 200116977Sdavidxu return (ret); 201116977Sdavidxu} 202116977Sdavidxu 203