fix
diff --git a/ChangeLog b/ChangeLog
index 891dfd9..c3fc2d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-22  Miklos Szeredi <miklos@szeredi.hu>
+
+	* A slight API change: fuse_get_context() doesn't need the "fuse"
+	pointer, but the returned context contains it instead.  The
+	fuse_get() function is not needed anymore, so it's removed.
+	
 2004-09-21  Miklos Szeredi <miklos@szeredi.hu>
 
 	* Fix deadlock in case of memory allocation failure.  Patch by
diff --git a/include/fuse.h b/include/fuse.h
index 81ef0d4..22de11b 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -133,6 +133,7 @@
 
 /** Extra context that may be needed by some filesystems */
 struct fuse_context {
+    struct fuse *fuse;
     uid_t uid;
     gid_t gid;
 };
@@ -162,15 +163,6 @@
  */
 void fuse_main(int argc, char *argv[], const struct fuse_operations *op);
 
-/*
- * Returns the fuse object created by fuse_main()
- * 
- * This is useful when fuse_get_context() is used.
- *
- * @return the fuse object
- */
-struct fuse *fuse_get(void);
-
 /**
  * Invalidate cached data of a file.
  *
@@ -266,7 +258,7 @@
  * @param f the FUSE handle
  * @return the context 
  */
-struct fuse_context *fuse_get_context(struct fuse *f);
+struct fuse_context *fuse_get_context(void);
 
 /**
  * Check whether a mount option should be passed to the kernel or the
@@ -288,6 +280,7 @@
 void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd);
 int __fuse_loop_mt(struct fuse *f, fuse_processor_t proc, void *data);
 int __fuse_exited(struct fuse* f);
+void __fuse_set_getcontext_func(struct fuse_context *(*func)(void));
 
 #ifdef __cplusplus
 }
diff --git a/lib/fuse.c b/lib/fuse.c
index a4d547a..fae68a1 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -23,6 +23,8 @@
 #define ENTRY_REVALIDATE_TIME 1 /* sec */
 #define ATTR_REVALIDATE_TIME 1 /* sec */
 
+static struct fuse_context *(*fuse_getcontext)(void) = NULL;
+
 static const char *opname(enum fuse_opcode opcode)
 {
     switch (opcode) { 
@@ -1428,7 +1430,7 @@
     struct fuse_in_header *in = (struct fuse_in_header *) cmd->buf;
     void *inarg = cmd->buf + sizeof(struct fuse_in_header);
     size_t argsize;
-    struct fuse_context *ctx = fuse_get_context(f);
+    struct fuse_context *ctx = fuse_get_context();
 
     dec_avail(f);
 
@@ -1439,6 +1441,7 @@
         fflush(stdout);
     }
 
+    ctx->fuse = f;
     ctx->uid = in->uid;
     ctx->gid = in->gid;
     
@@ -1664,12 +1667,18 @@
     f->exited = 1;
 }
 
-struct fuse_context *fuse_get_context(struct fuse *f)
+struct fuse_context *fuse_get_context()
 {
-    if (f->getcontext)
-        return f->getcontext(f);
+    static struct fuse_context context;
+    if (fuse_getcontext)
+        return fuse_getcontext();
     else
-        return &f->context;
+        return &context;
+}
+
+void __fuse_set_getcontext_func(struct fuse_context *(*func)(void))
+{
+    fuse_getcontext = func;
 }
 
 static int check_version(struct fuse *f)
@@ -1769,9 +1778,6 @@
     f->numworker = 0;
     f->numavail = 0;
     f->op = *op;
-    f->getcontext = NULL;
-    f->context.uid = 0;
-    f->context.gid = 0;
     f->exited = 0;
 
     root = (struct node *) calloc(1, sizeof(struct node));
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 3817062..c1aaa4c 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -51,9 +51,6 @@
     pthread_mutex_t lock;
     int numworker;
     int numavail;
-    struct fuse_context *(*getcontext)(struct fuse *);
-    struct fuse_context context;
-    pthread_key_t context_key;
     volatile int exited;
     int majorver;
     int minorver;
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index 8bac5ff..345da33 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -25,6 +25,10 @@
     fuse_processor_t proc;
 };
 
+static pthread_key_t context_key;
+static pthread_mutex_t context_lock = PTHREAD_MUTEX_INITIALIZER;
+static int context_ref;
+
 static int start_thread(struct fuse_worker *w, pthread_t *thread_id);
 
 static void *do_work(void *data)
@@ -41,7 +45,7 @@
         pthread_mutex_unlock(&f->lock);
         return NULL;
     }
-    pthread_setspecific(f->context_key, ctx);
+    pthread_setspecific(context_key, ctx);
 
     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
@@ -94,7 +98,7 @@
     res = pthread_create(thread_id, NULL, do_work, w);
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
     if (res != 0) {
-        fprintf(stderr, "Error creating thread: %s\n", strerror(res));
+        fprintf(stderr, "fuse: error creating thread: %s\n", strerror(res));
         return -1;
     }
     
@@ -102,9 +106,14 @@
     return 0;
 }
 
-static struct fuse_context *mt_getcontext(struct fuse *f)
+static struct fuse_context *mt_getcontext(void)
 {
-    return (struct fuse_context *) pthread_getspecific(f->context_key);
+    struct fuse_context *ctx =
+        (struct fuse_context *) pthread_getspecific(context_key);
+    if (ctx == NULL)
+        fprintf(stderr, "fuse: no thread specific data for this thread\n");
+
+    return ctx;
 }
 
 static void mt_freecontext(void *data)
@@ -112,10 +121,38 @@
     free(data);
 }
 
+static int mt_create_context_key()
+{
+    int err = 0;
+    pthread_mutex_lock(&context_lock);
+    if (!context_ref) {
+        err = pthread_key_create(&context_key, mt_freecontext);
+        if (err)
+            fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
+                    strerror(err));
+        else 
+            __fuse_set_getcontext_func(mt_getcontext);
+    }
+    if (!err)
+        context_ref ++;
+    pthread_mutex_unlock(&context_lock);
+    return err;
+}
+
+static void mt_delete_context_key()
+{
+    pthread_mutex_lock(&context_lock);
+    context_ref--;
+    if (!context_ref) {
+        __fuse_set_getcontext_func(NULL);
+        pthread_key_delete(context_key);
+    }
+    pthread_mutex_unlock(&context_lock);
+}
+
 int __fuse_loop_mt(struct fuse *f, fuse_processor_t proc, void *data)
 {
     struct fuse_worker *w;
-    int res;
     int i;
 
     w = malloc(sizeof(struct fuse_worker));    
@@ -128,20 +165,18 @@
     w->data = data;
     w->proc = proc;
 
-    f->numworker = 1;
-    res = pthread_key_create(&f->context_key, mt_freecontext);
-    if (res != 0) {
-        fprintf(stderr, "Failed to create thread specific key\n");
+    if (mt_create_context_key() != 0) {
+        free(w);
         return -1;
     }
-    f->getcontext = mt_getcontext;
+    f->numworker = 1;
     do_work(w);
 
     pthread_mutex_lock(&f->lock);
     for (i = 1; i < f->numworker; i++)
         pthread_cancel(w->threads[i]);
     pthread_mutex_unlock(&f->lock);
-    pthread_key_delete(f->context_key);
+    mt_delete_context_key();
     free(w);
     return 0;
 }
diff --git a/lib/helper.c b/lib/helper.c
index b9e8150..6031c5f 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -17,11 +17,6 @@
 
 static struct fuse *fuse;
 
-struct fuse *fuse_get(void)
-{
-    return fuse;
-}
-
 static void usage(char *progname)
 {
     fprintf(stderr,