diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | include/fuse_lowlevel.h | 12 | ||||
-rw-r--r-- | lib/fuse_i.h | 2 | ||||
-rwxr-xr-x | lib/fuse_lowlevel.c | 3 | ||||
-rw-r--r-- | lib/fuse_session.c | 31 | ||||
-rw-r--r-- | lib/helper.c | 3 |
6 files changed, 47 insertions, 10 deletions
@@ -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); } } |