From: Miklos Szeredi Date: Mon, 18 May 2015 14:55:20 +0000 (+0200) Subject: libfuse: refcount fuse_chan objects X-Git-Tag: fuse-3.0.0pre0~70^2~2 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=1344908b6ce8b26ce9ff6e6269348eec904e14dc;p=qemu-gpiodev%2Flibfuse.git libfuse: refcount fuse_chan objects New functions: fuse_chan_get(), fuse_chan_put(). Removed function: fuse_chan_destroy(). --- diff --git a/ChangeLog b/ChangeLog index 5c1c267..8a65763 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-05-23 Miklos Szeredi + + * libfuse: refcount fuse_chan objects. New functions: + fuse_chan_get(), fuse_chan_put(). Removed function: + fuse_chan_destroy(). + 2015-04-23 Miklos Szeredi * 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); } }