fix
diff --git a/ChangeLog b/ChangeLog
index 2bac818..710b4f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-11-21  Miklos Szeredi <miklos@szeredi.hu>
+
+	* Don't use async cancelation in multithreaded loop.  This makes
+	it more portable to systems where read() is not async cancel safe.
+	Report from Andriy Gapon
+
 2005-11-20  Miklos Szeredi <miklos@szeredi.hu>
 
 	* Warn if API version 11 compatibility is requested
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index df254a9..95399d7 100644
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -27,6 +27,7 @@
     struct fuse_chan *ch;
     struct fuse_chan *prevch;
     pthread_t threads[FUSE_MAX_WORKERS];
+    int exit;
     int error;
 };
 
@@ -70,7 +71,7 @@
 
     pthread_cleanup_push(free, buf);
     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
 
     while (!fuse_session_exited(w->se)) {
         int res = fuse_chan_receive(w->prevch, buf, bufsize);
@@ -83,6 +84,10 @@
         }
 
         pthread_mutex_lock(&w->lock);
+        if (w->exit) {
+            pthread_mutex_unlock(&w->lock);
+            break;
+        }
         w->numavail--;
         if (w->numavail == 0 && w->numworker < FUSE_MAX_WORKERS) {
             if (w->numworker < FUSE_MAX_WORKERS) {
@@ -117,7 +122,6 @@
         return -1;
     }
 
-    pthread_detach(*thread_id);
     return 0;
 }
 
@@ -153,7 +157,10 @@
     pthread_mutex_lock(&w->lock);
     for (i = 1; i < w->numworker; i++)
         pthread_cancel(w->threads[i]);
+    w->exit = 1;
     pthread_mutex_unlock(&w->lock);
+    for (i = 1; i < w->numworker; i++)
+        pthread_join(w->threads[i], NULL);
     pthread_mutex_destroy(&w->lock);
     err = w->error;
     fuse_chan_destroy(w->ch);