@ -12,17 +12,80 @@
/**
* @ file ProxySQL_Poll . cpp
*
* These functions provide functionality for managing file descriptors ( FDs ) and associated data streams in the ProxySQL_Poll class .
* They handle memory allocation , addition , removal , and searching of FDs within the poll object .
* Additionally , they ensure that memory is managed efficiently by dynamically resizing the internal arrays as needed .
*/
* @ brief Core I / O Multiplexing Engine for ProxySQL ' s Event - Driven Architecture
*
* The ProxySQL_Poll class is the heart of ProxySQL ' s event - driven I / O system , managing file descriptors
* and their associated data streams using the poll ( ) system call . It serves as the central mechanism
* for handling thousands of concurrent connections efficiently .
*
* @ section Architecture Integration
*
* ProxySQL_Poll is integrated throughout the ProxySQL codebase as follows :
*
* - * * Thread Classes * * : Each MySQL_Thread and PgSQL_Thread contains a ProxySQL_Poll instance
* - * * Data Stream Classes * * : MySQL_Data_Stream and PgSQL_Data_Stream maintain pointers to their poll instance
* - * * Main Event Loop * * : Forms the core of the poll ( ) loop in both thread types
*
* @ section Template Specialization
*
* ProxySQL_Poll is templated to work with different data stream types :
* - ProxySQL_Poll < MySQL_Data_Stream > for MySQL protocol connections
* - ProxySQL_Poll < PgSQL_Data_Stream > for PostgreSQL protocol connections
*
* @ section Memory Management
*
* The class implements sophisticated memory management :
* - Initial allocation : MIN_POLL_LEN ( 32 ) FDs
* - Dynamic expansion : Uses l_near_pow_2 ( ) for power - of - 2 sizing
* - Automatic shrinking : When FD count drops below threshold
* - Efficient cleanup : Proper deallocation in destructor
*
* @ section Event Processing Pipeline
*
* ProxySQL_Poll integrates into the event processing pipeline :
* 1. Before Poll : ProcessAllMyDS_BeforePoll ( ) - set up poll events , handle timeouts
* 2. Poll Execution : poll ( ) system call with dynamic timeout
* 3. After Poll : ProcessAllMyDS_AfterPoll ( ) - process events , handle new connections
*
* @ section Key Features
*
* - * * Scalability * * : Efficiently handles thousands of concurrent connections
* - * * Event - Driven * * : Non - blocking I / O for high performance
* - * * Bidirectional Integration * * : Data streams maintain poll array indices
* - * * Memory Efficiency * * : Dynamic resizing optimizes memory usage
* - * * Thread Safety * * : Each thread maintains its own poll instance
*
* @ section Integration with Data Streams
*
* Each data stream maintains critical integration fields :
* - ` mypolls ` : Pointer to parent ProxySQL_Poll instance
* - ` poll_fds_idx ` : Index in poll array for quick lookup
* - ` last_recv / sent ` : Timestamps managed by poll system
*
* This tight integration enables ProxySQL to achieve high performance by minimizing
* lookup overhead and maintaining efficient event - driven processing across all connections .
*
* For usage patterns and examples , see the documentation in :
* - MySQL_Thread . cpp
* - PgSQL_Thread . cpp
* - MySQL_Data_Stream . cpp
* - PgSQL_Data_Stream . cpp
*
* @ see MySQL_Thread
* @ see PgSQL_Thread
* @ see MySQL_Data_Stream
* @ see PgSQL_Data_Stream
*/
/**
* @ brief Shrinks the ProxySQL_Poll object by reallocating memory to fit the current number of elements .
*
*
* This function reduces the size of the ProxySQL_Poll object by reallocating memory to fit the current number of elements .
* It adjusts the size of internal arrays to a size that is a power of two near the current number of elements .
*
* @ note Called automatically when FD count drops below MIN_POLL_DELETE_RATIO threshold
* ( see lib / ProxySQL_Poll . cpp : 166 in remove_index_fast ( ) )
*/
template < class T >
void ProxySQL_Poll < T > : : shrink ( ) {
@ -36,10 +99,13 @@ void ProxySQL_Poll<T>::shrink() {
/**
* @ brief Expands the ProxySQL_Poll object to accommodate additional elements .
*
*
* This function expands the ProxySQL_Poll object to accommodate the specified number of additional elements .
* If the resulting size after expansion exceeds the current size , it reallocates memory to fit the expanded size .
*
*
* @ note Called automatically in add ( ) method when current capacity is exhausted
* ( see lib / ProxySQL_Poll . cpp : 114 in add ( ) )
*
* @ param more The number of additional elements to accommodate .
*/
template < class T >
@ -98,15 +164,27 @@ ProxySQL_Poll<T>::~ProxySQL_Poll() {
}
/**
* @ brief Adds a new file descriptor ( FD ) and its associated MySQL_Data_S tream to the ProxySQL_Poll object .
*
* This function adds a new file descriptor ( FD ) along with its associated MySQL_Data_S tream and relevant metadata
* @ brief Adds a new file descriptor ( FD ) and its associated data s tream to the ProxySQL_Poll object .
*
* This function adds a new file descriptor ( FD ) along with its associated data s tream and relevant metadata
* to the ProxySQL_Poll object . It automatically expands the internal arrays if needed .
*
* @ param _events The events to monitor for the FD .
* @ param _fd The file descriptor ( FD ) to add .
* @ param _myds The MySQL_Data_Stream associated with the FD .
* @ param sent_time The time when data was last sent on the FD .
*
* @ section Integration
* - Sets up bidirectional relationship : data stream - > poll instance via myds [ i ] - > mypolls = this
* - Sets up index tracking : data stream - > poll array index via myds [ i ] - > poll_fds_idx = i
* - Initializes timestamps for connection timeout management
*
* @ section Usage Patterns
* Called during :
* - New client connections ( MySQL_Thread . cpp : 4518 )
* - New server connections ( MySQL_Thread . cpp : 3600 )
* - Listener socket registration ( MySQL_Thread . cpp : 3015 )
* - PostgreSQL session establishment ( PgSQL_Session . cpp : 1094 )
*
* @ param _events The events to monitor for the FD ( POLLIN , POLLOUT , POLLIN | POLLOUT )
* @ param _fd The file descriptor ( FD ) to add
* @ param _myds The data stream object associated with the FD
* @ param sent_time The timestamp when data was last sent on the FD
*/
template < class T >
void ProxySQL_Poll < T > : : add ( uint32_t _events , int _fd , T * _myds , unsigned long long sent_time ) {
@ -142,12 +220,24 @@ void ProxySQL_Poll<T>::update_fd_at_index(unsigned int idx, int _fd) {
}
/**
* @ brief Removes a file descriptor ( FD ) and its associated MySQL_Data_Stream from the ProxySQL_Poll object .
*
* This function removes a file descriptor ( FD ) along with its associated MySQL_Data_Stream from the ProxySQL_Poll object .
* It also adjusts internal arrays and may shrink the ProxySQL_Poll object if necessary .
*
* @ param i The index of the file descriptor ( FD ) to remove .
* @ brief Removes a file descriptor ( FD ) and its associated data stream from the ProxySQL_Poll object .
*
* This function removes a file descriptor ( FD ) along with its associated data stream from the ProxySQL_Poll object .
* It uses a swap - and - pop technique for efficient removal and may shrink the object if necessary .
*
* @ section Removal Algorithm
* 1. Sets data stream ' s poll_fds_idx to - 1 to prevent double - free
* 2. If not last element , swaps with last element ( O ( 1 ) removal )
* 3. Updates swapped element ' s poll_fds_idx to new position
* 4. Decrement length and potentially shrink arrays
*
* @ section Usage Patterns
* Called during :
* - Data stream destruction ( MySQL_Data_Stream . cpp : 337 , PgSQL_Data_Stream . cpp : 1114 )
* - Thread cleanup operations ( MySQL_Thread . cpp : 3451 )
* - Connection termination and cleanup
*
* @ param i The index of the file descriptor ( FD ) to remove
*/
template < class T >
void ProxySQL_Poll < T > : : remove_index_fast ( unsigned int i ) {
@ -170,12 +260,23 @@ void ProxySQL_Poll<T>::remove_index_fast(unsigned int i) {
/**
* @ brief Finds the index of a file descriptor ( FD ) in the ProxySQL_Poll object .
*
* This function searches for a file descriptor ( FD ) in the ProxySQL_Poll object and returns its index if found .
*
* This function performs a linear search for a file descriptor ( FD ) in the ProxySQL_Poll object and returns its index if found .
* If the FD is not found , it returns - 1.
*
* @ param fd The file descriptor ( FD ) to search for .
* @ return The index of the file descriptor ( FD ) if found , otherwise - 1.
*
* @ section Performance Notes
* - O ( n ) complexity where n is number of FDs in poll set
* - Used for lookup operations where FD is known but poll index is needed
* - Data streams maintain their own poll_fds_idx for O ( 1 ) access in most cases
*
* @ section Usage Patterns
* Called during :
* - Listener socket operations ( MySQL_Thread . cpp : 3019 )
* - Connection management and lookup ( PgSQL_Thread . cpp : 2789 )
* - Debugging and diagnostic operations
*
* @ param fd The file descriptor ( FD ) to search for
* @ return The index of the file descriptor ( FD ) if found , otherwise - 1
*/
template < class T >
int ProxySQL_Poll < T > : : find_index ( int fd ) {