qemu/util/transactions.c
<<
>>
Prefs
   1/*
   2 * Simple transactions API
   3 *
   4 * Copyright (c) 2021 Virtuozzo International GmbH.
   5 *
   6 * Author:
   7 *  Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 */
  22
  23#include "qemu/osdep.h"
  24
  25#include "qemu/transactions.h"
  26#include "qemu/queue.h"
  27
  28typedef struct TransactionAction {
  29    TransactionActionDrv *drv;
  30    void *opaque;
  31    QSLIST_ENTRY(TransactionAction) entry;
  32} TransactionAction;
  33
  34struct Transaction {
  35    QSLIST_HEAD(, TransactionAction) actions;
  36};
  37
  38Transaction *tran_new(void)
  39{
  40    Transaction *tran = g_new(Transaction, 1);
  41
  42    QSLIST_INIT(&tran->actions);
  43
  44    return tran;
  45}
  46
  47void tran_add(Transaction *tran, TransactionActionDrv *drv, void *opaque)
  48{
  49    TransactionAction *act;
  50
  51    act = g_new(TransactionAction, 1);
  52    *act = (TransactionAction) {
  53        .drv = drv,
  54        .opaque = opaque
  55    };
  56
  57    QSLIST_INSERT_HEAD(&tran->actions, act, entry);
  58}
  59
  60void tran_abort(Transaction *tran)
  61{
  62    TransactionAction *act, *next;
  63
  64    QSLIST_FOREACH(act, &tran->actions, entry) {
  65        if (act->drv->abort) {
  66            act->drv->abort(act->opaque);
  67        }
  68    }
  69
  70    QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
  71        if (act->drv->clean) {
  72            act->drv->clean(act->opaque);
  73        }
  74
  75        g_free(act);
  76    }
  77
  78    g_free(tran);
  79}
  80
  81void tran_commit(Transaction *tran)
  82{
  83    TransactionAction *act, *next;
  84
  85    QSLIST_FOREACH(act, &tran->actions, entry) {
  86        if (act->drv->commit) {
  87            act->drv->commit(act->opaque);
  88        }
  89    }
  90
  91    QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
  92        if (act->drv->clean) {
  93            act->drv->clean(act->opaque);
  94        }
  95
  96        g_free(act);
  97    }
  98
  99    g_free(tran);
 100}
 101