+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()
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
}
struct fuse_chan {
struct fuse_session *se;
+ pthread_mutex_t lock;
+ int ctr;
int fd;
};
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);
}
memset(ch, 0, sizeof(*ch));
ch->fd = fd;
+ ch->ctr = 1;
+ fuse_mutex_init(&ch->lock);
return 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);
+ }
+
+ }
}
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);
}
}