src/dbfs/trans.c
changeset 56 9dfc861273e5
parent 42 40a3b13ffc9d
child 57 527d23bf6441
equal deleted inserted replaced
42:40a3b13ffc9d 56:9dfc861273e5
     1 
       
     2 #include <stdlib.h>
       
     3 #include <assert.h>
       
     4 
       
     5 #include "trans.h"
       
     6 #include "../lib/log.h"
       
     7 
       
     8 void dbfs_trans_free (struct dbfs_trans *ctx) {
       
     9     assert(!ctx->req);
       
    10     assert(!ctx->trans);
       
    11     
       
    12     if (ctx->free_fn)
       
    13         ctx->free_fn(ctx);
       
    14 
       
    15     free(ctx);
       
    16 }
       
    17 
       
    18 void dbfs_trans_fail (struct dbfs_trans *ctx, int err) {
       
    19     if (ctx->req) {
       
    20         if ((err = fuse_reply_err(ctx->req, err)))
       
    21             EWARNING(err, "fuse_reply_err: request hangs");
       
    22 
       
    23         ctx->req = NULL;
       
    24     }
       
    25 
       
    26     if (ctx->trans) {
       
    27         evsql_trans_abort(ctx->trans);
       
    28 
       
    29         ctx->trans = NULL;
       
    30     }
       
    31 
       
    32     dbfs_trans_free(ctx);
       
    33 }
       
    34 
       
    35 static void dbfs_trans_error (struct evsql_trans *trans, void *arg) {
       
    36     struct dbfs_trans *ctx = arg;
       
    37 
       
    38     // deassociate trans
       
    39     ctx->trans = NULL;
       
    40 
       
    41     // log error
       
    42     INFO("\t[dbfs_trans.err %p:%p] %s", ctx, ctx->req, evsql_trans_error(trans));
       
    43 
       
    44     // mark
       
    45     if (ctx->err_ptr)
       
    46         *ctx->err_ptr = EIO;
       
    47     
       
    48     // fail
       
    49     dbfs_trans_fail(ctx, EIO);
       
    50 }
       
    51 
       
    52 static void dbfs_trans_ready (struct evsql_trans *trans, void *arg) {
       
    53     struct dbfs_trans *ctx = arg;
       
    54 
       
    55     // associate trans
       
    56     ctx->trans = trans;
       
    57 
       
    58     // log
       
    59     INFO("\t[dbfs_trans.ready %p:%p] -> trans=%p", ctx, ctx->req, trans);
       
    60 
       
    61     // trigger the callback
       
    62     ctx->begin_fn(ctx);
       
    63 }
       
    64 
       
    65 static void dbfs_trans_done (struct evsql_trans *trans, void *arg) {
       
    66     struct dbfs_trans *ctx = arg;
       
    67 
       
    68     // deassociate trans
       
    69     ctx->trans = NULL;
       
    70 
       
    71     // log
       
    72     INFO("\t[dbfs_trans.done %p:%p]", ctx, ctx->req);
       
    73 
       
    74     // trigger the callback
       
    75     ctx->commit_fn(ctx);
       
    76 }
       
    77 
       
    78 int dbfs_trans_init (struct dbfs_trans *ctx, struct fuse_req *req) {
       
    79     struct dbfs *dbfs_ctx = fuse_req_userdata(req);
       
    80     int err;
       
    81 
       
    82     // store
       
    83     ctx->req = req;
       
    84 
       
    85     // trans
       
    86     if ((ctx->trans = evsql_trans(dbfs_ctx->db, EVSQL_TRANS_SERIALIZABLE, dbfs_trans_error, dbfs_trans_ready, dbfs_trans_done, ctx)) == NULL)
       
    87         EERROR(err = EIO, "evsql_trans");
       
    88 
       
    89     // good
       
    90     return 0;
       
    91 
       
    92 error:
       
    93     return -1;
       
    94 }
       
    95 
       
    96 struct dbfs_trans *dbfs_trans_new (struct fuse_req *req) {
       
    97     struct dbfs_trans *ctx = NULL;
       
    98 
       
    99     // alloc
       
   100     if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
       
   101         ERROR("calloc");
       
   102 
       
   103     // init
       
   104     if (dbfs_trans_init(ctx, req))
       
   105         goto error;
       
   106 
       
   107     // good
       
   108     return ctx;
       
   109     
       
   110 error:
       
   111     free(ctx);
       
   112 
       
   113     return NULL;
       
   114 }
       
   115 
       
   116 void dbfs_trans_commit (struct dbfs_trans *ctx) {
       
   117     int err, trans_err = 0;
       
   118 
       
   119     // detect errors
       
   120     ctx->err_ptr = &trans_err;
       
   121     
       
   122     // attempt commit
       
   123     if (evsql_trans_commit(ctx->trans))
       
   124         SERROR(err = EIO);
       
   125     
       
   126     // drop err_ptr
       
   127     ctx->err_ptr = NULL;
       
   128 
       
   129     // ok, wait for done or error
       
   130     return;
       
   131 
       
   132 error:
       
   133     // fail if not already failed
       
   134     if (!trans_err)
       
   135         dbfs_trans_fail(ctx, err);
       
   136 }
       
   137 
       
   138