The _Event class should be more careful with releasing its lock when
interrupted.  A try/finally will do nicely.  Maybe other classes need
this too, but since they manipulate more state it's less clear that
that is always the right thing, and I'm in a hurry.

Backport candidate.
diff --git a/Lib/threading.py b/Lib/threading.py
index f949d75..1e769a8 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -318,20 +318,26 @@
 
     def set(self):
         self.__cond.acquire()
-        self.__flag = True
-        self.__cond.notifyAll()
-        self.__cond.release()
+        try:
+            self.__flag = True
+            self.__cond.notifyAll()
+        finally:
+            self.__cond.release()
 
     def clear(self):
         self.__cond.acquire()
-        self.__flag = False
-        self.__cond.release()
+        try:
+            self.__flag = False
+        finally:
+            self.__cond.release()
 
     def wait(self, timeout=None):
         self.__cond.acquire()
-        if not self.__flag:
-            self.__cond.wait(timeout)
-        self.__cond.release()
+        try:
+            if not self.__flag:
+                self.__cond.wait(timeout)
+        finally:
+            self.__cond.release()
 
 # Helper to generate new thread names
 _counter = 0