16 #ifndef QGSCONNECTIONPOOL_H
17 #define QGSCONNECTIONPOOL_H
25 #include <QCoreApplication>
33 #include <QElapsedTimer>
35 #define CONN_POOL_EXPIRATION_TIME 60 // in seconds
36 #define CONN_POOL_SPARE_CONNECTIONS 2 // number of spare connections in case all the base connections are used but we have a nested request with the risk of a deadlock
81 for (
const Item &item : std::as_const(
conns ) )
83 qgsConnectionPool_ConnectionDestroy( item.c );
99 T
acquire(
int timeout,
bool requestMayBeNested )
101 const int requiredFreeConnectionCount = requestMayBeNested ? 1 : 3;
105 if ( !
sem.tryAcquire( requiredFreeConnectionCount, timeout ) )
114 sem.acquire( requiredFreeConnectionCount );
116 sem.release( requiredFreeConnectionCount - 1 );
122 if ( !
conns.isEmpty() )
125 if ( !qgsConnectionPool_ConnectionIsValid( i.
c ) )
127 qgsConnectionPool_ConnectionDestroy( i.
c );
128 qgsConnectionPool_ConnectionCreate(
connInfo, i.
c );
133 if (
conns.isEmpty() )
136 QMetaObject::invokeMethod(
expirationTimer->parent(),
"stopExpirationTimer" );
146 qgsConnectionPool_ConnectionCreate(
connInfo,
c );
164 if ( !qgsConnectionPool_ConnectionIsValid( conn ) )
166 qgsConnectionPool_ConnectionDestroy( conn );
178 QMetaObject::invokeMethod(
expirationTimer->parent(),
"startExpirationTimer" );
190 for (
const Item &i : std::as_const(
conns ) )
192 qgsConnectionPool_ConnectionDestroy( i.c );
196 qgsConnectionPool_InvalidateConnection(
c );
206 QObject::connect(
expirationTimer, SIGNAL( timeout() ), parent, SLOT( handleConnectionExpired() ) );
210 parent->moveToThread( qApp->thread() );
217 QTime now = QTime::currentTime();
221 for (
int i = 0; i <
conns.count(); ++i )
224 toDelete.append( i );
228 for (
int j = toDelete.count() - 1; j >= 0; --j )
230 int index = toDelete[j];
231 qgsConnectionPool_ConnectionDestroy(
conns[index].
c );
232 conns.remove( index );
235 if (
conns.isEmpty() )
270 template <
typename T,
typename T_Group>
280 for ( T_Group *group : std::as_const(
mGroups ) )
301 typename T_Groups::iterator it =
mGroups.find( connInfo );
304 it =
mGroups.insert( connInfo,
new T_Group( connInfo ) );
306 T_Group *group = *it;
314 while ( !feedback->isCanceled() )
316 if ( T conn = group->acquire( 300, requestMayBeNested ) )
319 if ( timeout > 0 && timer.elapsed() >= timeout )
326 return group->acquire( timeout, requestMayBeNested );
334 typename T_Groups::iterator it =
mGroups.find( qgsConnectionPool_ConnectionToName( conn ) );
335 Q_ASSERT( it !=
mGroups.end() );
336 T_Group *group = *it;
339 group->release( conn );
352 if (
mGroups.contains( connInfo ) )
353 mGroups[connInfo]->invalidateConnections();
364 #endif // QGSCONNECTIONPOOL_H