aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--include/fuse_lowlevel.h12
-rw-r--r--lib/fuse_i.h2
-rwxr-xr-xlib/fuse_lowlevel.c3
-rw-r--r--lib/fuse_session.c31
-rw-r--r--lib/helper.c3
6 files changed, 47 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c1c267..8a65763 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-23 Miklos Szeredi <miklos@szeredi.hu>
+
+ * libfuse: refcount fuse_chan objects. New functions:
+ fuse_chan_get(), fuse_chan_put(). Removed function:
+ fuse_chan_destroy().
+
2015-04-23 Miklos Szeredi <miklos@szeredi.hu>
* libfuse: add FUSE_CAP_NO_OPEN_SUPPORT flag to ->init()
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 20e7692..3cc9db5 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1705,11 +1705,19 @@ int fuse_session_loop_mt(struct fuse_session *se);
int fuse_chan_fd(struct fuse_chan *ch);
/**
- * Destroy a channel
+ * Obtain counted reference to the channel
+ *
+ * @param ch the channel
+ * @return the channel
+ */
+struct fuse_chan *fuse_chan_get(struct fuse_chan *ch);
+
+/**
+ * Drop counted reference to a channel
*
* @param ch the channel
*/
-void fuse_chan_destroy(struct fuse_chan *ch);
+void fuse_chan_put(struct fuse_chan *ch);
#ifdef __cplusplus
}
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 4bbcbd6..16adc69 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -23,6 +23,8 @@ struct fuse_session {
struct fuse_chan {
struct fuse_session *se;
+ pthread_mutex_t lock;
+ int ctr;
int fd;
};
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index f25d56f..e70733a 100755
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -2735,8 +2735,7 @@ static void fuse_ll_destroy(struct fuse_ll *f)
void fuse_session_destroy(struct fuse_session *se)
{
fuse_ll_destroy(se->f);
- if (se->ch != NULL)
- fuse_chan_destroy(se->ch);
+ fuse_chan_put(se->ch);
free(se);
}
diff --git a/lib/fuse_session.c b/lib/fuse_session.c
index e919e73..42fe5c3 100644
--- a/lib/fuse_session.c
+++ b/lib/fuse_session.c
@@ -84,6 +84,8 @@ struct fuse_chan *fuse_chan_new(int fd)
memset(ch, 0, sizeof(*ch));
ch->fd = fd;
+ ch->ctr = 1;
+ fuse_mutex_init(&ch->lock);
return ch;
}
@@ -98,9 +100,30 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
return ch->se;
}
-void fuse_chan_destroy(struct fuse_chan *ch)
+struct fuse_chan *fuse_chan_get(struct fuse_chan *ch)
{
- fuse_session_remove_chan(ch);
- fuse_chan_close(ch);
- free(ch);
+ assert(ch->ctr > 0);
+ pthread_mutex_lock(&ch->lock);
+ ch->ctr++;
+ pthread_mutex_unlock(&ch->lock);
+
+ return ch;
+}
+
+void fuse_chan_put(struct fuse_chan *ch)
+{
+ if (ch) {
+ pthread_mutex_lock(&ch->lock);
+ ch->ctr--;
+ if (!ch->ctr) {
+ pthread_mutex_unlock(&ch->lock);
+ fuse_session_remove_chan(ch);
+ fuse_chan_close(ch);
+ pthread_mutex_destroy(&ch->lock);
+ free(ch);
+ } else {
+ pthread_mutex_unlock(&ch->lock);
+ }
+
+ }
}
diff --git a/lib/helper.c b/lib/helper.c
index e5550c9..cca21b5 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -243,8 +243,7 @@ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
if (mountpoint) {
int fd = ch ? fuse_chan_clearfd(ch) : -1;
fuse_kern_unmount(mountpoint, fd);
- if (ch)
- fuse_chan_destroy(ch);
+ fuse_chan_put(ch);
}
}