thr_sigwait.c revision 165967
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: head/lib/libkse/thread/thr_sigwait.c 165967 2007-01-12 07:26:21Z imp $ 3122315Sjulian */ 3222315Sjulian#include <signal.h> 3351816Smarcel#include <sys/param.h> 3451816Smarcel#include <sys/signalvar.h> 3522315Sjulian#include <errno.h> 3622315Sjulian#include <pthread.h> 37103388Smini#include "thr_private.h" 3822315Sjulian 39156611SdeischenLT10_COMPAT_PRIVATE(__sigwait); 40156611SdeischenLT10_COMPAT_PRIVATE(_sigwait); 41156611SdeischenLT10_COMPAT_DEFAULT(sigwait); 42156611SdeischenLT10_COMPAT_PRIVATE(__sigtimedwait); 43156611SdeischenLT10_COMPAT_PRIVATE(_sigtimedwait); 44156611SdeischenLT10_COMPAT_DEFAULT(sigtimedwait); 45156611SdeischenLT10_COMPAT_PRIVATE(__sigwaitinfo); 46156611SdeischenLT10_COMPAT_PRIVATE(_sigwaitinfo); 47156611SdeischenLT10_COMPAT_DEFAULT(sigwaitinfo); 48156611Sdeischen 49116977Sdavidxu__weak_reference(__sigwait, sigwait); 50116977Sdavidxu__weak_reference(__sigtimedwait, sigtimedwait); 51116977Sdavidxu__weak_reference(__sigwaitinfo, sigwaitinfo); 5271581Sdeischen 53116977Sdavidxustatic int 54116977Sdavidxulib_sigtimedwait(const sigset_t *set, siginfo_t *info, 55116977Sdavidxu const struct timespec * timeout) 5622315Sjulian{ 57113658Sdeischen struct pthread *curthread = _get_curthread(); 58113658Sdeischen int ret = 0; 59113658Sdeischen int i; 60118075Sdavidxu struct sigwait_data waitdata; 61117706Sdavidxu sigset_t waitset; 62114254Sdeischen kse_critical_t crit; 63116977Sdavidxu siginfo_t siginfo; 64114254Sdeischen 65119063Sdavidxu if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 66116977Sdavidxu if (info == NULL) 67116977Sdavidxu info = &siginfo; 68117706Sdavidxu return (__sys_sigtimedwait((sigset_t *)set, info, 69117706Sdavidxu (struct timespec *)timeout)); 70116977Sdavidxu } 7122315Sjulian 7238539Sjb /* 73113658Sdeischen * Initialize the set of signals that will be waited on: 74113658Sdeischen */ 75113658Sdeischen waitset = *set; 76113658Sdeischen 77113658Sdeischen /* These signals can't be waited on. */ 78116977Sdavidxu SIGDELSET(waitset, SIGKILL); 79116977Sdavidxu SIGDELSET(waitset, SIGSTOP); 80113658Sdeischen 81113658Sdeischen /* 82117706Sdavidxu * POSIX says that the _application_ must explicitly install 83117706Sdavidxu * a dummy handler for signals that are SIG_IGN in order 84117706Sdavidxu * to sigwait on them. Note that SIG_IGN signals are left in 85117706Sdavidxu * the mask because a subsequent sigaction could enable an 86113658Sdeischen * ignored signal. 87113658Sdeischen */ 88117706Sdavidxu 89117706Sdavidxu crit = _kse_critical_enter(); 90117706Sdavidxu KSE_SCHED_LOCK(curthread->kse, curthread->kseg); 91117706Sdavidxu for (i = 1; i <= _SIG_MAXSIG; ++i) { 92116977Sdavidxu if (SIGISMEMBER(waitset, i) && 93117706Sdavidxu SIGISMEMBER(curthread->sigpend, i)) { 94117706Sdavidxu SIGDELSET(curthread->sigpend, i); 95117706Sdavidxu siginfo = curthread->siginfo[i - 1]; 96117706Sdavidxu KSE_SCHED_UNLOCK(curthread->kse, 97117706Sdavidxu curthread->kseg); 98117706Sdavidxu _kse_critical_leave(crit); 99117706Sdavidxu ret = i; 100117706Sdavidxu goto OUT; 101113658Sdeischen } 102113658Sdeischen } 103117706Sdavidxu curthread->timeout = 0; 104117706Sdavidxu curthread->interrupted = 0; 105117706Sdavidxu _thr_set_timeout(timeout); 106117706Sdavidxu /* Wait for a signal: */ 107117706Sdavidxu siginfo.si_signo = 0; 108118075Sdavidxu waitdata.waitset = &waitset; 109118075Sdavidxu waitdata.siginfo = &siginfo; 110118075Sdavidxu curthread->data.sigwait = &waitdata; 111117706Sdavidxu THR_SET_STATE(curthread, PS_SIGWAIT); 112117706Sdavidxu _thr_sched_switch_unlocked(curthread); 113117706Sdavidxu /* 114117706Sdavidxu * Return the signal number to the caller: 115117706Sdavidxu */ 116117706Sdavidxu if (siginfo.si_signo > 0) { 117117706Sdavidxu ret = siginfo.si_signo; 118117706Sdavidxu } else { 119117706Sdavidxu if (curthread->interrupted) 120117706Sdavidxu errno = EINTR; 121117706Sdavidxu else if (curthread->timeout) 122117706Sdavidxu errno = EAGAIN; 123117706Sdavidxu ret = -1; 124113658Sdeischen } 125117706Sdavidxu curthread->timeout = 0; 126117706Sdavidxu curthread->interrupted = 0; 127117706Sdavidxu /* 128117706Sdavidxu * Probably unnecessary, but since it's in a union struct 129117706Sdavidxu * we don't know how it could be used in the future. 130117706Sdavidxu */ 131118075Sdavidxu curthread->data.sigwait = NULL; 132113658Sdeischen 133117216SdavidxuOUT: 134117216Sdavidxu if (ret > 0 && info != NULL) 135117216Sdavidxu *info = siginfo; 136117216Sdavidxu 137116977Sdavidxu return (ret); 138116977Sdavidxu} 139116977Sdavidxu 140116977Sdavidxuint 141116977Sdavidxu__sigtimedwait(const sigset_t *set, siginfo_t *info, 142116977Sdavidxu const struct timespec * timeout) 143116977Sdavidxu{ 144116977Sdavidxu struct pthread *curthread = _get_curthread(); 145116977Sdavidxu int ret; 146116977Sdavidxu 147123312Sdavidxu _thr_cancel_enter(curthread); 148116977Sdavidxu ret = lib_sigtimedwait(set, info, timeout); 149123312Sdavidxu _thr_cancel_leave(curthread, 1); 150116977Sdavidxu return (ret); 151116977Sdavidxu} 152113658Sdeischen 153116977Sdavidxuint _sigtimedwait(const sigset_t *set, siginfo_t *info, 154116977Sdavidxu const struct timespec * timeout) 155116977Sdavidxu{ 156116977Sdavidxu return lib_sigtimedwait(set, info, timeout); 157116977Sdavidxu} 158116977Sdavidxu 159116977Sdavidxuint 160116977Sdavidxu__sigwaitinfo(const sigset_t *set, siginfo_t *info) 161116977Sdavidxu{ 162116977Sdavidxu struct pthread *curthread = _get_curthread(); 163116977Sdavidxu int ret; 164116977Sdavidxu 165123312Sdavidxu _thr_cancel_enter(curthread); 166116977Sdavidxu ret = lib_sigtimedwait(set, info, NULL); 167123312Sdavidxu _thr_cancel_leave(curthread, 1); 168113658Sdeischen return (ret); 16922315Sjulian} 170116977Sdavidxu 171116977Sdavidxuint 172116977Sdavidxu_sigwaitinfo(const sigset_t *set, siginfo_t *info) 173116977Sdavidxu{ 174116977Sdavidxu return lib_sigtimedwait(set, info, NULL); 175116977Sdavidxu} 176116977Sdavidxu 177116977Sdavidxuint 178116977Sdavidxu__sigwait(const sigset_t *set, int *sig) 179116977Sdavidxu{ 180116977Sdavidxu struct pthread *curthread = _get_curthread(); 181116977Sdavidxu int ret; 182116977Sdavidxu 183123312Sdavidxu _thr_cancel_enter(curthread); 184116977Sdavidxu ret = lib_sigtimedwait(set, NULL, NULL); 185116977Sdavidxu if (ret > 0) { 186116977Sdavidxu *sig = ret; 187116977Sdavidxu ret = 0; 188127102Sdavidxu } else { 189127102Sdavidxu ret = errno; 190116977Sdavidxu } 191123312Sdavidxu _thr_cancel_leave(curthread, 1); 192116977Sdavidxu return (ret); 193116977Sdavidxu} 194116977Sdavidxu 195116977Sdavidxuint 196116977Sdavidxu_sigwait(const sigset_t *set, int *sig) 197116977Sdavidxu{ 198116977Sdavidxu int ret; 199116977Sdavidxu 200116977Sdavidxu ret = lib_sigtimedwait(set, NULL, NULL); 201116977Sdavidxu if (ret > 0) { 202116977Sdavidxu *sig = ret; 203116977Sdavidxu ret = 0; 204116977Sdavidxu } else { 205127102Sdavidxu ret = errno; 206116977Sdavidxu } 207116977Sdavidxu return (ret); 208116977Sdavidxu} 209116977Sdavidxu 210