◆ acquire_manual_backend_worker()
This feature is designed for advanced users who need to run the backend worker on their own thread, providing more flexibility at the cost of complexity and potential pitfalls.
This approach is generally not recommended due to the potential for inefficiency and complexity in managing the backend worker outside the provided mechanisms.
Important notes:
- Do not use this to run the library in a single threaded application. This will lead to inefficiencies. The design of this logging library assumes that the backend worker operates in a separate thread from the frontend threads that issue log statements.
- The thread running the
ManualBackendWorker can log, but it must not use backend-waiting flush paths from that same thread. See ManualBackendWorker for the manual-backend threading contract.
- The
ManualBackendWorker should only be used by a single thread. It is not designed to handle multiple threads calling poll() simultaneously.
- You must call
ManualBackendWorker::shutdown() explicitly from the same thread that called init() before that thread exits. Do not rely on the ManualBackendWorker destructor for shutdown ordering.
- The built-in signal handler is not set up with
ManualBackendWorker. If signal handling is required, you must manually set up the signal handler and block signals from reaching the ManualBackendWorker thread. See the start<FrontendOptions>(BackendOptions, SignalHandlerOptions) implementation for guidance on how to do this.
- The following options are not supported when using
ManualBackendWorker: cpu_affinity, thread_name, sleep_duration, and enable_yield_when_idle.
- Avoid performing very heavy tasks in your custom thread. Significant delays in calling
poll() can lead to the SPSC queues of the frontend threads becoming full. When this happens, the frontend threads may need to allocate additional memory on the hot path.
std::thread backend_worker([]()
{
quill::ManualBackendWorker* manual_backend_worker = quill::Backend::acquire_manual_backend_worker();
quill::BackendOptions backend_options;
manual_backend_worker->init(backend_options);
while (running)
{
manual_backend_worker->poll();
}
manual_backend_worker->shutdown();
});
◆ convert_rdtsc_to_epoch_time()
| static QUILL_NODISCARD uint64_t Backend::convert_rdtsc_to_epoch_time |
( |
uint64_t |
rdtsc_value | ) |
|
|
inlinestatic |
Converts an rdtsc value to epoch time.
This function uses the same clock as the backend and can be called from any frontend thread. It is useful when using a logger with ClockSourceType::Tsc and you want to obtain a timestamp synchronized with the log files generated by the backend.
Alternatively you can use the Clock class from backend/Clock.h
- Parameters
-
| rdtsc_value | The RDTSC value to convert. |
- Returns
- The epoch time corresponding to the RDTSC value.
- Exceptions
-
| QuillError | if the backend TSC configuration is invalid. |
◆ get_thread_id()
| static QUILL_NODISCARD uint32_t Backend::get_thread_id |
( |
| ) |
|
|
inlinestaticnoexcept |
Retrieves the ID of the backend thread.
- Returns
- The ID of the backend thread.
◆ is_running()
| static QUILL_NODISCARD bool Backend::is_running |
( |
| ) |
|
|
inlinestaticnoexcept |
Checks if the backend is currently running.
- Returns
- True if the backend is running, false otherwise.
◆ notify()
| static void Backend::notify |
( |
| ) |
|
|
inlinestaticnoexcept |
Notifies the backend thread to wake up.
It is possible to use a long backend sleep_duration and then notify the backend to wake up from any frontend thread.
- Note
- thread-safe
◆ start() [1/2]
Starts the backend thread.
- Parameters
-
| options | Backend options to configure the backend behavior. |
- Note
- Concurrent calls to start() and stop() from different threads are not supported.
◆ start() [2/2]
template<typename TFrontendOptions >
Starts the backend thread and initialises a signal handler.
- Parameters
-
| backend_options | Backend options to configure the backend behavior. |
| signal_handler_options | SignalHandler options to configure the signal handler behavior. |
- Note
- Enabling the built-in signal handler overrides the listed process signal handlers.
-
Concurrent calls to start() and stop() from different threads are not supported.
-
When using the SignalHandler on Linux/MacOS, ensure that each spawned thread in your application has performed one of the following actions: i) Logged at least once. or ii) Called Frontend::preallocate(). or iii) Blocked signals on that thread to prevent the signal handler from running on it. This requirement is because the built-in signal handler utilizes the frontend queue state to issue log statements and wait for flushing. The queue is constructed on its first use with
new(). Failing to meet any of the above criteria means the queue may be first-constructed inside the signal handler, which is not signal-safe. Preallocating or logging once on those threads avoids that first-use allocation, but the built-in handler should still be treated as a best-effort crash-preservation facility rather than a general async-signal-safe logging API.
-
On Windows, Backend::start() installs structured exception and console control handlers. CRT signal handlers are thread-specific and must be installed explicitly with init_signal_handler<TFrontendOptions>() on each frontend/user thread that needs them, not on the backend worker thread.
◆ stop()
| static QUILL_ATTRIBUTE_COLD void Backend::stop |
( |
| ) |
|
|
inlinestatic |
Stops the backend thread.
- Note
- On POSIX systems, when the built-in signal handler is enabled, this restores the Quill-managed signals to their default dispositions. It does not restore any previously installed user handlers.
-
Concurrent calls to start() and stop() from different threads are not supported.
-
This function must not be called from backend-thread callbacks because it joins the backend worker thread.
-
thread-safe
The documentation for this class was generated from the following file: