src/dbfs/interrupt.c
changeset 56 9dfc861273e5
parent 42 40a3b13ffc9d
child 57 527d23bf6441
equal deleted inserted replaced
42:40a3b13ffc9d 56:9dfc861273e5
     1 
       
     2 #include "dbfs.h"
       
     3 
       
     4 void _dbfs_interrupt_reply (evutil_socket_t _unused1, short _unused2, void *req_ptr) {
       
     5     struct fuse_req *req = req_ptr;
       
     6     err_t err;
       
     7     
       
     8     // error the req
       
     9     if ((err = -fuse_reply_err(req, EINTR)))
       
    10         EWARNING(err, "fuse_reply_err");
       
    11 }
       
    12 
       
    13 void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr) {
       
    14     struct dbfs *ctx = fuse_req_userdata(req);
       
    15     struct evsql_query *query = query_ptr;
       
    16     struct timeval tv;
       
    17     err_t err;
       
    18 
       
    19     // abort query
       
    20     evsql_query_abort(NULL, query);
       
    21     
       
    22     /*
       
    23      * 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
       
    24      * schedule after this function returns.
       
    25      */
       
    26     tv.tv_sec = 0;
       
    27     tv.tv_usec = 0;
       
    28     if (event_base_once(ctx->ev_base, -1, EV_TIMEOUT, _dbfs_interrupt_reply, req, &tv))
       
    29         PWARNING("event_base_once failed, dropping req reply: %p", req);
       
    30 }
       
    31 
       
    32 void _dbfs_interrupt_ctx (struct fuse_req *req, void *ctx_ptr) {
       
    33     // dereference ctx
       
    34     struct dbfs_interrupt_ctx *ctx = ctx_ptr;
       
    35     
       
    36     // just cancel query if pending
       
    37     if (ctx->query) {
       
    38         evsql_query_abort(NULL, ctx->query);
       
    39         ctx->query = NULL;
       
    40     }
       
    41 
       
    42     // mark as interrupted
       
    43     ctx->interrupted = 1;
       
    44 }
       
    45 
       
    46 int dbfs_interrupt_register (struct fuse_req *req, struct dbfs_interrupt_ctx *ctx) {
       
    47     // initialize
       
    48     ctx->query = NULL;
       
    49     ctx->interrupted = 0;
       
    50 
       
    51     // just pass over to fuse_req_interrupt_func
       
    52     fuse_req_interrupt_func(req, _dbfs_interrupt_ctx, ctx);
       
    53 }