@@ -72,6 +72,28 @@ enum class httpclient_errorcode_context
72
72
};
73
73
74
74
class asio_connection_pool ;
75
+
76
+ class asio_connection_pool_map
77
+ {
78
+ public:
79
+ static asio_connection_pool_map &instance ();
80
+
81
+ std::shared_ptr<asio_connection_pool> obtain_connection_pool (const std::string &pool_key, bool start_with_ssl, std::chrono::seconds idle_timeout);
82
+
83
+ void release_connection_pool (const std::string &pool_key);
84
+
85
+ void free_connection_pool (const boost::system::error_code &ec, const std::string &pool_key);
86
+
87
+ private:
88
+ asio_connection_pool_map ()
89
+ : m_threadpool(crossplat::threadpool::shared_instance())
90
+ {}
91
+
92
+ crossplat::threadpool &m_threadpool;
93
+ std::mutex m_connection_pool_map_mutex;
94
+ std::map<std::string, std::shared_ptr<asio_connection_pool>> m_connection_pool_map;
95
+ };
96
+
75
97
class asio_connection
76
98
{
77
99
friend class asio_connection_pool ;
@@ -257,8 +279,7 @@ class asio_connection_pool
257
279
m_start_with_ssl (start_with_ssl),
258
280
m_ssl_context_callback (ssl_context_callback),
259
281
m_pool_timeout_secs (60 ), // Clean this connection pool 60 secs after the last asio_client release it.
260
- m_pool_timer (io_service),
261
- m_use_count (0 )
282
+ m_pool_timer (io_service)
262
283
{}
263
284
264
285
~asio_connection_pool ()
@@ -320,11 +341,6 @@ class asio_connection_pool
320
341
}
321
342
}
322
343
323
- int &use_count ()
324
- {
325
- return m_use_count;
326
- }
327
-
328
344
private:
329
345
330
346
// Using weak_ptr here ensures bind() to this handler will not prevent the connection object from going out of scope.
@@ -354,9 +370,49 @@ class asio_connection_pool
354
370
355
371
const int m_pool_timeout_secs;
356
372
boost::asio::deadline_timer m_pool_timer;
357
- int m_use_count;
358
373
};
359
374
375
+ asio_connection_pool_map &asio_connection_pool_map::instance ()
376
+ {
377
+ static asio_connection_pool_map s_instance;
378
+ return s_instance;
379
+ }
380
+
381
+ std::shared_ptr<asio_connection_pool> asio_connection_pool_map::obtain_connection_pool (const std::string &pool_key, bool start_with_ssl, std::chrono::seconds idle_timeout)
382
+ {
383
+ std::lock_guard<std::mutex> lg (m_connection_pool_map_mutex);
384
+ auto &pool = m_connection_pool_map[pool_key];
385
+ if (!pool)
386
+ {
387
+ pool = std::make_shared<asio_connection_pool>(crossplat::threadpool::shared_instance ().service (), start_with_ssl, idle_timeout, nullptr );
388
+ }
389
+
390
+ pool->cancel_pool_timer ();
391
+ return pool;
392
+ }
393
+
394
+ void asio_connection_pool_map::release_connection_pool (const std::string &pool_key)
395
+ {
396
+ std::lock_guard<std::mutex> lg (m_connection_pool_map_mutex);
397
+ auto &pool = m_connection_pool_map[pool_key];
398
+ if (pool)
399
+ {
400
+ pool->start_pool_timer (boost::bind (&asio_connection_pool_map::free_connection_pool, this , boost::asio::placeholders::error, pool_key));
401
+ }
402
+ }
403
+
404
+ void asio_connection_pool_map::free_connection_pool (const boost::system::error_code &ec, const std::string &pool_key)
405
+ {
406
+ if (!ec)
407
+ {
408
+ std::lock_guard<std::mutex> lg (m_connection_pool_map_mutex);
409
+ auto &pool = m_connection_pool_map[pool_key];
410
+ if (pool && pool.use_count () == 1 )
411
+ {
412
+ m_connection_pool_map.erase (pool_key);
413
+ }
414
+ }
415
+ }
360
416
361
417
class asio_client : public _http_client_communicator
362
418
{
@@ -365,13 +421,14 @@ class asio_client : public _http_client_communicator
365
421
: _http_client_communicator(std::move(address), std::move(client_config))
366
422
, m_resolver(crossplat::threadpool::shared_instance().service())
367
423
{
368
- if (this ->client_config ().get_ssl_context_callback ())
424
+ bool start_with_ssl = base_uri ().scheme () == " https" && !_http_client_communicator::client_config ().proxy ().is_specified ();
425
+ const std::chrono::seconds idle_timeout (30 ); // Unused sockets are kept in pool for 30 seconds.
426
+ auto ssl_context_callback = this ->client_config ().get_ssl_context_callback ();
427
+
428
+ if (ssl_context_callback)
369
429
{
370
430
// The pool is not added to the map because there is no better approaches to compare callback functors.
371
- m_pool = std::make_shared<asio_connection_pool>(crossplat::threadpool::shared_instance ().service (),
372
- base_uri ().scheme () == " https" && !_http_client_communicator::client_config ().proxy ().is_specified (),
373
- std::chrono::seconds (30 ), // Unused sockets are kept in pool for 30 seconds.
374
- this ->client_config ().get_ssl_context_callback ());
431
+ m_pool = std::make_shared<asio_connection_pool>(crossplat::threadpool::shared_instance ().service (), start_with_ssl, idle_timeout, ssl_context_callback);
375
432
}
376
433
else
377
434
{
@@ -393,37 +450,15 @@ class asio_client : public _http_client_communicator
393
450
}
394
451
}
395
452
396
- m_pool = crossplat::threadpool::shared_instance ().obtain_connection_pool (m_pool_key, [this ]()
397
- {
398
- return std::make_shared<asio_connection_pool>(crossplat::threadpool::shared_instance ().service (),
399
- base_uri ().scheme () == " https" && !_http_client_communicator::client_config ().proxy ().is_specified (),
400
- std::chrono::seconds (30 ), // Unused sockets are kept in pool for 30 seconds.
401
- nullptr );
402
- });
403
-
404
- if (m_pool->use_count () == 0 )
405
- {
406
- m_pool->cancel_pool_timer ();
407
- }
408
- ++m_pool->use_count ();
453
+ m_pool = asio_connection_pool_map::instance ().obtain_connection_pool (m_pool_key, start_with_ssl, idle_timeout);
409
454
}
410
455
}
411
456
412
457
~asio_client ()
413
458
{
414
459
if (!m_pool_key.empty ())
415
460
{
416
- crossplat::threadpool::shared_instance ().release_connection_pool (m_pool_key, [this ](std::shared_ptr<web::http::client::details::asio_connection_pool> pool)
417
- {
418
- if (pool)
419
- {
420
- --pool->use_count ();
421
- if (pool->use_count () == 0 )
422
- {
423
- pool->start_pool_timer (boost::bind (&crossplat::threadpool::free_connection_pool, &crossplat::threadpool::shared_instance (), boost::asio::placeholders::error, m_pool_key));
424
- }
425
- }
426
- });
461
+ asio_connection_pool_map::instance ().release_connection_pool (m_pool_key);
427
462
}
428
463
}
429
464
0 commit comments