diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ovsdb-idl.c | 35 | ||||
-rw-r--r-- | lib/ovsdb-idl.h | 2 |
2 files changed, 35 insertions, 2 deletions
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index ed4eddc55..3dbf0f7c9 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -3918,7 +3918,27 @@ ovsdb_idl_loop_run(struct ovsdb_idl_loop *loop) return loop->open_txn; } -void +/* Attempts to commit the current transaction, if one is open, and sets up the + * poll loop to wake up when some more work might be needed. + * + * If a transaction was open, in this or a previous iteration of the main loop, + * and had not before finished committing (successfully or unsuccessfully), the + * return value is one of: + * + * 1: The transaction committed successfully (or it did not change anything in + * the database). + * 0: The transaction failed. + * -1: The commit is still in progress. + * + * Thus, the return value is -1 if the transaction is in progress and otherwise + * true for success, false for failure. + * + * (In the corner case where the IDL sends a transaction to the database and + * the database commits it, and the connection between the IDL and the database + * drops before the IDL receives the message confirming the commit, this + * function can return 0 even though the transaction succeeded.) + */ +int ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *loop) { if (loop->open_txn) { @@ -3929,6 +3949,7 @@ ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *loop) } struct ovsdb_idl_txn *txn = loop->committing_txn; + int retval; if (txn) { enum ovsdb_idl_txn_status status = ovsdb_idl_txn_commit(txn); if (status != TXN_INCOMPLETE) { @@ -3941,32 +3962,44 @@ ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *loop) if (ovsdb_idl_get_seqno(loop->idl) != loop->skip_seqno) { poll_immediate_wake(); } + retval = 0; break; case TXN_SUCCESS: /* Possibly some work on the database was deferred because no * further transaction could proceed. Wake up again. */ + retval = 1; loop->cur_cfg = loop->next_cfg; poll_immediate_wake(); break; case TXN_UNCHANGED: + retval = 1; loop->cur_cfg = loop->next_cfg; break; case TXN_ABORTED: case TXN_NOT_LOCKED: case TXN_ERROR: + retval = 0; break; case TXN_UNCOMMITTED: case TXN_INCOMPLETE: + default: OVS_NOT_REACHED(); } ovsdb_idl_txn_destroy(txn); loop->committing_txn = NULL; + } else { + retval = -1; } + } else { + /* Not a meaningful return value: no transaction was in progress. */ + retval = 1; } ovsdb_idl_wait(loop->idl); + + return retval; } diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h index 81365861f..28fe37474 100644 --- a/lib/ovsdb-idl.h +++ b/lib/ovsdb-idl.h @@ -315,7 +315,7 @@ struct ovsdb_idl_loop { void ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *); struct ovsdb_idl_txn *ovsdb_idl_loop_run(struct ovsdb_idl_loop *); -void ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *); +int ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *); /* Conditional Replication * ======================= |