Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/os/aix/vm/jsig.c
32284 views
/*1* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.2* Copyright 2012, 2013 SAP AG. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425/* CopyrightVersion 1.2 */2627/* This is a special library that should be loaded before libc &28* libthread to interpose the signal handler installation functions:29* sigaction(), signal(), sigset().30* Used for signal-chaining. See RFE 4381843.31*/3233#include <signal.h>34#include <dlfcn.h>35#include <pthread.h>36#include <stdio.h>37#include <stdlib.h>3839#define bool int40#define true 141#define false 04243// Highest so far on AIX 5.2 is SIGSAK (63)44#define MAXSIGNUM 6345#define MASK(sig) ((unsigned int)1 << sig)4647static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */48static unsigned int jvmsigs = 0; /* signals used by jvm */4950/* used to synchronize the installation of signal handlers */51static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;52static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;53static pthread_t tid = 0;5455typedef void (*sa_handler_t)(int);56typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);57// signal_t is already defined on AIX58typedef sa_handler_t (*signal_like_function_t)(int, sa_handler_t);59typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);6061static signal_like_function_t os_signal = 0; /* os's version of signal()/sigset() */62static sigaction_t os_sigaction = 0; /* os's version of sigaction() */6364static bool jvm_signal_installing = false;65static bool jvm_signal_installed = false;6667static void signal_lock() {68pthread_mutex_lock(&mutex);69/* When the jvm is installing its set of signal handlers, threads70* other than the jvm thread should wait */71if (jvm_signal_installing) {72if (tid != pthread_self()) {73pthread_cond_wait(&cond, &mutex);74}75}76}7778static void signal_unlock() {79pthread_mutex_unlock(&mutex);80}8182static sa_handler_t call_os_signal(int sig, sa_handler_t disp,83bool is_sigset) {84if (os_signal == NULL) {85if (!is_sigset) {86// Aix: call functions directly instead of dlsym'ing them87os_signal = signal;88} else {89// Aix: call functions directly instead of dlsym'ing them90os_signal = sigset;91}92if (os_signal == NULL) {93printf("%s\n", dlerror());94exit(0);95}96}97return (*os_signal)(sig, disp);98}99100static void save_signal_handler(int sig, sa_handler_t disp) {101sigset_t set;102sact[sig].sa_handler = disp;103sigemptyset(&set);104sact[sig].sa_mask = set;105sact[sig].sa_flags = 0;106}107108static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {109sa_handler_t oldhandler;110bool sigused;111112signal_lock();113114sigused = (MASK(sig) & jvmsigs) != 0;115if (jvm_signal_installed && sigused) {116/* jvm has installed its signal handler for this signal. */117/* Save the handler. Don't really install it. */118oldhandler = sact[sig].sa_handler;119save_signal_handler(sig, disp);120121signal_unlock();122return oldhandler;123} else if (jvm_signal_installing) {124/* jvm is installing its signal handlers. Install the new125* handlers and save the old ones. jvm uses sigaction().126* Leave the piece here just in case. */127oldhandler = call_os_signal(sig, disp, is_sigset);128save_signal_handler(sig, oldhandler);129130/* Record the signals used by jvm */131jvmsigs |= MASK(sig);132133signal_unlock();134return oldhandler;135} else {136/* jvm has no relation with this signal (yet). Install the137* the handler. */138oldhandler = call_os_signal(sig, disp, is_sigset);139140signal_unlock();141return oldhandler;142}143}144145sa_handler_t signal(int sig, sa_handler_t disp) {146return set_signal(sig, disp, false);147}148149sa_handler_t sigset(int sig, sa_handler_t disp) {150return set_signal(sig, disp, true);151}152153static int call_os_sigaction(int sig, const struct sigaction *act,154struct sigaction *oact) {155if (os_sigaction == NULL) {156// Aix: call functions directly instead of dlsym'ing them157os_sigaction = sigaction;158if (os_sigaction == NULL) {159printf("%s\n", dlerror());160exit(0);161}162}163return (*os_sigaction)(sig, act, oact);164}165166int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {167int res;168bool sigused;169struct sigaction oldAct;170171signal_lock();172173sigused = (MASK(sig) & jvmsigs) != 0;174if (jvm_signal_installed && sigused) {175/* jvm has installed its signal handler for this signal. */176/* Save the handler. Don't really install it. */177if (oact != NULL) {178*oact = sact[sig];179}180if (act != NULL) {181sact[sig] = *act;182}183184signal_unlock();185return 0;186} else if (jvm_signal_installing) {187/* jvm is installing its signal handlers. Install the new188* handlers and save the old ones. */189res = call_os_sigaction(sig, act, &oldAct);190sact[sig] = oldAct;191if (oact != NULL) {192*oact = oldAct;193}194195/* Record the signals used by jvm */196jvmsigs |= MASK(sig);197198signal_unlock();199return res;200} else {201/* jvm has no relation with this signal (yet). Install the202* the handler. */203res = call_os_sigaction(sig, act, oact);204205signal_unlock();206return res;207}208}209210/* The three functions for the jvm to call into */211void JVM_begin_signal_setting() {212signal_lock();213jvm_signal_installing = true;214tid = pthread_self();215signal_unlock();216}217218void JVM_end_signal_setting() {219signal_lock();220jvm_signal_installed = true;221jvm_signal_installing = false;222pthread_cond_broadcast(&cond);223signal_unlock();224}225226struct sigaction *JVM_get_signal_action(int sig) {227/* Does race condition make sense here? */228if ((MASK(sig) & jvmsigs) != 0) {229return &sact[sig];230}231return NULL;232}233234235