Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision df2e621c24f26d06158dbd519ce22ee6c3cd0775)
+++ uspace/lib/c/generic/fibril_synch.c	(revision 53f68fd038cbfc97249287d7997bce6e78828e0f)
@@ -450,28 +450,31 @@
 	fibril_mutex_lock(&timer->lock);
 
-	while (true) {
-		while (timer->state != fts_active &&
-		    timer->state != fts_cleanup) {
-
-			if (timer->state == fts_cleanup)
-				break;
-
+	while (timer->state != fts_cleanup) {
+		switch (timer->state) {
+		case fts_not_set:
+		case fts_fired:
 			fibril_condvar_wait(&timer->cv, &timer->lock);
+			break;
+		case fts_active:
+			rc = fibril_condvar_wait_timeout(&timer->cv,
+			    &timer->lock, timer->delay);
+			if (rc == ETIMEOUT && timer->state == fts_active) {
+				timer->state = fts_fired;
+				fibril_mutex_unlock(&timer->lock);
+				timer->fun(timer->arg);
+				fibril_mutex_lock(&timer->lock);
+			}
+			break;
+		case fts_cleanup:
+		case fts_clean:
+			assert(false);
+			break;
 		}
-
-		if (timer->state == fts_cleanup)
-			break;
-
-		rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock,
-		    timer->delay);
-		if (rc == ETIMEOUT) {
-			timer->state = fts_fired;
-			fibril_mutex_unlock(&timer->lock);
-			timer->fun(timer->arg);
-			fibril_mutex_lock(&timer->lock);
-		}
-	}
-
+	}
+
+	/* Acknowledge timer fibril has finished cleanup. */
+	timer->state = fts_clean;
 	fibril_mutex_unlock(&timer->lock);
+
 	return 0;
 }
@@ -514,7 +517,14 @@
 {
 	fibril_mutex_lock(&timer->lock);
-	assert(timer->state != fts_active);
+	assert(timer->state == fts_not_set || timer->state == fts_fired);
+
+	/* Request timer fibril to terminate. */
 	timer->state = fts_cleanup;
 	fibril_condvar_broadcast(&timer->cv);
+
+	/* Wait for timer fibril to acknowledge. */
+	while (timer->state != fts_clean)
+		fibril_condvar_wait(&timer->cv, &timer->lock);
+
 	fibril_mutex_unlock(&timer->lock);
 }
@@ -534,4 +544,5 @@
 {
 	fibril_mutex_lock(&timer->lock);
+	assert(timer->state == fts_not_set || timer->state == fts_fired);
 	timer->state = fts_active;
 	timer->delay = delay;
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision df2e621c24f26d06158dbd519ce22ee6c3cd0775)
+++ uspace/lib/c/include/fibril_synch.h	(revision 53f68fd038cbfc97249287d7997bce6e78828e0f)
@@ -116,6 +116,8 @@
 	/** Timer has fired and has not been cleared since */
 	fts_fired,
-	/** Timer is being destroyed */
-	fts_cleanup
+	/** Timer fibril is requested to terminate */
+	fts_cleanup,
+	/** Timer fibril acknowledged termination */
+	fts_clean
 } fibril_timer_state_t;
 
