prod/native/extension/code/ForkHandler.cpp (48 lines of code) (raw):
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "ForkHandler.h"
#ifndef _WINDOWS
#include <pthread.h>
#include <errno.h>
#include "os/OsUtils.h"
#include "LoggerInterface.h"
#include "ModuleGlobals.h"
#include "PeriodicTaskExecutor.h"
#include "transport/HttpTransportAsync.h"
static void callbackToLogForkBeforeInParent() {
ELOGF_NF_DEBUG(EAPM_GL(logger_), "Before process fork (i.e., in parent context); its parent (i.e., grandparent) PID: %d", static_cast<int>(elasticapm::osutils::getParentProcessId()));
// TODO implement forkable registry
if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->periodicTaskExecutor_) {
ELASTICAPM_G(globals)->periodicTaskExecutor_->prefork();
}
if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->httpTransportAsync_) {
ELASTICAPM_G(globals)->httpTransportAsync_->prefork();
}
}
static void callbackToLogForkAfterInParent() {
ELOGF_NF_DEBUG(EAPM_GL(logger_), "After process fork (in parent context)");
if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->periodicTaskExecutor_) {
ELASTICAPM_G(globals)->periodicTaskExecutor_->postfork(false);
}
if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->httpTransportAsync_) {
ELASTICAPM_G(globals)->httpTransportAsync_->postfork(false);
}
}
static void callbackToLogForkAfterInChild() {
ELOGF_NF_DEBUG(EAPM_GL(logger_), "After process fork (in child context); parent PID: %d", static_cast<int>(elasticapm::osutils::getParentProcessId()));
if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->periodicTaskExecutor_) {
ELASTICAPM_G(globals)->periodicTaskExecutor_->postfork(true);
}
if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->httpTransportAsync_) {
ELASTICAPM_G(globals)->httpTransportAsync_->postfork(true);
}
}
void registerCallbacksToLogFork() {
int retVal = pthread_atfork(callbackToLogForkBeforeInParent, callbackToLogForkAfterInParent, callbackToLogForkAfterInChild);
if (retVal == 0) {
ELOGF_NF_DEBUG(EAPM_GL(logger_), "Registered callbacks to log process fork");
} else {
ELOGF_NF_WARNING(EAPM_GL(logger_), "Failed to register callbacks to log process fork; return value: %d", retVal);
}
}
#else
void registerCallbacksToLogFork() {
}
#endif