diff --git a/btpd/btpd.c b/btpd/btpd.c
index 30c8744..426eab7 100644
--- a/btpd/btpd.c
+++ b/btpd/btpd.c
@@ -120,6 +120,8 @@ btpd_init(void)
     BTPDQ_INIT(&btpd.readq);
     BTPDQ_INIT(&btpd.writeq);
 
+    BTPDQ_INIT(&btpd.unattached);
+
     btpd.port = 6881;
 
     btpd.obwlim = 0;
diff --git a/btpd/btpd.h b/btpd/btpd.h
index e5d102d..9356d0a 100644
--- a/btpd/btpd.h
+++ b/btpd/btpd.h
@@ -50,6 +50,8 @@ struct btpd {
     struct peer_tq readq;
     struct peer_tq writeq;
 
+    struct peer_tq unattached;
+
     int port;
     int peer4_sd;
     int ipc_sd;
diff --git a/btpd/peer.c b/btpd/peer.c
index 2843b75..9c2dc90 100644
--- a/btpd/peer.c
+++ b/btpd/peer.c
@@ -25,6 +25,8 @@ peer_kill(struct peer *p)
 
     if (p->flags & PF_ATTACHED)
 	cm_on_lost_peer(p);
+    else
+	BTPDQ_REMOVE(&btpd.unattached, p, cm_entry);
     if (p->flags & PF_ON_READQ)
 	BTPDQ_REMOVE(&btpd.readq, p, rq_entry);
     if (p->flags & PF_ON_WRITEQ)
@@ -151,6 +153,7 @@ peer_create_common(int sd)
     event_set(&p->in_ev, p->sd, EV_READ, net_read_cb, p);
     event_add(&p->in_ev, NULL);
 
+    BTPDQ_INSERT_TAIL(&btpd.unattached, p, cm_entry);
     btpd.npeers++;
     return p;
 }
diff --git a/btpd/policy.c b/btpd/policy.c
index 8056149..44f0d12 100644
--- a/btpd/policy.c
+++ b/btpd/policy.c
@@ -318,6 +318,7 @@ cm_on_new_peer(struct peer *peer)
 
     tp->npeers++;
     peer->flags |= PF_ATTACHED;
+    BTPDQ_REMOVE(&btpd.unattached, peer, cm_entry);
 
     if (tp->npeers == 1) {
 	BTPDQ_INSERT_HEAD(&tp->peers, peer, cm_entry);
diff --git a/btpd/torrent.c b/btpd/torrent.c
index f1fd6f9..5419b59 100644
--- a/btpd/torrent.c
+++ b/btpd/torrent.c
@@ -156,11 +156,20 @@ torrent_unload(struct torrent *tp)
     peer = BTPDQ_FIRST(&tp->peers);
     while (peer != NULL) {
         struct peer *next = BTPDQ_NEXT(peer, cm_entry);
+	BTPDQ_REMOVE(&tp->peers, peer, cm_entry);
+	BTPDQ_INSERT_TAIL(&btpd.unattached, peer, cm_entry);
         peer->flags &= ~PF_ATTACHED;
-        peer_kill(peer);
         peer = next;
     }
 
+    peer = BTPDQ_FIRST(&btpd.unattached);
+    while (peer != NULL) {
+	struct peer *next = BTPDQ_NEXT(peer, cm_entry);
+	if (peer->tp == tp)
+	    peer_kill(peer);
+	peer = next;
+    }
+
     piece = BTPDQ_FIRST(&tp->getlst);
     while (piece != NULL) {
 	struct piece *next = BTPDQ_NEXT(piece, entry);