Index: generic/include/proc/thread.h
===================================================================
--- generic/include/proc/thread.h	(revision fe04594398a175db7fe2fccfec39a1b8e74b0a05)
+++ generic/include/proc/thread.h	(revision 203f4c3aea8429f12d8190c6d45de70bfc8f4e7b)
@@ -81,6 +81,10 @@
 	void *thread_arg;			/**< Argument passed to thread_code() function. */
 
-	context_t saved_context;		/**< From here, the stored context is restored when the thread is scheduled. */
-	context_t sleep_timeout_context;	/**< From here, the stored failover context is restored when sleep times out. */
+	/** From here, the stored context is restored when the thread is scheduled. */
+	context_t saved_context;
+	/** From here, the stored timeout context is restored when sleep times out. */
+	context_t sleep_timeout_context;
+	/** From here, the stored interruption context is restored when sleep is interrupted. */
+	context_t sleep_interruption_context;
 
 	waitq_t *sleep_queue;			/**< Wait queue in which this thread sleeps. */
Index: generic/include/synch/synch.h
===================================================================
--- generic/include/synch/synch.h	(revision fe04594398a175db7fe2fccfec39a1b8e74b0a05)
+++ generic/include/synch/synch.h	(revision 203f4c3aea8429f12d8190c6d45de70bfc8f4e7b)
@@ -36,8 +36,9 @@
 #define ESYNCH_WOULD_BLOCK	1	/**< Could not satisfy the request without going to sleep. */
 #define ESYNCH_TIMEOUT		2	/**< Timeout occurred. */
-#define ESYNCH_OK_ATOMIC	4	/**< Operation succeeded without sleeping. */
-#define ESYNCH_OK_BLOCKED	8	/**< Operation succeeded and did sleep. */
+#define ESYNCH_INTERRUPTED	4	/**< Sleep was interrupted. */
+#define ESYNCH_OK_ATOMIC	8	/**< Operation succeeded without sleeping. */
+#define ESYNCH_OK_BLOCKED	16	/**< Operation succeeded and did sleep. */
 
-#define SYNCH_FAILED(rc)	((rc) & (ESYNCH_WOULD_BLOCK | ESYNCH_TIMEOUT))
+#define SYNCH_FAILED(rc)	((rc) & (ESYNCH_WOULD_BLOCK | ESYNCH_TIMEOUT | ESYNCH_INTERRUPTED))
 #define SYNCH_OK(rc)		((rc) & (ESYNCH_OK_ATOMIC | ESYNCH_OK_BLOCKED))
 
Index: generic/include/synch/waitq.h
===================================================================
--- generic/include/synch/waitq.h	(revision fe04594398a175db7fe2fccfec39a1b8e74b0a05)
+++ generic/include/synch/waitq.h	(revision 203f4c3aea8429f12d8190c6d45de70bfc8f4e7b)
@@ -55,10 +55,9 @@
 	waitq_sleep_timeout((wq),SYNCH_NO_TIMEOUT,SYNCH_BLOCKING)
 
-extern void waitq_interrupted_sleep(void *data);
-
 extern void waitq_initialize(waitq_t *wq);
 extern int waitq_sleep_timeout(waitq_t *wq, __u32 usec, int nonblocking);
 extern void waitq_wakeup(waitq_t *wq, bool all);
 extern void _waitq_wakeup_unsafe(waitq_t *wq, bool all);
+extern void waitq_interrupt_sleep(thread_t *t);
 
 #endif
Index: generic/src/synch/waitq.c
===================================================================
--- generic/src/synch/waitq.c	(revision fe04594398a175db7fe2fccfec39a1b8e74b0a05)
+++ generic/src/synch/waitq.c	(revision 203f4c3aea8429f12d8190c6d45de70bfc8f4e7b)
@@ -40,4 +40,6 @@
 #include <adt/list.h>
 
+static void waitq_timeouted_sleep(void *data);
+
 /** Initialize wait queue
  *
@@ -65,5 +67,5 @@
  * @param data Pointer to the thread that called waitq_sleep_timeout().
  */
-void waitq_interrupted_sleep(void *data)
+void waitq_timeouted_sleep(void *data)
 {
 	thread_t *t = (thread_t *) data;
@@ -101,5 +103,49 @@
 }
 
-/** Sleep until either wakeup or timeout occurs
+/** Interrupt sleeping thread.
+ *
+ * This routine attempts to interrupt a thread from its sleep in a waitqueue.
+ * If the thread is not found sleeping, no action is taken.
+ *
+ * @param t Thread to be interrupted.
+ */
+void waitq_interrupt_sleep(thread_t *t)
+{
+	waitq_t *wq;
+	bool do_wakeup = false;
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&threads_lock);
+	if (!list_member(&t->threads_link, &threads_head))
+		goto out;
+
+grab_locks:
+	spinlock_lock(&t->lock);
+	if ((wq = t->sleep_queue)) {		/* assignment */
+		if (!spinlock_trylock(&wq->lock)) {
+			spinlock_unlock(&t->lock);
+			goto grab_locks;	/* avoid deadlock */
+		}
+
+		list_remove(&t->wq_link);
+		t->saved_context = t->sleep_interruption_context;
+		do_wakeup = true;
+		
+		spinlock_unlock(&wq->lock);
+		t->sleep_queue = NULL;
+	}
+	spinlock_unlock(&t->lock);
+
+	if (do_wakeup)
+		thread_ready(t);
+
+out:
+	spinlock_unlock(&threads_lock);
+	interrupts_restore(ipl);
+}
+
+
+/** Sleep until either wakeup, timeout or interruption occurs
  *
  * This is a sleep implementation which allows itself to be
@@ -131,4 +177,6 @@
  *
  * ESYNCH_TIMEOUT means that the sleep timed out.
+ *
+ * ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread.
  *
  * ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was
@@ -179,5 +227,4 @@
 		}
 	}
-
 	
 	/*
@@ -185,10 +232,20 @@
 	 */
 	spinlock_lock(&THREAD->lock);
+
+	/*
+	 * Set context that will be restored if the sleep
+	 * of this thread is ever interrupted.
+	 */
+	if (!context_save(&THREAD->sleep_interruption_context)) {
+		/* Short emulation of scheduler() return code. */
+		spinlock_unlock(&THREAD->lock);
+		interrupts_restore(ipl);
+		return ESYNCH_INTERRUPTED;
+	}
+
 	if (usec) {
 		/* We use the timeout variant. */
 		if (!context_save(&THREAD->sleep_timeout_context)) {
-			/*
-			 * Short emulation of scheduler() return code.
-			 */
+			/* Short emulation of scheduler() return code. */
 			spinlock_unlock(&THREAD->lock);
 			interrupts_restore(ipl);
@@ -196,5 +253,5 @@
 		}
 		THREAD->timeout_pending = true;
-		timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD);
+		timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_timeouted_sleep, THREAD);
 	}
 
