diff --git a/devlib/exception.py b/devlib/exception.py
index a7884c8..33ef3c0 100644
--- a/devlib/exception.py
+++ b/devlib/exception.py
@@ -180,3 +180,11 @@ def get_traceback(exc=None):
     traceback.print_tb(tb, file=sio)
     del tb  # needs to be done explicitly see: http://docs.python.org/2/library/sys.html#sys.exc_info
     return sio.getvalue()
+
+
+class AdbRootError(TargetStableError):
+    """
+    Exception raised when it is not safe to use ``adb root`` or ``adb unroot``
+    because other connections are known to be active, and changing rootness
+    requires restarting the server.
+    """
diff --git a/devlib/utils/android.py b/devlib/utils/android.py
index b46a825..5d20ca3 100755
--- a/devlib/utils/android.py
+++ b/devlib/utils/android.py
@@ -40,7 +40,7 @@ try:
 except ImportError:
     from pipes import quote
 
-from devlib.exception import TargetTransientError, TargetStableError, HostError, TargetTransientCalledProcessError, TargetStableCalledProcessError
+from devlib.exception import TargetTransientError, TargetStableError, HostError, TargetTransientCalledProcessError, TargetStableCalledProcessError, AdbRootError
 from devlib.utils.misc import check_output, which, ABI_MAP, redirect_streams, get_subprocess
 from devlib.connection import ConnectionBase, AdbBackgroundCommand, PopenBackgroundCommand, PopenTransferManager
 
@@ -301,10 +301,17 @@ class AdbConnection(ConnectionBase):
                             'poll_period': transfer_poll_period,
                             }
         self.transfer_mgr = PopenTransferManager(self, **transfer_opts) if poll_transfers else None
-        if self.adb_as_root:
-            self.adb_root(enable=True)
-        adb_connect(self.device, adb_server=self.adb_server, attempts=connection_attempts)
         AdbConnection.active_connections[self.device] += 1
+        if self.adb_as_root:
+            try:
+                self.adb_root(enable=True)
+            # Exception will be raised if we are not the only connection
+            # active. adb_root() requires restarting the server, which is not
+            # acceptable if other connections are active and can apparently
+            # lead to commands hanging forever in some situations.
+            except AdbRootError:
+                pass
+        adb_connect(self.device, adb_server=self.adb_server, attempts=connection_attempts)
         self._setup_ls()
         self._setup_su()
 
@@ -384,6 +391,9 @@ class AdbConnection(ConnectionBase):
         pass
 
     def adb_root(self, enable=True):
+        if AdbConnection.active_connections[self.device] > 1:
+            raise AdbRootError('Can only restart adb server if no other connection is active')
+
         cmd = 'root' if enable else 'unroot'
         try:
             output = adb_command(self.device, cmd, timeout=30, adb_server=self.adb_server)