brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · b050b17 Raw
96 lines · cpp
1//===-- Implementation of at-fork callback helpers  -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "fork_callbacks.h"10 11#include "src/__support/CPP/mutex.h" // lock_guard12#include "src/__support/macros/config.h"13#include "src/__support/threads/mutex.h"14 15#include <stddef.h> // For size_t16 17namespace LIBC_NAMESPACE_DECL {18 19namespace {20 21struct ForkCallbackTriple {22  ForkCallback *prepare = nullptr;23  ForkCallback *parent = nullptr;24  ForkCallback *child = nullptr;25  constexpr ForkCallbackTriple() = default;26};27 28class AtForkCallbackManager {29  static constexpr size_t CALLBACK_SIZE = 32;30  // TODO: Replace this with block store when integration tests31  // can use allocators.32  ForkCallbackTriple list[CALLBACK_SIZE];33  Mutex mtx;34  size_t next_index;35 36public:37  constexpr AtForkCallbackManager()38      : mtx(/*timed=*/false, /*recursive=*/false, /*robust=*/false,39            /*pshared=*/false),40        next_index(0) {}41 42  bool register_triple(const ForkCallbackTriple &triple) {43    cpp::lock_guard lock(mtx);44    if (next_index >= CALLBACK_SIZE)45      return false;46    list[next_index] = triple;47    ++next_index;48    return true;49  }50 51  void invoke_prepare() {52    cpp::lock_guard lock(mtx);53    for (size_t i = 0; i < next_index; ++i) {54      auto prepare = list[i].prepare;55      if (prepare)56        prepare();57    }58  }59 60  void invoke_parent() {61    cpp::lock_guard lock(mtx);62    for (size_t i = 0; i < next_index; ++i) {63      auto parent = list[i].parent;64      if (parent)65        parent();66    }67  }68 69  void invoke_child() {70    cpp::lock_guard lock(mtx);71    for (size_t i = 0; i < next_index; ++i) {72      auto child = list[i].child;73      if (child)74        child();75    }76  }77};78 79AtForkCallbackManager cb_manager;80 81} // Anonymous namespace82 83bool register_atfork_callbacks(ForkCallback *prepare_cb,84                               ForkCallback *parent_cb,85                               ForkCallback *child_cb) {86  return cb_manager.register_triple({prepare_cb, parent_cb, child_cb});87}88 89void invoke_child_callbacks() { cb_manager.invoke_child(); }90 91void invoke_prepare_callbacks() { cb_manager.invoke_prepare(); }92 93void invoke_parent_callbacks() { cb_manager.invoke_parent(); }94 95} // namespace LIBC_NAMESPACE_DECL96