aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <mszeredi@suse.cz>2015-05-18 16:55:20 +0200
committerGravatar Miklos Szeredi <mszeredi@suse.cz>2015-05-18 16:55:20 +0200
commit1344908b6ce8b26ce9ff6e6269348eec904e14dc (patch)
tree770018c536b780498ed7c856e686907d5944d884 /lib
parent04ad73fab6ed679941958ed155169ba4146f719e (diff)
libfuse: refcount fuse_chan objects
New functions: fuse_chan_get(), fuse_chan_put(). Removed function: fuse_chan_destroy().
Diffstat (limited to 'lib')
-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
4 files changed, 31 insertions, 8 deletions
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);
}
}