Changeset: 13ac9088b87e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=13ac9088b87e
Modified Files:
sql/storage/objectset.c
Branch: default
Log Message:
Fix race condition between rollback and cleanup.
diffs (86 lines):
diff --git a/sql/storage/objectset.c b/sql/storage/objectset.c
--- a/sql/storage/objectset.c
+++ b/sql/storage/objectset.c
@@ -331,34 +331,53 @@ static void
state |= rollbacked;
os_atmc_set_state(ov, state);
- if (ov->name_based_older && !(os_atmc_get_state(ov->name_based_older) &
rollbacked)) {
- if (ov->ts != ov->name_based_older->ts) {
+ bte state_older;
+
+ // TODO ATOMIC GET
+ objectversion* name_based_older = ov->name_based_older;
+ if (name_based_older && !((state_older=
os_atmc_get_state(name_based_older)) & rollbacked)) {
+ if (ov->ts != name_based_older->ts) {
// older is last committed state or belongs to parent
transaction.
// In any case, we restore versionhead pointer to that.
- // TODO START ATOMIC SET
- ov->name_based_head->ov = ov->name_based_older;
+
+ ATOMIC_BASE_TYPE expected_deleted = deleted;
+ if (state_older == active || (state_older == deleted &&
ATOMIC_CAS(&name_based_older->state, &expected_deleted, block_destruction))) {
+ ov->name_based_head->ov = name_based_older;
+ name_based_older->name_based_newer=NULL;
+ if (state_older != active && expected_deleted
== deleted)
+ os_atmc_set_state(name_based_older,
deleted); //Restore the deleted older back to its deleted state.
+ }
}
else {
- _os_rollback(ov->name_based_older, store);
+ _os_rollback(name_based_older, store);
}
}
- else if (!ov->name_based_older) {
+ else if (!name_based_older) {
// this is a terminal node. i.e. this objectversion does not
have name based committed history
if (ov->name_based_head) // The oposite can happen during an
early conflict in os_add or os_del.
os_remove_name_based_chain(ov->os, store,
ov->name_based_head);
}
- if (ov->id_based_older && !(os_atmc_get_state(ov->id_based_older) &
rollbacked)) {
- if (ov->ts != ov->id_based_older->ts) {
+ // TODO ATOMIC GET
+ objectversion* id_based_older = ov->id_based_older;
+ if (id_based_older && !((state_older=
os_atmc_get_state(id_based_older)) & rollbacked)) {
+ if (ov->ts != id_based_older->ts) {
// older is last committed state or belongs to parent
transaction.
// In any case, we restore versionhead pointer to that.
// TODO START ATOMIC SET
- ov->id_based_head->ov = ov->id_based_older;
+
+ ATOMIC_BASE_TYPE expected_deleted = deleted;
+ if (state_older == active || (state_older == deleted &&
ATOMIC_CAS(&id_based_older->state, &expected_deleted, block_destruction))) {
+ ov->id_based_head->ov = id_based_older;
+ id_based_older->id_based_newer=NULL;
+ if (state_older != active && expected_deleted
== deleted)
+ os_atmc_set_state(id_based_older,
deleted); //Restore the deleted older back to its deleted state.
+ }
}
- else if (ov->id_based_older != ov->name_based_older)
- _os_rollback(ov->id_based_older, store);
+ else if (id_based_older != name_based_older)
+ _os_rollback(id_based_older, store);
}
- else if (!ov->id_based_older) {
+ else if (!id_based_older) {
// this is a terminal node. i.e. this objectversion does not
have id based committed history
os_remove_id_based_chain(ov->os, store, ov->id_based_head);
}
@@ -386,14 +405,14 @@ try_to_mark_deleted_for_destruction(sqls
ATOMIC_BASE_TYPE expected_deleted = deleted;
if (ATOMIC_CAS(&ov->state, &expected_deleted, under_destruction)) {
- if (!ov->name_based_newer ||
(os_atmc_get_state(ov->name_based_newer) & rollbacked)) { // TODO: This gives
race conditions with os_rollback.
+ if (!ov->name_based_newer ||
(os_atmc_get_state(ov->name_based_newer) & rollbacked)) {
os_remove_name_based_chain(ov->os, store,
ov->name_based_head);
}
else {
ov->name_based_newer->name_based_older = NULL;
}
- if (!ov->id_based_newer ||
(os_atmc_get_state(ov->id_based_newer) & rollbacked)) { // TODO: This gives
race conditions with os_rollback.
+ if (!ov->id_based_newer ||
(os_atmc_get_state(ov->id_based_newer) & rollbacked)) {
os_remove_id_based_chain(ov->os, store,
ov->id_based_head);
}
else {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list