diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 89facd5f959134a4b93b90596b41b7eabe53ab8c..9ab9cd7ab80ed8460e860e5869336904870401d5 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -79,7 +79,7 @@
 boolean server = true; // true or false but !server == client
 #define client (!server)
 boolean nodownload = false;
-static boolean serverrunning = false;
+boolean serverrunning = false;
 INT32 serverplayer = 0;
 char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
 
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index a3992c8f974401b2ef0bb2581972138074160b48..294d88d7cd030ec0dadf47e4e71d09a86b6192fc 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -523,6 +523,7 @@ typedef enum
 } kickreason_t;
 
 extern boolean server;
+extern boolean serverrunning;
 #define client (!server)
 extern boolean dedicated; // For dedicated server
 extern UINT16 software_MAXPACKETLENGTH;
diff --git a/src/hms123311.c b/src/hms123311.c
index 6730438a7ae95f8345a0adcc3249b3921a5b9c13..6e749e3bf78dcc75c5ebaeb3a517ddca2126191e 100644
--- a/src/hms123311.c
+++ b/src/hms123311.c
@@ -22,6 +22,7 @@ Documentation available here.
 #include "m_menu.h"
 #include "mserv.h"
 #include "i_tcp.h"/* for current_port */
+#include "i_threads.h"
 
 /* I just stop myself from making macros anymore. */
 #define Blame( ... ) \
@@ -34,6 +35,11 @@ consvar_t cv_masterserver_debug = {
 
 static int hms_started;
 
+static char *hms_api;
+#ifdef HAVE_THREADS
+static I_mutex hms_api_mutex;
+#endif
+
 static char *hms_server_token;
 
 struct HMS_buffer
@@ -101,13 +107,21 @@ HMS_connect (const char *format, ...)
 		return NULL;
 	}
 
-	seek = strlen(ms_API) + 1;/* + '/' */
+#ifdef HAVE_THREADS
+	I_lock_mutex(&hms_api_mutex);
+#endif
+
+	seek = strlen(hms_api) + 1;/* + '/' */
 
 	va_start (ap, format);
 	url = malloc(seek + vsnprintf(0, 0, format, ap) + 1);
 	va_end (ap);
 
-	sprintf(url, "%s/", ms_API);
+	sprintf(url, "%s/", hms_api);
+
+#ifdef HAVE_THREADS
+	I_unlock_mutex(hms_api_mutex);
+#endif
 
 	va_start (ap, format);
 	vsprintf(&url[seek], format, ap);
@@ -590,3 +604,18 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
 
 	return ok;
 }
+
+void
+HMS_set_api (char *api)
+{
+#ifdef HAVE_THREADS
+	I_lock_mutex(&hms_api_mutex);
+#endif
+	{
+		free(hms_api);
+		hms_api = api;
+	}
+#ifdef HAVE_THREADS
+	I_unlock_mutex(hms_api_mutex);
+#endif
+}
diff --git a/src/mserv.c b/src/mserv.c
index 6acb5068e8bf310ab3f9f9c9922fa37acdb1c85f..490f79d67780e78d0a3bc4cc71b8313c47132d25 100644
--- a/src/mserv.c
+++ b/src/mserv.c
@@ -61,7 +61,6 @@ consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_N
 
 consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
 
-char *ms_API;
 INT16 ms_RoomId = -1;
 
 #ifdef HAVE_THREADS
@@ -377,6 +376,19 @@ Unlist_server_thread (int *id)
 
 	free(id);
 }
+
+static void
+Change_masterserver_thread (char *api)
+{
+	Lock_state();
+	{
+		while (MSRegistered)
+			I_hold_cond(&MSCond, MSMutex);
+	}
+	Unlock_state();
+
+	HMS_set_api(api);
+}
 #endif/*HAVE_THREADS*/
 
 void RegisterServer(void)
@@ -421,7 +433,7 @@ void UnregisterServer(void)
 static boolean
 Online (void)
 {
-	return ( server && ms_RoomId > 0 );
+	return ( serverrunning && ms_RoomId > 0 );
 }
 
 static inline void SendPingToMasterServer(void)
@@ -480,21 +492,26 @@ void MasterClient_Ticker(void)
 	SendPingToMasterServer();
 }
 
-static void MasterServer_OnChange(void)
+static void
+Set_api (const char *api)
 {
-	boolean auto_register;
-
-	//auto_register = ( con_state != MSCS_NONE );
-	auto_register = false;
+#ifdef HAVE_THREADS
+	I_spawn_thread(
+			"change-masterserver",
+			(I_thread_fn)Change_masterserver_thread,
+			strdup(api)
+	);
+#else
+	HMS_set_api(strdup(api));
+#endif
+}
 
-	if (ms_API)
-	{
-		UnregisterServer();
-		Z_Free(ms_API);
-	}
+static void MasterServer_OnChange(void)
+{
+	UnregisterServer();
 
-	ms_API = Z_StrDup(cv_masterserver.string);
+	Set_api(cv_masterserver.string);
 
-	if (auto_register)
+	if (Online())
 		RegisterServer();
 }
diff --git a/src/mserv.h b/src/mserv.h
index 71350e0de722cd79761691f35e8e4959350c2ad6..06c91b334d5a773156638ea432fd1ac3a652f974 100644
--- a/src/mserv.h
+++ b/src/mserv.h
@@ -70,8 +70,6 @@ extern consvar_t cv_masterserver, cv_servername;
 extern consvar_t cv_masterserver_update_rate;
 extern consvar_t cv_masterserver_debug;
 
-extern char *ms_API;
-
 // < 0 to not connect (usually -1) (offline mode)
 // == 0 to show all rooms, not a valid hosting room
 // anything else is whatever room the MS assigns to that number (online mode)
@@ -101,7 +99,7 @@ extern msg_rooms_t room_list[NUM_LIST_ROOMS+1];
 void AddMServCommands(void);
 
 /* HTTP */
-int  HMS_in_use (void);
+void HMS_set_api (char *api);
 int  HMS_fetch_rooms (int joining, int id);
 int  HMS_register (void);
 int  HMS_unlist (void);