oi.watchers.erase(oi_iter);
t->nop(); // update oi on disk
ctx->watch_disconnects.push_back(
- OpContext::watch_disconnect_t(cookie, entity, false));
+ watch_disconnect_t(cookie, entity, false));
} else {
dout(10) << " can't remove: no watch by " << entity << dendl;
}
++p) {
dout(20) << __func__ << " will disconnect watcher " << p->first << dendl;
ctx->watch_disconnects.push_back(
- OpContext::watch_disconnect_t(p->first.first, p->first.second, true));
+ watch_disconnect_t(p->first.first, p->first.second, true));
}
oi.watchers.clear();
}
}
-void ReplicatedPG::do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn)
+void ReplicatedPG::complete_disconnect_watches(
+ ObjectContextRef obc,
+ const list<watch_disconnect_t> &to_disconnect)
{
- entity_name_t entity = ctx->reqid.name;
- dout(15) << "do_osd_op_effects " << entity << " con " << conn.get() << dendl;
-
- // disconnects first
- for (list<OpContext::watch_disconnect_t>::iterator i =
- ctx->watch_disconnects.begin();
- i != ctx->watch_disconnects.end();
+ for (list<watch_disconnect_t>::const_iterator i =
+ to_disconnect.begin();
+ i != to_disconnect.end();
++i) {
pair<uint64_t, entity_name_t> watcher(i->cookie, i->name);
- if (ctx->obc->watchers.count(watcher)) {
- WatchRef watch = ctx->obc->watchers[watcher];
+ if (obc->watchers.count(watcher)) {
+ WatchRef watch = obc->watchers[watcher];
dout(10) << "do_osd_op_effects disconnect watcher " << watcher << dendl;
- ctx->obc->watchers.erase(watcher);
+ obc->watchers.erase(watcher);
watch->remove(i->send_disconnect);
} else {
dout(10) << "do_osd_op_effects disconnect failed to find watcher "
<< watcher << dendl;
}
}
+}
+
+void ReplicatedPG::do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn)
+{
+ entity_name_t entity = ctx->reqid.name;
+ dout(15) << "do_osd_op_effects " << entity << " con " << conn.get() << dendl;
+
+ // disconnects first
+ complete_disconnect_watches(ctx->obc, ctx->watch_disconnects);
if (!conn)
return;
LogClientTemp clog_error() { return osd->clog->error(); }
+ struct watch_disconnect_t {
+ uint64_t cookie;
+ entity_name_t name;
+ bool send_disconnect;
+ watch_disconnect_t(uint64_t c, entity_name_t n, bool sd)
+ : cookie(c), name(n), send_disconnect(sd) {}
+ };
+ void complete_disconnect_watches(
+ ObjectContextRef obc,
+ const list<watch_disconnect_t> &to_disconnect);
+
/*
* Capture all object state associated with an in-progress read or write.
*/
// side effects
list<pair<watch_info_t,bool> > watch_connects; ///< new watch + will_ping flag
- struct watch_disconnect_t {
- uint64_t cookie;
- entity_name_t name;
- bool send_disconnect;
- watch_disconnect_t(uint64_t c, entity_name_t n, bool sd)
- : cookie(c), name(n), send_disconnect(sd) {}
- };
list<watch_disconnect_t> watch_disconnects; ///< old watch + send_discon
list<notify_info_t> notifies;
struct NotifyAck {