void JournalPlayer::handle_watch(int r) {
ldout(m_cct, 10) << __func__ << ": r=" << r << dendl;
+ if (r == -ECANCELED) {
+ // unwatch of object player(s)
+ return;
+ }
Mutex::Locker locker(m_lock);
m_watch_scheduled = false;
+
std::set<uint64_t> object_numbers;
for (auto &players : m_object_players) {
object_numbers.insert(
struct C_Watch : public Context {
JournalPlayer *player;
+ Mutex lock;
uint8_t pending_fetches = 1;
int ret_val = 0;
- C_Watch(JournalPlayer *player) : player(player) {
+ C_Watch(JournalPlayer *player)
+ : player(player), lock("JournalPlayer::C_Watch::lock") {
}
virtual void complete(int r) override {
- player->m_lock.Lock();
+ lock.Lock();
if (ret_val == 0 && r < 0) {
ret_val = r;
}
assert(pending_fetches > 0);
if (--pending_fetches == 0) {
- player->m_lock.Unlock();
+ lock.Unlock();
Context::complete(ret_val);
} else {
- player->m_lock.Unlock();
+ lock.Unlock();
}
}
void ObjectPlayer::unwatch() {
ldout(m_cct, 20) << __func__ << ": " << m_oid << " unwatch" << dendl;
- Mutex::Locker timer_locker(m_timer_lock);
+ Context *watch_ctx = nullptr;
+ {
+ Mutex::Locker timer_locker(m_timer_lock);
- cancel_watch();
+ cancel_watch();
- Context *watch_ctx = nullptr;
- std::swap(watch_ctx, m_watch_ctx);
- if (watch_ctx != nullptr) {
- delete watch_ctx;
+ std::swap(watch_ctx, m_watch_ctx);
+ while (m_watch_in_progress) {
+ m_watch_in_progress_cond.Wait(m_timer_lock);
+ }
}
- while (m_watch_in_progress) {
- m_watch_in_progress_cond.Wait(m_timer_lock);
+ if (watch_ctx != nullptr) {
+ watch_ctx->complete(-ECANCELED);
}
}