Rocket.Chat.ReactNative/ios/Pods/Flipper-Folly/folly/io/async/AsyncSignalHandler.h

122 lines
3.8 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed 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.
*/
#pragma once
#include <folly/io/async/EventBase.h>
#include <folly/portability/Event.h>
#include <map>
namespace folly {
/**
* A handler to receive notification about POSIX signals.
*
* AsyncSignalHandler allows code to process signals from within a EventBase
* loop.
*
* Standard signal handlers interrupt execution of the main thread, and
* are run while the main thread is paused. As a result, great care must be
* taken to avoid race conditions if the signal handler has to access or modify
* any data used by the main thread.
*
* AsyncSignalHandler solves this problem by running the AsyncSignalHandler
* callback in normal thread of execution, as a EventBase callback.
*
* AsyncSignalHandler may only be used in a single thread. It will only
* process signals received by the thread where the AsyncSignalHandler is
* registered. It is the user's responsibility to ensure that signals are
* delivered to the desired thread in multi-threaded programs.
*/
class AsyncSignalHandler {
public:
/**
* Create a new AsyncSignalHandler.
*/
explicit AsyncSignalHandler(EventBase* eventBase);
virtual ~AsyncSignalHandler();
/**
* Attach this AsyncSignalHandler to an EventBase.
*
* This should only be called if the AsyncSignalHandler is not currently
* registered for any signals and is not currently attached to an existing
* EventBase.
*/
void attachEventBase(EventBase* eventBase);
/**
* Detach this AsyncSignalHandler from its EventBase.
*
* This should only be called if the AsyncSignalHandler is not currently
* registered for any signals.
*/
void detachEventBase();
/**
* Get the EventBase used by this AsyncSignalHandler.
*/
EventBase* getEventBase() const {
return eventBase_;
}
/**
* Register to receive callbacks about the specified signal.
*
* Once the handler has been registered for a particular signal,
* signalReceived() will be called each time this thread receives this
* signal.
*
* Throws if an error occurs or if this handler is already
* registered for this signal.
*/
void registerSignalHandler(int signum);
/**
* Unregister for callbacks about the specified signal.
*
* Throws if an error occurs, or if this signal was not registered.
*/
void unregisterSignalHandler(int signum);
/**
* signalReceived() will called to indicate that the specified signal has
* been received.
*
* signalReceived() will always be invoked from the EventBase loop (i.e.,
* after the main POSIX signal handler has returned control to the EventBase
* thread).
*/
virtual void signalReceived(int signum) noexcept = 0;
private:
// we cannot copy the EventBaseEvent instances
// so we need to store ptrs to them
// Also some backends store ptrs to the EventBaseEvent instances
using SignalEventMap = std::map<int, std::unique_ptr<EventBaseEvent>>;
// Forbidden copy constructor and assignment operator
AsyncSignalHandler(AsyncSignalHandler const&);
AsyncSignalHandler& operator=(AsyncSignalHandler const&);
static void libeventCallback(libevent_fd_t signum, short events, void* arg);
EventBase* eventBase_{nullptr};
SignalEventMap signalEvents_;
};
} // namespace folly