diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py
index 6c5f37d407af356b1f4fd4760280c5af2d1fa72d..493143641b04cdbb979c7dd932e4144c4010e50c 100755
--- a/indra/llcorehttp/tests/test_llcorehttp_peer.py
+++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py
@@ -34,16 +34,19 @@
 import time
 import select
 import getopt
-from threading import Thread
 try:
     from cStringIO import StringIO
 except ImportError:
     from StringIO import StringIO
 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
-from SocketServer import ThreadingMixIn
 
 from llbase.fastest_elementtree import parse as xml_parse
 from llbase import llsd
+
+# we're in llcorehttp/tests ; testrunner.py is found in llmessage/tests
+sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
+                             "llmessage", "tests"))
+
 from testrunner import freeport, run, debug, VERBOSE
 
 class TestHTTPRequestHandler(BaseHTTPRequestHandler):
@@ -269,7 +272,7 @@ def log_error(self, format, *args):
             # Suppress error output as well
             pass
 
-class Server(ThreadingMixIn, HTTPServer):
+class Server(HTTPServer):
     # This pernicious flag is on by default in HTTPServer. But proper
     # operation of freeport() absolutely depends on it being off.
     allow_reuse_address = False
@@ -293,22 +296,26 @@ def handle_error(self, request, client_address):
         if option == "-V" or option == "--valgrind":
             do_valgrind = True
 
-    # Instantiate a Server(TestHTTPRequestHandler) on the first free port
-    # in the specified port range. Doing this inline is better than in a
-    # daemon thread: if it blows up here, we'll get a traceback. If it blew up
-    # in some other thread, the traceback would get eaten and we'd run the
-    # subject test program anyway.
-    httpd, port = freeport(xrange(8000, 8020),
-                           lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler))
+    # function to make a server with specified port
+    make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)
+
+    if not sys.platform.startswith("win"):
+        # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the
+        # runtime.
+        httpd = make_server(0)
+    else:
+        # "Then there's Windows"
+        # Instantiate a Server(TestHTTPRequestHandler) on the first free port
+        # in the specified port range.
+        httpd, port = freeport(xrange(8000, 8020), make_server)
 
     # Pass the selected port number to the subject test program via the
     # environment. We don't want to impose requirements on the test program's
     # command-line parsing -- and anyway, for C++ integration tests, that's
     # performed in TUT code rather than our own.
-    os.environ["LL_TEST_PORT"] = str(port)
-    debug("$LL_TEST_PORT = %s", port)
+    os.environ["LL_TEST_PORT"] = str(httpd.server_port)
+    debug("$LL_TEST_PORT = %s", httpd.server_port)
     if do_valgrind:
         args = ["valgrind", "--log-file=./valgrind.log"] + args
         path_search = True
-    sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), use_path=path_search, *args))
-
+    sys.exit(run(server_inst=httpd, use_path=path_search, *args))
diff --git a/indra/llcorehttp/tests/testrunner.py b/indra/llcorehttp/tests/testrunner.py
deleted file mode 100755
index 9a2de711425359cb4d0053139cde7d0dc5200981..0000000000000000000000000000000000000000
--- a/indra/llcorehttp/tests/testrunner.py
+++ /dev/null
@@ -1,265 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file   testrunner.py
-@author Nat Goodspeed
-@date   2009-03-20
-@brief  Utilities for writing wrapper scripts for ADD_COMM_BUILD_TEST unit tests
-
-$LicenseInfo:firstyear=2009&license=viewerlgpl$
-Second Life Viewer Source Code
-Copyright (C) 2010, Linden Research, Inc.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation;
-version 2.1 of the License only.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-$/LicenseInfo$
-"""
-
-from __future__ import with_statement
-
-import os
-import sys
-import re
-import errno
-import socket
-
-VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet
-# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if
-# that construct actually turns on verbosity...
-VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE)
-
-if VERBOSE:
-    def debug(fmt, *args):
-        print fmt % args
-        sys.stdout.flush()
-else:
-    debug = lambda *args: None
-
-def freeport(portlist, expr):
-    """
-    Find a free server port to use. Specifically, evaluate 'expr' (a
-    callable(port)) until it stops raising EADDRINUSE exception.
-
-    Pass:
-
-    portlist: an iterable (e.g. xrange()) of ports to try. If you exhaust the
-    range, freeport() lets the socket.error exception propagate. If you want
-    unbounded, you could pass itertools.count(baseport), though of course in
-    practice the ceiling is 2^16-1 anyway. But it seems prudent to constrain
-    the range much more sharply: if we're iterating an absurd number of times,
-    probably something else is wrong.
-
-    expr: a callable accepting a port number, specifically one of the items
-    from portlist. If calling that callable raises socket.error with
-    EADDRINUSE, freeport() retrieves the next item from portlist and retries.
-
-    Returns: (expr(port), port)
-
-    port: the value from portlist for which expr(port) succeeded
-
-    Raises:
-
-    Any exception raised by expr(port) other than EADDRINUSE.
-
-    socket.error if, for every item from portlist, expr(port) raises
-    socket.error. The exception you see is the one from the last item in
-    portlist.
-
-    StopIteration if portlist is completely empty.
-
-    Example:
-
-    class Server(HTTPServer):
-        # If you use BaseHTTPServer.HTTPServer, turning off this flag is
-        # essential for proper operation of freeport()!
-        allow_reuse_address = False
-    # ...
-    server, port = freeport(xrange(8000, 8010),
-                            lambda port: Server(("localhost", port),
-                                                MyRequestHandler))
-    # pass 'port' to client code
-    # call server.serve_forever()
-    """
-    try:
-        # If portlist is completely empty, let StopIteration propagate: that's an
-        # error because we can't return meaningful values. We have no 'port',
-        # therefore no 'expr(port)'.
-        portiter = iter(portlist)
-        port = portiter.next()
-
-        while True:
-            try:
-                # If this value of port works, return as promised.
-                value = expr(port)
-
-            except socket.error, err:
-                # Anything other than 'Address already in use', propagate
-                if err.args[0] != errno.EADDRINUSE:
-                    raise
-
-                # Here we want the next port from portiter. But on StopIteration,
-                # we want to raise the original exception rather than
-                # StopIteration. So save the original exc_info().
-                type, value, tb = sys.exc_info()
-                try:
-                    try:
-                        port = portiter.next()
-                    except StopIteration:
-                        raise type, value, tb
-                finally:
-                    # Clean up local traceback, see docs for sys.exc_info()
-                    del tb
-
-            else:
-                debug("freeport() returning %s on port %s", value, port)
-                return value, port
-
-            # Recap of the control flow above:
-            # If expr(port) doesn't raise, return as promised.
-            # If expr(port) raises anything but EADDRINUSE, propagate that
-            # exception.
-            # If portiter.next() raises StopIteration -- that is, if the port
-            # value we just passed to expr(port) was the last available -- reraise
-            # the EADDRINUSE exception.
-            # If we've actually arrived at this point, portiter.next() delivered a
-            # new port value. Loop back to pass that to expr(port).
-
-    except Exception, err:
-        debug("*** freeport() raising %s: %s", err.__class__.__name__, err)
-        raise
-
-def run(*args, **kwds):
-    """All positional arguments collectively form a command line, executed as
-    a synchronous child process.
-    In addition, pass server=new_thread_instance as an explicit keyword (to
-    differentiate it from an additional command-line argument).
-    new_thread_instance should be an instantiated but not yet started Thread
-    subclass instance, e.g.:
-    run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd"))
-    """
-    # If there's no server= keyword arg, don't start a server thread: simply
-    # run a child process.
-    try:
-        thread = kwds.pop("server")
-    except KeyError:
-        pass
-    else:
-        # Start server thread. Note that this and all other comm server
-        # threads should be daemon threads: we'll let them run "forever,"
-        # confident that the whole process will terminate when the main thread
-        # terminates, which will be when the child process terminates.
-        thread.setDaemon(True)
-        thread.start()
-    # choice of os.spawnv():
-    # - [v vs. l] pass a list of args vs. individual arguments,
-    # - [no p] don't use the PATH because we specifically want to invoke the
-    #   executable passed as our first arg,
-    # - [no e] child should inherit this process's environment.
-    debug("Running %s...", " ".join(args))
-    if kwds.get("use_path", False):
-        rc = os.spawnvp(os.P_WAIT, args[0], args)
-    else:
-        rc = os.spawnv(os.P_WAIT, args[0], args)
-    debug("%s returned %s", args[0], rc)
-    return rc
-
-# ****************************************************************************
-#   test code -- manual at this point, see SWAT-564
-# ****************************************************************************
-def test_freeport():
-    # ------------------------------- Helpers --------------------------------
-    from contextlib import contextmanager
-    # helper Context Manager for expecting an exception
-    # with exc(SomeError):
-    #     raise SomeError()
-    # raises AssertionError otherwise.
-    @contextmanager
-    def exc(exception_class, *args):
-        try:
-            yield
-        except exception_class, err:
-            for i, expected_arg in enumerate(args):
-                assert expected_arg == err.args[i], \
-                       "Raised %s, but args[%s] is %r instead of %r" % \
-                       (err.__class__.__name__, i, err.args[i], expected_arg)
-            print "Caught expected exception %s(%s)" % \
-                  (err.__class__.__name__, ', '.join(repr(arg) for arg in err.args))
-        else:
-            assert False, "Failed to raise " + exception_class.__class__.__name__
-
-    # helper to raise specified exception
-    def raiser(exception):
-        raise exception
-
-    # the usual
-    def assert_equals(a, b):
-        assert a == b, "%r != %r" % (a, b)
-
-    # ------------------------ Sanity check the above ------------------------
-    class SomeError(Exception): pass
-    # Without extra args, accept any err.args value
-    with exc(SomeError):
-        raiser(SomeError("abc"))
-    # With extra args, accept only the specified value
-    with exc(SomeError, "abc"):
-        raiser(SomeError("abc"))
-    with exc(AssertionError):
-        with exc(SomeError, "abc"):
-            raiser(SomeError("def"))
-    with exc(AssertionError):
-        with exc(socket.error, errno.EADDRINUSE):
-            raiser(socket.error(errno.ECONNREFUSED, 'Connection refused'))
-
-    # ----------- freeport() without engaging socket functionality -----------
-    # If portlist is empty, freeport() raises StopIteration.
-    with exc(StopIteration):
-        freeport([], None)
-
-    assert_equals(freeport([17], str), ("17", 17))
-
-    # This is the magic exception that should prompt us to retry
-    inuse = socket.error(errno.EADDRINUSE, 'Address already in use')
-    # Get the iterator to our ports list so we can check later if we've used all
-    ports = iter(xrange(5))
-    with exc(socket.error, errno.EADDRINUSE):
-        freeport(ports, lambda port: raiser(inuse))
-    # did we entirely exhaust 'ports'?
-    with exc(StopIteration):
-        ports.next()
-
-    ports = iter(xrange(2))
-    # Any exception but EADDRINUSE should quit immediately
-    with exc(SomeError):
-        freeport(ports, lambda port: raiser(SomeError()))
-    assert_equals(ports.next(), 1)
-
-    # ----------- freeport() with platform-dependent socket stuff ------------
-    # This is what we should've had unit tests to begin with (see CHOP-661).
-    def newbind(port):
-        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        sock.bind(('127.0.0.1', port))
-        return sock
-
-    bound0, port0 = freeport(xrange(7777, 7780), newbind)
-    assert_equals(port0, 7777)
-    bound1, port1 = freeport(xrange(7777, 7780), newbind)
-    assert_equals(port1, 7778)
-    bound2, port2 = freeport(xrange(7777, 7780), newbind)
-    assert_equals(port2, 7779)
-    with exc(socket.error, errno.EADDRINUSE):
-        bound3, port3 = freeport(xrange(7777, 7780), newbind)
-
-if __name__ == "__main__":
-    test_freeport()
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 43b6b3bcd6b4ab350c47bd3b5e48f0443ede0ceb..a07ea146212c5e208651ef42ff9519ab11661927 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -800,7 +800,7 @@ U8* LLImageBase::getData()
 	return mData; 
 }
 
-bool LLImageBase::isBufferInvalid()
+bool LLImageBase::isBufferInvalid() const
 {
 	return mBadBufferAllocation || mData == NULL ;
 }
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 9cc7431a9cfd069d6e0c31420e6287bc5a117200..d0bd4a2aefe554964057bd53051c28be4241f0a5 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -141,7 +141,7 @@ class LLImageBase
 
 	const U8 *getData() const	;
 	U8 *getData()				;
-	bool isBufferInvalid() ;
+	bool isBufferInvalid() const;
 
 	void setSize(S32 width, S32 height, S32 ncomponents);
 	U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1); // setSize() + allocateData()
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index bac18fa37404b4c3451012bed3641735ae38732e..9cd2959ea18e59b1999ca72cfeb2ecfd5cfa99ec 100755
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -31,7 +31,6 @@
 
 import os
 import sys
-from threading import Thread
 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
 
 from llbase.fastest_elementtree import parse as xml_parse
@@ -155,17 +154,23 @@ class Server(HTTPServer):
     allow_reuse_address = False
 
 if __name__ == "__main__":
-    # Instantiate a Server(TestHTTPRequestHandler) on the first free port
-    # in the specified port range. Doing this inline is better than in a
-    # daemon thread: if it blows up here, we'll get a traceback. If it blew up
-    # in some other thread, the traceback would get eaten and we'd run the
-    # subject test program anyway.
-    httpd, port = freeport(xrange(8000, 8020),
-                           lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler))
+    # function to make a server with specified port
+    make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)
+
+    if not sys.platform.startswith("win"):
+        # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the
+        # runtime.
+        httpd = make_server(0)
+    else:
+        # "Then there's Windows"
+        # Instantiate a Server(TestHTTPRequestHandler) on the first free port
+        # in the specified port range.
+        httpd, port = freeport(xrange(8000, 8020), make_server)
+
     # Pass the selected port number to the subject test program via the
     # environment. We don't want to impose requirements on the test program's
     # command-line parsing -- and anyway, for C++ integration tests, that's
     # performed in TUT code rather than our own.
-    os.environ["PORT"] = str(port)
-    debug("$PORT = %s", port)
-    sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:]))
+    os.environ["PORT"] = str(httpd.server_port)
+    debug("$PORT = %s", httpd.server_port)
+    sys.exit(run(server_inst=httpd, *sys.argv[1:]))
diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py
index 5b9beb359b8ec729f6ecb8310d0a7d7da112b578..c25945067eb0fd4ab5628fca93174aaef62b42a2 100755
--- a/indra/llmessage/tests/testrunner.py
+++ b/indra/llmessage/tests/testrunner.py
@@ -27,13 +27,12 @@
 $/LicenseInfo$
 """
 
-from __future__ import with_statement
-
 import os
 import sys
 import re
 import errno
 import socket
+import subprocess
 
 VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet
 # Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if
@@ -47,6 +46,9 @@ def debug(fmt, *args):
 else:
     debug = lambda *args: None
 
+class Error(Exception):
+    pass
+
 def freeport(portlist, expr):
     """
     Find a free server port to use. Specifically, evaluate 'expr' (a
@@ -141,34 +143,73 @@ class Server(HTTPServer):
         raise
 
 def run(*args, **kwds):
-    """All positional arguments collectively form a command line, executed as
-    a synchronous child process.
-    In addition, pass server=new_thread_instance as an explicit keyword (to
-    differentiate it from an additional command-line argument).
-    new_thread_instance should be an instantiated but not yet started Thread
-    subclass instance, e.g.:
-    run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd"))
     """
-    # If there's no server= keyword arg, don't start a server thread: simply
-    # run a child process.
+    Run a specified command as a synchronous child process, optionally
+    launching a server Thread during the run.
+
+    All positional arguments collectively form a command line. The first
+    positional argument names the program file to execute.
+
+    Returns the termination code of the child process.
+
+    In addition, you may pass keyword-only arguments:
+
+    use_path=True: allow a simple filename as command and search PATH for that
+    filename. (This argument is retained for backwards compatibility but is
+    now the default behavior.)
+
+    server_inst: an instance of a subclass of SocketServer.BaseServer.
+
+    When you pass server_inst, run() calls its handle_request() method in a
+    loop until the child process terminates.
+    """
+    # server= keyword arg is discontinued
     try:
         thread = kwds.pop("server")
     except KeyError:
         pass
     else:
-        # Start server thread. Note that this and all other comm server
-        # threads should be daemon threads: we'll let them run "forever,"
-        # confident that the whole process will terminate when the main thread
-        # terminates, which will be when the child process terminates.
-        thread.setDaemon(True)
-        thread.start()
-    # choice of os.spawnv():
-    # - [v vs. l] pass a list of args vs. individual arguments,
-    # - [no p] don't use the PATH because we specifically want to invoke the
-    #   executable passed as our first arg,
-    # - [no e] child should inherit this process's environment.
+        raise Error("Obsolete call to testrunner.run(): pass server_inst=, not server=")
+
     debug("Running %s...", " ".join(args))
-    rc = os.spawnv(os.P_WAIT, args[0], args)
+
+    try:
+        server_inst = kwds.pop("server_inst")
+    except KeyError:
+        # Without server_inst, this is very simple: just run child process.
+        rc = subprocess.call(args)
+    else:
+        # We're being asked to run a local server while the child process
+        # runs. We used to launch a daemon thread calling
+        # server_inst.serve_forever(), then eventually call sys.exit() with
+        # the daemon thread still running -- but in recent versions of Python
+        # 2, even when you call sys.exit(0), apparently killing the thread
+        # causes the Python runtime to force the process termination code
+        # nonzero. So now we avoid the extra thread altogether.
+
+        # SocketServer.BaseServer.handle_request() honors a 'timeout'
+        # attribute, if it's set to something other than None.
+        # We pick 0.5 seconds because that's the default poll timeout for
+        # BaseServer.serve_forever(), which is what we used to use.
+        server_inst.timeout = 0.5
+
+        child = subprocess.Popen(args)
+        while child.poll() is None:
+            # Setting server_inst.timeout is what keeps this handle_request()
+            # call from blocking "forever." Interestingly, looping over
+            # handle_request() with a timeout is very like the implementation
+            # of serve_forever(). We just check a different flag to break out.
+            # It might be interesting if handle_request() returned an
+            # indication of whether it in fact handled a request or timed out.
+            # Oddly, it doesn't. We could discover that by overriding
+            # handle_timeout(), whose default implementation does nothing --
+            # but in fact we really don't care. All that matters is that we
+            # regularly poll both the child process and the server socket.
+            server_inst.handle_request()
+        # We don't bother to capture the rc returned by child.poll() because
+        # poll() is already defined to capture that in its returncode attr.
+        rc = child.returncode
+
     debug("%s returned %s", args[0], rc)
     return rc
 
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 81a5537f78df20809532bc10e586d23ebf2ac322..20cba68f84779cbdbad1bc77560aa044f07662e6 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1267,6 +1267,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
 	llassert(gGLManager.mInited);
 	stop_glerror();
 
+	if (!imageraw || imageraw->isBufferInvalid())
+	{
+		LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL;
+		return FALSE;
+	}
+
 	if (discard_level < 0)
 	{
 		llassert(mCurrentDiscardLevel >= 0);
diff --git a/indra/newview/tests/test_llxmlrpc_peer.py b/indra/newview/tests/test_llxmlrpc_peer.py
index 281b72a058fde3d9ad9bc5a2092c81116d052dca..cff40aa4c2516809595b78b31c3a1a10e0af0f1e 100755
--- a/indra/newview/tests/test_llxmlrpc_peer.py
+++ b/indra/newview/tests/test_llxmlrpc_peer.py
@@ -31,15 +31,23 @@
 
 import os
 import sys
-from threading import Thread
 from SimpleXMLRPCServer import SimpleXMLRPCServer
 
 mydir = os.path.dirname(__file__)       # expected to be .../indra/newview/tests/
-sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
-sys.path.insert(1, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests"))
+sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests"))
 from testrunner import freeport, run, debug
 
 class TestServer(SimpleXMLRPCServer):
+    # This server_bind() override is borrowed and simplified from
+    # BaseHTTPServer.HTTPServer.server_bind(): we want to capture the actual
+    # server port. BaseHTTPServer.HTTPServer.server_bind() stores the actual
+    # port in a server_port attribute, but SimpleXMLRPCServer isn't derived
+    # from HTTPServer. So do it ourselves.
+    def server_bind(self):
+        """Override server_bind to store the server port."""
+        SimpleXMLRPCServer.server_bind(self)
+        self.server_port = self.socket.getsockname()[1]
+
     def _dispatch(self, method, params):
         try:
             func = getattr(self, method)
@@ -67,15 +75,21 @@ def log_error(self, format, *args):
         pass
 
 if __name__ == "__main__":
-    # Instantiate a TestServer on the first free port in the specified port
-    # range. Doing this inline is better than in a daemon thread: if it blows
-    # up here, we'll get a traceback. If it blew up in some other thread, the
-    # traceback would get eaten and we'd run the subject test program anyway.
-    xmlrpcd, port = freeport(xrange(8000, 8020),
-                             lambda port: TestServer(('127.0.0.1', port)))
+    # function to make a server with specified port
+    make_server = lambda port: TestServer(('127.0.0.1', port))
+
+    if not sys.platform.startswith("win"):
+        # Instantiate a TestServer on a port chosen by the runtime.
+        xmlrpcd = make_server(0)
+    else:
+        # "Then there's Windows"
+        # Instantiate a TestServer on the first free port in the specified
+        # port range.
+        xmlrpcd, port = freeport(xrange(8000, 8020), make_server)
+
     # Pass the selected port number to the subject test program via the
     # environment. We don't want to impose requirements on the test program's
     # command-line parsing -- and anyway, for C++ integration tests, that's
     # performed in TUT code rather than our own.
-    os.environ["PORT"] = str(port)
-    sys.exit(run(server=Thread(name="xmlrpc", target=xmlrpcd.serve_forever), *sys.argv[1:]))
+    os.environ["PORT"] = str(xmlrpcd.server_port)
+    sys.exit(run(server_inst=xmlrpcd, *sys.argv[1:]))