terom@41: terom@41: #include "dbfs.h" terom@41: terom@42: void _dbfs_interrupt_reply (evutil_socket_t _unused1, short _unused2, void *req_ptr) { terom@42: struct fuse_req *req = req_ptr; terom@42: err_t err; terom@42: terom@42: // error the req terom@42: if ((err = -fuse_reply_err(req, EINTR))) terom@42: EWARNING(err, "fuse_reply_err"); terom@42: } terom@42: terom@41: void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr) { terom@42: struct dbfs *ctx = fuse_req_userdata(req); terom@41: struct evsql_query *query = query_ptr; terom@42: struct timeval tv; terom@41: err_t err; terom@41: terom@42: // abort query terom@41: evsql_query_abort(NULL, query); terom@44: terom@44: // error the req terom@44: if ((err = -fuse_reply_err(req, EINTR))) terom@44: EWARNING(err, "fuse_reply_err"); terom@42: terom@42: /* terom@42: * 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 terom@42: * schedule after this function returns. terom@44: * / terom@42: tv.tv_sec = 0; terom@42: tv.tv_usec = 0; terom@42: if (event_base_once(ctx->ev_base, -1, EV_TIMEOUT, _dbfs_interrupt_reply, req, &tv)) terom@42: PWARNING("event_base_once failed, dropping req reply: %p", req); terom@44: */ terom@41: } terom@41: terom@41: void _dbfs_interrupt_ctx (struct fuse_req *req, void *ctx_ptr) { terom@41: // dereference ctx terom@41: struct dbfs_interrupt_ctx *ctx = ctx_ptr; terom@41: terom@41: // just cancel query if pending terom@41: if (ctx->query) { terom@41: evsql_query_abort(NULL, ctx->query); terom@41: ctx->query = NULL; terom@41: } terom@41: terom@41: // mark as interrupted terom@41: ctx->interrupted = 1; terom@41: } terom@41: terom@41: int dbfs_interrupt_register (struct fuse_req *req, struct dbfs_interrupt_ctx *ctx) { terom@41: // initialize terom@41: ctx->query = NULL; terom@41: ctx->interrupted = 0; terom@41: terom@41: // just pass over to fuse_req_interrupt_func terom@41: fuse_req_interrupt_func(req, _dbfs_interrupt_ctx, ctx); terom@41: }