MySQL 9.1.0
Source Code Documentation
|
Circular buffer that can be used to asynchronously feed a sink. More...
#include <gcs_logging_system.h>
Public Member Functions | |
Gcs_async_buffer (Sink_interface *sink, const int buffer_size=DEFAULT_ASYNC_BUFFERS) | |
~Gcs_async_buffer () | |
enum_gcs_error | initialize () |
Asynchronous circular buffer initialization method. More... | |
enum_gcs_error | finalize () |
Asynchronous circular buffer finalization method. More... | |
const std::string | get_information () const |
The purpose of this method is to return information on the associated sink such as its location. More... | |
void | consume_events () |
Consumer thread invokes this method to process log events until it is terminated. More... | |
void | produce_events (const char *message, size_t message_size) |
Producer threads invoke this method to log events (i.e. More... | |
void | produce_events (const std::string &message) |
Producer threads invoke this method to log events (i.e. More... | |
Gcs_log_event & | get_entry () |
Get a reference to an in-memory buffer where a message content will be written to. More... | |
void | notify_entry (Gcs_log_event &buffer_entry) |
Notify that an in-memory buffer was filled in and is ready to be consumed. More... | |
Sink_interface * | get_sink () const |
Private Member Functions | |
uint64_t | get_index (int64_t index) const |
Get the correct index to an entry according to the buffer size. More... | |
int64_t | get_write_index () |
Get an index entry to an in-memory buffer where a message content will be written to. More... | |
void | sleep_consumer () const |
Make the consumer sleep while there is no entry to be consumed. More... | |
void | wake_up_consumer () const |
Wake up the consumer thread so that it can write whatever was added to the asynchronous buffer to a sink. More... | |
Gcs_async_buffer (Gcs_async_buffer &l) | |
Gcs_async_buffer & | operator= (const Gcs_async_buffer &l) |
Private Attributes | |
std::vector< Gcs_log_event > | m_buffer |
Slots where messages will be copied to before a consumer thread writes them to a sink. More... | |
int | m_buffer_size |
Number of available slots in the buffer. More... | |
int64_t | m_write_index |
Next entry in the buffer where producers will write their messages to. More... | |
int64_t | m_read_index |
Next entry in the buffer that will be read by the consumer. More... | |
int64_t | m_number_entries |
Number of entries written by producers and not yet consumed. More... | |
bool | m_terminated |
Whether the asynchronous circular buffer has been stopped or not. More... | |
bool | m_initialized |
Whether the asynchronous circular buffer has been started or not. More... | |
Sink_interface * | m_sink |
Sink where the consumer will write messages to. More... | |
My_xp_thread * | m_consumer |
Consumer thread that is responsible for reading the entries in the circular buffer. More... | |
My_xp_cond * | m_wait_for_events_cond |
Conditional variable that is used by the producer to notify the consumer that it should wake up. More... | |
My_xp_cond * | m_free_buffer_cond |
Conditional variable that is used by the consumer to notify the producer that there are free slots. More... | |
My_xp_mutex * | m_free_buffer_mutex |
Mutex variable that is used to synchronize access to the circular buffer in particular the m_number_entries, m_write_index and m_terminated shared variables. More... | |
Circular buffer that can be used to asynchronously feed a sink.
In this, messages are temporarily stored in-memory and asynchronously written to the sink. Using this in-memory intermediate buffer is possible to minimize performance drawbacks associated with the direct access to the sink which is usually the terminal, a file or a remote process.
By default, the circular buffer has DEFAULT_ASYNC_BUFFERS entries and this value can be changed by providing different contructor's parameters. Note that, however, this is not currently exposed to the end-user. If there is no free slot available, the caller thread will be temporarily blocked until it can copy its message into a free slot. Only one thread will read the entries in the circular buffer and write them to a sink.
Concurrent access to the buffer is controlled by using a mutex and atomic variables. If you are tempted to change this, please, measure the performance first before changing anything. We have done so and the bulk of the time is spent in formatting the messages and for that reason a simple circular buffer implementation is enough.
Another alternative would be to format the message within the consumer but this would require to always pass information by value. In order to give users flexibility, we have decided not to do this. Besides, XCOM almost always formats its messages within the context of the caller thread. For those reasons, we kept the current behavior but we might revisit this in the future.
|
explicit |
Gcs_async_buffer::~Gcs_async_buffer | ( | ) |
|
private |
void Gcs_async_buffer::consume_events | ( | ) |
Consumer thread invokes this method to process log events until it is terminated.
enum_gcs_error Gcs_async_buffer::finalize | ( | ) |
Asynchronous circular buffer finalization method.
GCS_OK | in case everything goes well. Any other value of gcs_error in case of error. |
Gcs_log_event & Gcs_async_buffer::get_entry | ( | ) |
Get a reference to an in-memory buffer where a message content will be written to.
|
inlineprivate |
Get the correct index to an entry according to the buffer size.
const std::string Gcs_async_buffer::get_information | ( | ) | const |
The purpose of this method is to return information on the associated sink such as its location.
In this particular case, it will return the string "asynchronous" along with the information returned by then sink in use.
Calling this method would return "asynchronous::output" if the sink in use was the standard output.
Sink_interface * Gcs_async_buffer::get_sink | ( | ) | const |
|
private |
Get an index entry to an in-memory buffer where a message content will be written to.
enum_gcs_error Gcs_async_buffer::initialize | ( | ) |
Asynchronous circular buffer initialization method.
GCS_OK | in case everything goes well. Any other value of gcs_error in case of error. |
void Gcs_async_buffer::notify_entry | ( | Gcs_log_event & | buffer_entry | ) |
Notify that an in-memory buffer was filled in and is ready to be consumed.
|
private |
|
inline |
Producer threads invoke this method to log events (i.e.
messages).
This method is only provided for the sake of completeness and is currently not used because the message would have to be copied into the circular buffer and usually it is necessary to compose the message first thus incurring an extra copy.
Currently, a producer calls directly the get_entry() and notify_entry() methods directly.
|
inline |
Producer threads invoke this method to log events (i.e.
messages).
This method is only provided for the sake of completeness and is currently not used because the message would have to be copied into the circular buffer and usually it is necessary to compose the message first thus incurring an extra copy.
Currently, a producer calls directly the get_entry() and notify_entry() methods directly
|
inlineprivate |
Make the consumer sleep while there is no entry to be consumed.
|
inlineprivate |
Wake up the consumer thread so that it can write whatever was added to the asynchronous buffer to a sink.
|
private |
Slots where messages will be copied to before a consumer thread writes them to a sink.
|
private |
Number of available slots in the buffer.
|
private |
Consumer thread that is responsible for reading the entries in the circular buffer.
|
private |
Conditional variable that is used by the consumer to notify the producer that there are free slots.
|
private |
Mutex variable that is used to synchronize access to the circular buffer in particular the m_number_entries, m_write_index and m_terminated shared variables.
|
private |
Whether the asynchronous circular buffer has been started or not.
|
private |
Number of entries written by producers and not yet consumed.
|
private |
Next entry in the buffer that will be read by the consumer.
|
private |
Sink where the consumer will write messages to.
|
private |
Whether the asynchronous circular buffer has been stopped or not.
|
private |
Conditional variable that is used by the producer to notify the consumer that it should wake up.
|
private |
Next entry in the buffer where producers will write their messages to.