18cad15b1SVladimir Sementsov-Ogievskiy /*
28cad15b1SVladimir Sementsov-Ogievskiy * Simple transactions API
38cad15b1SVladimir Sementsov-Ogievskiy *
48cad15b1SVladimir Sementsov-Ogievskiy * Copyright (c) 2021 Virtuozzo International GmbH.
58cad15b1SVladimir Sementsov-Ogievskiy *
68cad15b1SVladimir Sementsov-Ogievskiy * Author:
78cad15b1SVladimir Sementsov-Ogievskiy * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
88cad15b1SVladimir Sementsov-Ogievskiy *
98cad15b1SVladimir Sementsov-Ogievskiy * This program is free software; you can redistribute it and/or modify
108cad15b1SVladimir Sementsov-Ogievskiy * it under the terms of the GNU General Public License as published by
118cad15b1SVladimir Sementsov-Ogievskiy * the Free Software Foundation; either version 2 of the License, or
128cad15b1SVladimir Sementsov-Ogievskiy * (at your option) any later version.
138cad15b1SVladimir Sementsov-Ogievskiy *
148cad15b1SVladimir Sementsov-Ogievskiy * This program is distributed in the hope that it will be useful,
158cad15b1SVladimir Sementsov-Ogievskiy * but WITHOUT ANY WARRANTY; without even the implied warranty of
168cad15b1SVladimir Sementsov-Ogievskiy * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
178cad15b1SVladimir Sementsov-Ogievskiy * GNU General Public License for more details.
188cad15b1SVladimir Sementsov-Ogievskiy *
198cad15b1SVladimir Sementsov-Ogievskiy * You should have received a copy of the GNU General Public License
208cad15b1SVladimir Sementsov-Ogievskiy * along with this program. If not, see <http://www.gnu.org/licenses/>.
218cad15b1SVladimir Sementsov-Ogievskiy *
228cad15b1SVladimir Sementsov-Ogievskiy *
238cad15b1SVladimir Sementsov-Ogievskiy * = Generic transaction API =
248cad15b1SVladimir Sementsov-Ogievskiy *
258cad15b1SVladimir Sementsov-Ogievskiy * The intended usage is the following: you create "prepare" functions, which
268cad15b1SVladimir Sementsov-Ogievskiy * represents the actions. They will usually have Transaction* argument, and
278cad15b1SVladimir Sementsov-Ogievskiy * call tran_add() to register finalization callbacks. For finalization
288cad15b1SVladimir Sementsov-Ogievskiy * callbacks, prepare corresponding TransactionActionDrv structures.
298cad15b1SVladimir Sementsov-Ogievskiy *
308cad15b1SVladimir Sementsov-Ogievskiy * Then, when you need to make a transaction, create an empty Transaction by
318cad15b1SVladimir Sementsov-Ogievskiy * tran_create(), call your "prepare" functions on it, and finally call
328cad15b1SVladimir Sementsov-Ogievskiy * tran_abort() or tran_commit() to finalize the transaction by corresponding
338cad15b1SVladimir Sementsov-Ogievskiy * finalization actions in reverse order.
34*079bff69SHanna Reitz *
35*079bff69SHanna Reitz * The clean() functions registered by the drivers in a transaction are called
36*079bff69SHanna Reitz * last, after all abort() or commit() functions have been called.
378cad15b1SVladimir Sementsov-Ogievskiy */
388cad15b1SVladimir Sementsov-Ogievskiy
398cad15b1SVladimir Sementsov-Ogievskiy #ifndef QEMU_TRANSACTIONS_H
408cad15b1SVladimir Sementsov-Ogievskiy #define QEMU_TRANSACTIONS_H
418cad15b1SVladimir Sementsov-Ogievskiy
428cad15b1SVladimir Sementsov-Ogievskiy #include <gmodule.h>
438cad15b1SVladimir Sementsov-Ogievskiy
448cad15b1SVladimir Sementsov-Ogievskiy typedef struct TransactionActionDrv {
458cad15b1SVladimir Sementsov-Ogievskiy void (*abort)(void *opaque);
468cad15b1SVladimir Sementsov-Ogievskiy void (*commit)(void *opaque);
478cad15b1SVladimir Sementsov-Ogievskiy void (*clean)(void *opaque);
488cad15b1SVladimir Sementsov-Ogievskiy } TransactionActionDrv;
498cad15b1SVladimir Sementsov-Ogievskiy
508cad15b1SVladimir Sementsov-Ogievskiy typedef struct Transaction Transaction;
518cad15b1SVladimir Sementsov-Ogievskiy
528cad15b1SVladimir Sementsov-Ogievskiy Transaction *tran_new(void);
538cad15b1SVladimir Sementsov-Ogievskiy void tran_add(Transaction *tran, TransactionActionDrv *drv, void *opaque);
548cad15b1SVladimir Sementsov-Ogievskiy void tran_abort(Transaction *tran);
558cad15b1SVladimir Sementsov-Ogievskiy void tran_commit(Transaction *tran);
568cad15b1SVladimir Sementsov-Ogievskiy
tran_finalize(Transaction * tran,int ret)578cad15b1SVladimir Sementsov-Ogievskiy static inline void tran_finalize(Transaction *tran, int ret)
588cad15b1SVladimir Sementsov-Ogievskiy {
598cad15b1SVladimir Sementsov-Ogievskiy if (ret < 0) {
608cad15b1SVladimir Sementsov-Ogievskiy tran_abort(tran);
618cad15b1SVladimir Sementsov-Ogievskiy } else {
628cad15b1SVladimir Sementsov-Ogievskiy tran_commit(tran);
638cad15b1SVladimir Sementsov-Ogievskiy }
648cad15b1SVladimir Sementsov-Ogievskiy }
658cad15b1SVladimir Sementsov-Ogievskiy
668cad15b1SVladimir Sementsov-Ogievskiy #endif /* QEMU_TRANSACTIONS_H */
67