Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision 1ede0598fc7143538b96aeaa2c832f4801b4079c)
+++ uspace/lib/c/generic/fibril_synch.c	(revision 7c15d6fdab0640d24d4287b2b625aad65abc0ce9)
@@ -461,9 +461,9 @@
 			if (rc == ETIMEOUT && timer->state == fts_active) {
 				timer->state = fts_fired;
-				timer->handler_running = true;
+				timer->handler_fid = fibril_get_id();
 				fibril_mutex_unlock(timer->lockp);
 				timer->fun(timer->arg);
 				fibril_mutex_lock(timer->lockp);
-				timer->handler_running = false;
+				timer->handler_fid = 0;
 			}
 			break;
@@ -608,6 +608,16 @@
 	assert(fibril_mutex_is_locked(timer->lockp));
 
-	while (timer->handler_running)
+	while (timer->handler_fid != 0) {
+		if (timer->handler_fid == fibril_get_id()) {
+			printf("Deadlock detected.\n");
+			stacktrace_print();
+			printf("Fibril %zx is trying to clear timer %p from "
+			    "inside its handler %p.\n",
+			    fibril_get_id(), timer, timer->fun);
+			abort();
+		}
+
 		fibril_condvar_wait(&timer->cv, timer->lockp);
+	}
 
 	old_state = timer->state;
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision 1ede0598fc7143538b96aeaa2c832f4801b4079c)
+++ uspace/lib/c/include/fibril_synch.h	(revision 7c15d6fdab0640d24d4287b2b625aad65abc0ce9)
@@ -135,5 +135,6 @@
 	fid_t fibril;
 	fibril_timer_state_t state;
-	bool handler_running;
+	/** FID of fibril executing handler or 0 if handler is not running */
+	fid_t handler_fid;
 
 	suseconds_t delay;
Index: uspace/srv/net/tcp/tqueue.c
===================================================================
--- uspace/srv/net/tcp/tqueue.c	(revision 1ede0598fc7143538b96aeaa2c832f4801b4079c)
+++ uspace/srv/net/tcp/tqueue.c	(revision 7c15d6fdab0640d24d4287b2b625aad65abc0ce9)
@@ -351,8 +351,8 @@
 
 	/* Reset retransmission timer */
-	tcp_tqueue_timer_set(tqe->conn);
+	fibril_timer_set_locked(conn->retransmit.timer, RETRANSMIT_TIMEOUT,
+	    retransmit_timeout_func, (void *) conn);
 
 	tcp_conn_unlock(conn);
-	tcp_conn_delref(conn);
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: retransmit_timeout_func(%p) end", conn->name, conn);
