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