/**
* Helper for simple callbacks that call a void fn with no args.
*/
-class C_VoidFn : public MDSInternalContext
+class C_MDS_VoidFn : public MDSInternalContext
{
typedef void (MDSRank::*fn_ptr)();
protected:
fn_ptr fn;
public:
- C_VoidFn(MDSRank *mds_, fn_ptr fn_)
+ C_MDS_VoidFn(MDSRank *mds_, fn_ptr fn_)
: MDSInternalContext(mds_), fn(fn_)
{
assert(mds_);
reopen_log();
- mdcache->resolve_start(new C_VoidFn(this, &MDSRank::resolve_done));
+ mdcache->resolve_start(new C_MDS_VoidFn(this, &MDSRank::resolve_done));
finish_contexts(g_ceph_context, waiting_for_resolve);
}
void MDSRank::resolve_done()
reopen_log();
}
- server->reconnect_clients(new C_VoidFn(this, &MDSRank::reconnect_done));
+ server->reconnect_clients(new C_MDS_VoidFn(this, &MDSRank::reconnect_done));
finish_contexts(g_ceph_context, waiting_for_reconnect);
}
void MDSRank::reconnect_done()
void MDSRank::rejoin_start()
{
dout(1) << "rejoin_start" << dendl;
- mdcache->rejoin_start(new C_VoidFn(this, &MDSRank::rejoin_done));
+ mdcache->rejoin_start(new C_MDS_VoidFn(this, &MDSRank::rejoin_done));
}
void MDSRank::rejoin_done()
{
{
dout(3) << "boot_create" << dendl;
- MDSGatherBuilder fin(g_ceph_context, new C_VoidFn(this, &MDSRank::creating_done));
+ MDSGatherBuilder fin(g_ceph_context, new C_MDS_VoidFn(this, &MDSRank::creating_done));
mdcache->init_layouts();
// -- wait --
+ const static uint64_t WAIT_ORDERED = (1ull<<61);
const static uint64_t WAIT_SINGLEAUTH = (1ull<<60);
const static uint64_t WAIT_UNFREEZE = (1ull<<59); // pka AUTHPINNABLE
// ---------------------------------------------
// waiting
protected:
- compact_multimap<uint64_t, MDSInternalContextBase*> waiting;
+ compact_multimap<uint64_t, pair<uint64_t, MDSInternalContextBase*> > waiting;
+ static uint64_t last_wait_seq;
public:
bool is_waiter_for(uint64_t mask, uint64_t min=0) {
while (min & (min-1)) // if more than one bit is set
min &= min-1; // clear LSB
}
- for (compact_multimap<uint64_t,MDSInternalContextBase*>::iterator p = waiting.lower_bound(min);
+ for (auto p = waiting.lower_bound(min);
p != waiting.end();
++p) {
if (p->first & mask) return true;
virtual void add_waiter(uint64_t mask, MDSInternalContextBase *c) {
if (waiting.empty())
get(PIN_WAITER);
- waiting.insert(pair<uint64_t,MDSInternalContextBase*>(mask, c));
+
+ uint64_t seq = 0;
+ if (mask & WAIT_ORDERED) {
+ seq = ++last_wait_seq;
+ mask &= ~WAIT_ORDERED;
+ }
+ waiting.insert(pair<uint64_t, pair<uint64_t, MDSInternalContextBase*> >(
+ mask,
+ pair<uint64_t, MDSInternalContextBase*>(seq, c)));
// pdout(10,g_conf->debug_mds) << (mdsco_db_line_prefix(this))
// << "add_waiter " << hex << mask << dec << " " << c
// << " on " << *this
}
virtual void take_waiting(uint64_t mask, list<MDSInternalContextBase*>& ls) {
if (waiting.empty()) return;
- compact_multimap<uint64_t,MDSInternalContextBase*>::iterator it = waiting.begin();
- while (it != waiting.end()) {
+
+ // process ordered waiters in the same order that they were added.
+ std::map<uint64_t, MDSInternalContextBase*> ordered_waiters;
+
+ for (auto it = waiting.begin();
+ it != waiting.end(); ) {
if (it->first & mask) {
- ls.push_back(it->second);
+
+ if (it->second.first > 0)
+ ordered_waiters.insert(it->second);
+ else
+ ls.push_back(it->second.second);
// pdout(10,g_conf->debug_mds) << (mdsco_db_line_prefix(this))
// << "take_waiting mask " << hex << mask << dec << " took " << it->second
// << " tag " << hex << it->first << dec
++it;
}
}
+ for (auto it = ordered_waiters.begin();
+ it != ordered_waiters.end();
+ ++it) {
+ ls.push_back(it->second);
+ }
if (waiting.empty())
put(PIN_WAITER);
}