@@ -123,218 +123,219 @@ class QgsConnectionPoolGroup
123
123
{
124
124
qgsConnectionPool_ConnectionDestroy ( i.c );
125
125
qgsConnectionPool_ConnectionCreate ( connInfo, i.c );
126
+ }
126
127
127
128
128
- // no need to run if nothing can expire
129
- if ( conns.isEmpty () )
130
- {
131
- // will call the slot directly or queue the call (if the object lives in a different thread)
132
- QMetaObject::invokeMethod ( expirationTimer->parent (), " stopExpirationTimer" );
133
- }
134
-
135
- acquiredConns.append ( i.c );
136
-
137
- return i.c ;
129
+ // no need to run if nothing can expire
130
+ if ( conns.isEmpty () )
131
+ {
132
+ // will call the slot directly or queue the call (if the object lives in a different thread)
133
+ QMetaObject::invokeMethod ( expirationTimer->parent (), " stopExpirationTimer" );
138
134
}
139
- }
140
135
141
- T c;
142
- qgsConnectionPool_ConnectionCreate ( connInfo, c );
143
- if ( !c )
144
- {
145
- // we didn't get connection for some reason, so release the lock
146
- sem.release ();
147
- return nullptr ;
148
- }
136
+ acquiredConns.append ( i.c );
149
137
150
- connMutex.lock ();
151
- acquiredConns.append ( c );
152
- connMutex.unlock ();
153
- return c;
138
+ return i.c ;
139
+ }
154
140
}
155
141
156
- void release ( T conn )
142
+ T c;
143
+ qgsConnectionPool_ConnectionCreate ( connInfo, c );
144
+ if ( !c )
157
145
{
158
- connMutex.lock ();
159
- acquiredConns.removeAll ( conn );
160
- if ( !qgsConnectionPool_ConnectionIsValid ( conn ) )
161
- {
162
- qgsConnectionPool_ConnectionDestroy ( conn );
163
- }
164
- else
165
- {
166
- Item i;
167
- i.c = conn;
168
- i.lastUsedTime = QTime::currentTime ();
169
- conns.push ( i );
170
-
171
- if ( !expirationTimer->isActive () )
172
- {
173
- // will call the slot directly or queue the call (if the object lives in a different thread)
174
- QMetaObject::invokeMethod ( expirationTimer->parent (), " startExpirationTimer" );
175
- }
176
- }
146
+ // we didn't get connection for some reason, so release the lock
147
+ sem.release ();
148
+ return nullptr ;
149
+ }
177
150
178
- connMutex.unlock ();
151
+ connMutex.lock ();
152
+ acquiredConns.append ( c );
153
+ connMutex.unlock ();
154
+ return c;
155
+ }
179
156
180
- sem.release (); // this can unlock a thread waiting in acquire()
157
+ void release ( T conn )
158
+ {
159
+ connMutex.lock ();
160
+ acquiredConns.removeAll ( conn );
161
+ if ( !qgsConnectionPool_ConnectionIsValid ( conn ) )
162
+ {
163
+ qgsConnectionPool_ConnectionDestroy ( conn );
181
164
}
182
-
183
- void invalidateConnections ()
165
+ else
184
166
{
185
- connMutex.lock ();
186
- for ( const Item &i : qgis::as_const ( conns ) )
167
+ Item i;
168
+ i.c = conn;
169
+ i.lastUsedTime = QTime::currentTime ();
170
+ conns.push ( i );
171
+
172
+ if ( !expirationTimer->isActive () )
187
173
{
188
- qgsConnectionPool_ConnectionDestroy ( i.c );
174
+ // will call the slot directly or queue the call (if the object lives in a different thread)
175
+ QMetaObject::invokeMethod ( expirationTimer->parent (), " startExpirationTimer" );
189
176
}
190
- conns.clear ();
191
- for ( T c : qgis::as_const ( acquiredConns ) )
192
- qgsConnectionPool_InvalidateConnection ( c );
193
- connMutex.unlock ();
194
177
}
195
178
196
- protected:
179
+ connMutex. unlock ();
197
180
198
- void initTimer ( QObject * parent )
181
+ sem.release (); // this can unlock a thread waiting in acquire()
182
+ }
183
+
184
+ void invalidateConnections ()
185
+ {
186
+ connMutex.lock ();
187
+ for ( const Item &i : qgis::as_const ( conns ) )
199
188
{
200
- expirationTimer = new QTimer ( parent );
201
- expirationTimer->setInterval ( CONN_POOL_EXPIRATION_TIME * 1000 );
202
- QObject::connect ( expirationTimer, SIGNAL ( timeout () ), parent, SLOT ( handleConnectionExpired () ) );
189
+ qgsConnectionPool_ConnectionDestroy ( i.c );
190
+ }
191
+ conns.clear ();
192
+ for ( T c : qgis::as_const ( acquiredConns ) )
193
+ qgsConnectionPool_InvalidateConnection ( c );
194
+ connMutex.unlock ();
195
+ }
196
+
197
+ protected:
198
+
199
+ void initTimer ( QObject *parent )
200
+ {
201
+ expirationTimer = new QTimer ( parent );
202
+ expirationTimer->setInterval ( CONN_POOL_EXPIRATION_TIME * 1000 );
203
+ QObject::connect ( expirationTimer, SIGNAL ( timeout () ), parent, SLOT ( handleConnectionExpired () ) );
203
204
204
- // just to make sure the object belongs to main thread and thus will get events
205
- if ( qApp )
206
- parent->moveToThread ( qApp->thread () );
205
+ // just to make sure the object belongs to main thread and thus will get events
206
+ if ( qApp )
207
+ parent->moveToThread ( qApp->thread () );
208
+ }
209
+
210
+ void onConnectionExpired ()
211
+ {
212
+ connMutex.lock ();
213
+
214
+ QTime now = QTime::currentTime ();
215
+
216
+ // what connections have expired?
217
+ QList<int > toDelete;
218
+ for ( int i = 0 ; i < conns.count (); ++i )
219
+ {
220
+ if ( conns.at ( i ).lastUsedTime .secsTo ( now ) >= CONN_POOL_EXPIRATION_TIME )
221
+ toDelete.append ( i );
207
222
}
208
223
209
- void onConnectionExpired ()
224
+ // delete expired connections
225
+ for ( int j = toDelete.count () - 1 ; j >= 0 ; --j )
210
226
{
211
- connMutex.lock ();
227
+ int index = toDelete[j];
228
+ qgsConnectionPool_ConnectionDestroy ( conns[index].c );
229
+ conns.remove ( index );
230
+ }
212
231
213
- QTime now = QTime::currentTime ();
232
+ if ( conns.isEmpty () )
233
+ expirationTimer->stop ();
214
234
215
- // what connections have expired?
216
- QList<int > toDelete;
217
- for ( int i = 0 ; i < conns.count (); ++i )
218
- {
219
- if ( conns.at ( i ).lastUsedTime .secsTo ( now ) >= CONN_POOL_EXPIRATION_TIME )
220
- toDelete.append ( i );
221
- }
235
+ connMutex.unlock ();
236
+ }
222
237
223
- // delete expired connections
224
- for ( int j = toDelete.count () - 1 ; j >= 0 ; --j )
225
- {
226
- int index = toDelete[j];
227
- qgsConnectionPool_ConnectionDestroy ( conns[index].c );
228
- conns.remove ( index );
229
- }
238
+ protected:
230
239
231
- if ( conns.isEmpty () )
232
- expirationTimer->stop ();
240
+ QString connInfo;
241
+ QStack<Item> conns;
242
+ QList<T> acquiredConns;
243
+ QMutex connMutex;
244
+ QSemaphore sem;
245
+ QTimer *expirationTimer = nullptr ;
233
246
234
- connMutex.unlock ();
235
- }
247
+ };
236
248
237
- protected:
238
249
239
- QString connInfo;
240
- QStack<Item> conns;
241
- QList<T> acquiredConns;
242
- QMutex connMutex;
243
- QSemaphore sem;
244
- QTimer *expirationTimer = nullptr ;
250
+ /* *
251
+ * \ingroup core
252
+ * Template class responsible for keeping a pool of open connections.
253
+ * This is desired to avoid the overhead of creation of new connection every time.
254
+ *
255
+ * The methods are thread safe.
256
+ *
257
+ * The connection pool has a limit on maximum number of concurrent connections
258
+ * (per server), once the limit is reached, the acquireConnection() function
259
+ * will block. All connections that have been acquired must be then released
260
+ * with releaseConnection() function.
261
+ *
262
+ * When the connections are not used for some time, they will get closed automatically
263
+ * to save resources.
264
+ * \note not available in Python bindings
265
+ */
266
+ template <typename T, typename T_Group>
267
+ class QgsConnectionPool
268
+ {
269
+ public:
245
270
246
- } ;
271
+ typedef QMap<QString, T_Group *> T_Groups ;
247
272
273
+ virtual ~QgsConnectionPool ()
274
+ {
275
+ mMutex .lock ();
276
+ for ( T_Group *group : qgis::as_const ( mGroups ) )
277
+ {
278
+ delete group;
279
+ }
280
+ mGroups .clear ();
281
+ mMutex .unlock ();
282
+ }
248
283
249
284
/* *
250
- * \ingroup core
251
- * Template class responsible for keeping a pool of open connections.
252
- * This is desired to avoid the overhead of creation of new connection every time .
285
+ * Try to acquire a connection for a maximum of \a timeout milliseconds.
286
+ * If \a timeout is a negative value the calling thread will be blocked
287
+ * until a connection becomes available. This is the default behavior .
253
288
*
254
- * The methods are thread safe.
255
289
*
256
- * The connection pool has a limit on maximum number of concurrent connections
257
- * (per server), once the limit is reached, the acquireConnection() function
258
- * will block. All connections that have been acquired must be then released
259
- * with releaseConnection() function.
260
290
*
261
- * When the connections are not used for some time, they will get closed automatically
262
- * to save resources.
263
- * \note not available in Python bindings
291
+ * \returns initialized connection or nullptr if unsuccessful
264
292
*/
265
- template <typename T, typename T_Group>
266
- class QgsConnectionPool
293
+ T acquireConnection ( const QString &connInfo, int timeout = -1 , bool requestMayBeNested = false )
267
294
{
268
- public:
269
-
270
- typedef QMap<QString, T_Group *> T_Groups;
271
-
272
- virtual ~QgsConnectionPool ()
273
- {
274
- mMutex .lock ();
275
- for ( T_Group *group : qgis::as_const ( mGroups ) )
276
- {
277
- delete group;
278
- }
279
- mGroups .clear ();
280
- mMutex .unlock ();
281
- }
282
-
283
- /* *
284
- * Try to acquire a connection for a maximum of \a timeout milliseconds.
285
- * If \a timeout is a negative value the calling thread will be blocked
286
- * until a connection becomes available. This is the default behavior.
287
- *
288
- *
289
- *
290
- * \returns initialized connection or nullptr if unsuccessful
291
- */
292
- T acquireConnection ( const QString &connInfo, int timeout = -1 , bool requestMayBeNested = false )
293
- {
294
- mMutex .lock ();
295
- typename T_Groups::iterator it = mGroups .find ( connInfo );
296
- if ( it == mGroups .end () )
297
- {
298
- it = mGroups .insert ( connInfo, new T_Group ( connInfo ) );
299
- }
300
- T_Group *group = *it;
301
- mMutex .unlock ();
295
+ mMutex .lock ();
296
+ typename T_Groups::iterator it = mGroups .find ( connInfo );
297
+ if ( it == mGroups .end () )
298
+ {
299
+ it = mGroups .insert ( connInfo, new T_Group ( connInfo ) );
300
+ }
301
+ T_Group *group = *it;
302
+ mMutex .unlock ();
302
303
303
- return group->acquire ( timeout, requestMayBeNested );
304
- }
304
+ return group->acquire ( timeout, requestMayBeNested );
305
+ }
305
306
306
- // ! Release an existing connection so it will get back into the pool and can be reused
307
- void releaseConnection ( T conn )
308
- {
309
- mMutex .lock ();
310
- typename T_Groups::iterator it = mGroups .find ( qgsConnectionPool_ConnectionToName ( conn ) );
311
- Q_ASSERT ( it != mGroups .end () );
312
- T_Group *group = *it;
313
- mMutex .unlock ();
307
+ // ! Release an existing connection so it will get back into the pool and can be reused
308
+ void releaseConnection ( T conn )
309
+ {
310
+ mMutex .lock ();
311
+ typename T_Groups::iterator it = mGroups .find ( qgsConnectionPool_ConnectionToName ( conn ) );
312
+ Q_ASSERT ( it != mGroups .end () );
313
+ T_Group *group = *it;
314
+ mMutex .unlock ();
314
315
315
- group->release ( conn );
316
- }
316
+ group->release ( conn );
317
+ }
317
318
318
- /* *
319
- * Invalidates all connections to the specified resource.
320
- * The internal state of certain handles (for instance OGR) are altered
321
- * when a dataset is modified. Consquently, all open handles need to be
322
- * invalidated when such datasets are changed to ensure the handles are
323
- * refreshed. See the OGR provider for an example where this is needed.
324
- */
325
- void invalidateConnections ( const QString &connInfo )
326
- {
327
- mMutex .lock ();
328
- if ( mGroups .contains ( connInfo ) )
329
- mGroups [connInfo]->invalidateConnections ();
330
- mMutex .unlock ();
331
- }
319
+ /* *
320
+ * Invalidates all connections to the specified resource.
321
+ * The internal state of certain handles (for instance OGR) are altered
322
+ * when a dataset is modified. Consquently, all open handles need to be
323
+ * invalidated when such datasets are changed to ensure the handles are
324
+ * refreshed. See the OGR provider for an example where this is needed.
325
+ */
326
+ void invalidateConnections ( const QString &connInfo )
327
+ {
328
+ mMutex .lock ();
329
+ if ( mGroups .contains ( connInfo ) )
330
+ mGroups [connInfo]->invalidateConnections ();
331
+ mMutex .unlock ();
332
+ }
332
333
333
334
334
- protected:
335
- T_Groups mGroups ;
336
- QMutex mMutex ;
337
- };
335
+ protected:
336
+ T_Groups mGroups ;
337
+ QMutex mMutex ;
338
+ };
338
339
339
340
340
341
#endif // QGSCONNECTIONPOOL_H
0 commit comments