defer fuse_reply_err using event_base_once, interrupt happens without deadlock now default
authorTero Marttila <terom@fixme.fi>
Tue, 18 Nov 2008 02:06:52 +0200
changeset 42 40a3b13ffc9d
parent 41 6abda2fa4579
child 43 5776ace903b5
defer fuse_reply_err using event_base_once, interrupt happens without deadlock now
src/dbfs/dbfs.h
src/dbfs/interrupt.c
--- a/src/dbfs/dbfs.h	Tue Nov 18 01:55:13 2008 +0200
+++ b/src/dbfs/dbfs.h	Tue Nov 18 02:06:52 2008 +0200
@@ -81,6 +81,8 @@
 
 /*
  * Useable as a callback to fuse_req_interrupt_func, will abort the given query and err the req.
+ *
+ * Due to a locking bug in libfuse 2.7.4, this will actually delay the fuse_req_err until the next event-loop iteration.
  */
 void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr);
 
--- a/src/dbfs/interrupt.c	Tue Nov 18 01:55:13 2008 +0200
+++ b/src/dbfs/interrupt.c	Tue Nov 18 02:06:52 2008 +0200
@@ -1,16 +1,32 @@
 
 #include "dbfs.h"
 
+void _dbfs_interrupt_reply (evutil_socket_t _unused1, short _unused2, void *req_ptr) {
+    struct fuse_req *req = req_ptr;
+    err_t err;
+    
+    // error the req
+    if ((err = -fuse_reply_err(req, EINTR)))
+        EWARNING(err, "fuse_reply_err");
+}
+
 void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr) {
+    struct dbfs *ctx = fuse_req_userdata(req);
     struct evsql_query *query = query_ptr;
+    struct timeval tv;
     err_t err;
 
-    // abort
+    // abort query
     evsql_query_abort(NULL, query);
-
-    // error the req
-    if ((err = -fuse_reply_err(req, EINTR)))
-        PWARNING("fuse_reply_err", err);
+    
+    /*
+     * Due to a locking bug in libfuse (at least 2.7.4), we can't call fuse_reply_err from the interrupt function, so we must
+     * schedule after this function returns.
+     */
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+    if (event_base_once(ctx->ev_base, -1, EV_TIMEOUT, _dbfs_interrupt_reply, req, &tv))
+        PWARNING("event_base_once failed, dropping req reply: %p", req);
 }
 
 void _dbfs_interrupt_ctx (struct fuse_req *req, void *ctx_ptr) {