#include "config.h"
#include "Finisher.h"
+#include "common/debug.h"
+#define DOUT_SUBSYS finisher
+#undef dout_prefix
+#define dout_prefix *_dout << dbeginl << std::hex << pthread_self() << std::dec << " finisher(" << this << ") "
+
void Finisher::start()
{
finisher_thread.create();
void Finisher::wait_for_empty()
{
finisher_lock.Lock();
- while (!finisher_queue.empty())
- finisher_cond.Wait(finisher_lock);
+ while (!finisher_queue.empty() || finisher_running) {
+ dout(10) << "wait_for_empty waiting" << dendl;
+ finisher_empty_cond.Wait(finisher_lock);
+ }
+ dout(10) << "wait_for_empty empty" << dendl;
finisher_lock.Unlock();
}
void *Finisher::finisher_thread_entry()
{
finisher_lock.Lock();
- //dout_generic(10) << "finisher_thread start" << dendl;
+ dout(10) << "finisher_thread start" << dendl;
while (!finisher_stop) {
while (!finisher_queue.empty()) {
list<pair<Context*,int> > ls_rval;
ls.swap(finisher_queue);
ls_rval.swap(finisher_queue_rval);
+ finisher_running = true;
finisher_lock.Unlock();
+ dout(10) << "finisher_thread doing " << ls << dendl;
for (vector<Context*>::iterator p = ls.begin();
p != ls.end();
ls_rval.pop_front();
}
}
+ dout(10) << "finisher_thread done with " << ls << dendl;
ls.clear();
finisher_lock.Lock();
- finisher_empty_cond.Signal();
+ finisher_running = false;
}
- if (finisher_stop) break;
+ dout(10) << "finisher_thread empty" << dendl;
+ finisher_empty_cond.Signal();
+ if (finisher_stop)
+ break;
- //dout_generic(30) << "finisher_thread sleeping" << dendl;
+ dout(10) << "finisher_thread sleeping" << dendl;
finisher_cond.Wait(finisher_lock);
}
+ finisher_empty_cond.Signal();
- //dout_generic(10) << "finisher_thread start" << dendl;
+ dout(10) << "finisher_thread stop" << dendl;
finisher_lock.Unlock();
return 0;
}
class Finisher {
Mutex finisher_lock;
Cond finisher_cond, finisher_empty_cond;
- bool finisher_stop;
+ bool finisher_stop, finisher_running;
vector<Context*> finisher_queue;
list<pair<Context*,int> > finisher_queue_rval;
void wait_for_empty();
- Finisher() : finisher_lock("Finisher::finisher_lock"), finisher_stop(false), finisher_thread(this) {}
+ Finisher() : finisher_lock("Finisher::finisher_lock"),
+ finisher_stop(false), finisher_running(false), finisher_thread(this) {}
};
#endif
OPTION(debug_paxos, 0, OPT_INT, 0),
OPTION(debug_tp, 0, OPT_INT, 0),
OPTION(debug_auth, 0, OPT_INT, 1),
+ OPTION(debug_finisher, 0, OPT_INT, 1),
OPTION(keys_file, 'k', OPT_STR, "~/.ceph/keyring.bin, /etc/ceph/keyring.bin, .ceph_keyring"),
OPTION(supported_auth, 0, OPT_STR, "none"),
OPTION(clock_lock, 0, OPT_BOOL, false),