From b9d2aa5750579a13d63b0bb3abee896cd7d70097 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Tue, 4 Dec 2018 18:11:38 +0100
Subject: [PATCH] Protocols.HTTP.Session: Improved thread-safety.

Fixes race-condition when multiple threads call give_me_connection()
with the same url at the same time.

Fixes [PIKE-148].
---
 .gitattributes                                    | 1 -
 lib/modules/Protocols.pmod/HTTP.pmod/Session.pike | 8 +++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index 1236c4027c..e300efbe93 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -147,7 +147,6 @@ testfont binary
 /lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike foreign_ident
 /lib/modules/Protocols.pmod/DNS.pmod foreign_ident
 /lib/modules/Protocols.pmod/HTTP.pmod/Query.pike foreign_ident
-/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike foreign_ident
 /lib/modules/Protocols.pmod/IMAP.pmod/imap_server.pike foreign_ident
 /lib/modules/Protocols.pmod/IMAP.pmod/requests.pmod foreign_ident
 /lib/modules/Protocols.pmod/IRC.pmod/Requests.pmod foreign_ident
diff --git a/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike b/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike
index 97a5510e5a..13952aa650 100644
--- a/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike
+++ b/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike
@@ -1,6 +1,6 @@
 #pike __REAL_VERSION__
 
-// $Id: Session.pike,v 1.14 2004/01/11 00:49:02 nilsson Exp $
+// $Id$
 
 import Protocols.HTTP;
 
@@ -601,6 +601,7 @@ int maximum_connection_reuse=1000000;
 
 // internal (but readable for debug purposes)
 mapping(string:array(KeptConnection)) connection_cache=([]);
+Thread.Mutex connection_cache_mux = Thread.Mutex();
 int connections_kept_n=0;
 int connections_inuse_n=0;
 mapping(string:int) connections_host_n=([]);
@@ -612,6 +613,7 @@ static class KeptConnection
 
    void create(string _lookup,Query _q)
    {
+      Thread.MutexKey key = connection_cache_mux->lock(2);
       lookup=_lookup;
       q=_q;
 
@@ -623,6 +625,7 @@ static class KeptConnection
 
    void disconnect()
    {
+      Thread.MutexKey key = connection_cache_mux->lock(2);
       connection_cache[lookup]-=({this});
       if (!sizeof(connection_cache[lookup]))
 	 m_delete(connection_cache,lookup);
@@ -638,6 +641,7 @@ static class KeptConnection
 
    Query use()
    {
+      Thread.MutexKey key = connection_cache_mux->lock(2);
       connection_cache[lookup]-=({this});
       if (!sizeof(connection_cache[lookup]))
 	 m_delete(connection_cache,lookup);
@@ -660,6 +664,8 @@ Query give_me_connection(Standards.URI url)
 {
    Query q;
 
+   Thread.MutexKey key = connection_cache_mux->lock();
+
    if (array(KeptConnection) v =
        connection_cache[connection_lookup(url)])
    {
-- 
GitLab