2018-10-09 12:05:08 +03:00
/* -------------------------------------------------------------------------- */
2023-01-09 14:23:19 +03:00
/* Copyright 2002-2023, OpenNebula Project, OpenNebula Systems */
2018-10-09 12:05:08 +03:00
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
# ifndef REQUEST_MANAGER_CONNECTION_H_
# define REQUEST_MANAGER_CONNECTION_H_
# include "RequestManager.h"
2020-09-10 14:32:52 +03:00
# include <condition_variable>
2018-10-09 12:05:08 +03:00
/**
* The connection manager class synchronizes the connection and manager threads
*/
class ConnectionManager
{
public :
2020-09-10 14:32:52 +03:00
ConnectionManager ( int mc )
: connections ( 0 )
, max_connections ( mc )
, end ( false )
2018-10-09 12:05:08 +03:00
{
2020-09-10 14:32:52 +03:00
}
2018-10-09 12:05:08 +03:00
2020-09-10 14:32:52 +03:00
~ ConnectionManager ( ) = default ;
2018-10-09 12:05:08 +03:00
/**
* Increments number of active connections
*/
int add ( )
{
2020-09-10 14:32:52 +03:00
std : : lock_guard < std : : mutex > lock ( _mutex ) ;
2019-04-15 18:10:07 +03:00
2020-09-10 14:32:52 +03:00
return + + connections ;
}
2018-10-09 12:05:08 +03:00
/**
* Decrements number of active connections and signals management thread
*/
void del ( )
{
2020-09-10 14:32:52 +03:00
std : : lock_guard < std : : mutex > lock ( _mutex ) ;
2019-04-15 18:10:07 +03:00
2018-10-09 12:05:08 +03:00
- - connections ;
2020-09-10 14:32:52 +03:00
cond . notify_one ( ) ;
}
2018-10-09 12:05:08 +03:00
/**
* Waits for active connections to be under the max_connection threshold
*/
void wait ( )
{
2020-09-10 14:32:52 +03:00
std : : unique_lock < std : : mutex > lock ( _mutex ) ;
2018-10-09 12:05:08 +03:00
2020-09-10 14:32:52 +03:00
if ( end )
2018-10-09 12:05:08 +03:00
{
2020-09-10 14:32:52 +03:00
return ;
2018-10-09 12:05:08 +03:00
}
2020-09-10 14:32:52 +03:00
cond . wait ( lock , [ & ] {
return ( connections < max_connections ) | | end ; } ) ;
}
/**
* Interrupts and prevents wait ( ) operations
*/
void terminate ( )
{
std : : lock_guard < std : : mutex > lock ( _mutex ) ;
end = true ;
cond . notify_one ( ) ;
}
2018-10-09 12:05:08 +03:00
private :
/**
* Synchronization for connection threads and listener thread
*/
2020-09-10 14:32:52 +03:00
std : : mutex _mutex ;
std : : condition_variable cond ;
2018-10-09 12:05:08 +03:00
/**
* Number of active connections
*/
int connections ;
/**
* Max number of active connections
*/
int max_connections ;
2020-09-10 14:32:52 +03:00
/**
* Terminate wait
*/
std : : atomic < bool > end ;
2018-10-09 12:05:08 +03:00
} ;
# endif