// discard pending transaction
pending_proposal.reset();
- finish_contexts(g_ceph_context, pending_finishers, -EAGAIN);
- finish_contexts(g_ceph_context, committing_finishers, -EAGAIN);
+ reset_pending_committing_finishers();
logger->inc(l_paxos_start_leader);
pending_proposal.reset();
// no chance to write now!
+ reset_pending_committing_finishers();
finish_contexts(g_ceph_context, waiting_for_writeable, -EAGAIN);
- finish_contexts(g_ceph_context, pending_finishers, -EAGAIN);
- finish_contexts(g_ceph_context, committing_finishers, -EAGAIN);
logger->inc(l_paxos_start_peon);
}
// discard pending transaction
pending_proposal.reset();
- finish_contexts(g_ceph_context, committing_finishers, -EAGAIN);
- finish_contexts(g_ceph_context, pending_finishers, -EAGAIN);
+ reset_pending_committing_finishers();
finish_contexts(g_ceph_context, waiting_for_active, -EAGAIN);
logger->inc(l_paxos_restart);
}
+void Paxos::reset_pending_committing_finishers()
+{
+ committing_finishers.splice(committing_finishers.end(), pending_finishers);
+ finish_contexts(g_ceph_context, committing_finishers, -EAGAIN);
+}
void Paxos::dispatch(MonOpRequestRef op)
{
* this list. When it commits, these finishers are notified.
*/
list<Context*> committing_finishers;
+ /**
+ * This function re-triggers pending_ and committing_finishers
+ * safely, so as to maintain existing system invariants. In particular
+ * we maintain ordering by triggering committing before pending, and
+ * we clear out pending_finishers prior to any triggers so that
+ * we don't trigger asserts on them being empty. You should
+ * use it instead of sending -EAGAIN to them with finish_contexts.
+ */
+ void reset_pending_committing_finishers();
/**
* @defgroup Paxos_h_sync_warns Synchronization warnings