1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
17 #include "include/memory.h"
20 #include "msg/Messenger.h"
21 #include "include/Context.h"
30 void intrusive_ptr_add_ref(PrimaryLogPG *pg);
31 void intrusive_ptr_release(PrimaryLogPG *pg);
36 typedef ceph::shared_ptr<Watch> WatchRef;
37 typedef ceph::weak_ptr<Watch> WWatchRef;
40 typedef ceph::shared_ptr<Notify> NotifyRef;
41 typedef ceph::weak_ptr<Notify> WNotifyRef;
43 struct CancelableContext;
46 * Notify tracks the progress of a particular notify
48 * References are held by Watch and the timeout callback.
51 friend class NotifyTimeoutCB;
58 bool timed_out; ///< true if the notify timed out
59 set<WatchRef> watchers;
68 CancelableContext *cb;
71 /// (gid,cookie) -> reply_bl for everyone who acked the notify
72 multimap<pair<uint64_t,uint64_t>,bufferlist> notify_replies;
74 /// true if this notify is being discarded
76 return discarded || complete;
79 /// Sends notify completion if watchers.empty() or timeout
80 void maybe_complete_notify();
82 /// Called on Notify timeout
95 /// registers a timeout callback with the watch_timer
98 /// removes the timeout callback, called on completion or cancellation
102 string gen_dbg_prefix() {
104 ss << "Notify(" << make_pair(cookie, notify_id) << " "
105 << " watchers=" << watchers.size()
109 void set_self(NotifyRef _self) {
112 static NotifyRef makeNotifyRef(
113 ConnectionRef client,
122 /// Call after creation to initialize
125 /// Called once per watcher prior to init()
127 WatchRef watcher ///< [in] watcher to complete
130 /// Called once per NotifyAck
131 void complete_watcher(
132 WatchRef watcher, ///< [in] watcher to complete
133 bufferlist& reply_bl ///< [in] reply buffer from the notified watcher
135 /// Called when a watcher unregisters or times out
136 void complete_watcher_remove(
137 WatchRef watcher ///< [in] watcher to complete
140 /// Called when the notify is canceled due to a new peering interval
145 * Watch is a mapping between a Connection and an ObjectContext
147 * References are held by ObjectContext and the timeout callback
149 class HandleWatchTimeout;
150 class HandleDelayedWatchTimeout;
153 friend class HandleWatchTimeout;
154 friend class HandleDelayedWatchTimeout;
156 CancelableContext *cb;
159 boost::intrusive_ptr<PrimaryLogPG> pg;
160 ceph::shared_ptr<ObjectContext> obc;
162 std::map<uint64_t, NotifyRef> in_progress_notifies;
164 // Could have watch_info_t here, but this file includes osd_types.h
165 uint32_t timeout; ///< timeout in seconds
169 bool will_ping; ///< is client new enough to ping the watch
170 utime_t last_ping; ///< last cilent ping
172 entity_name_t entity;
176 PrimaryLogPG *pg, OSDService *osd,
177 ceph::shared_ptr<ObjectContext> obc, uint32_t timeout,
178 uint64_t cookie, entity_name_t entity,
179 const entity_addr_t& addr);
181 /// Registers the timeout callback with watch_timer
184 /// send a Notify message when connected for notif
185 void send_notify(NotifyRef notif);
187 /// Cleans up state on discard or remove (including Connection state, obc)
188 void discard_state();
190 /// Unregisters the timeout callback
191 void unregister_cb();
193 /// note receipt of a ping
194 void got_ping(utime_t t);
195 utime_t get_last_ping() const {
199 bool is_connected() const {
200 return conn.get() != NULL;
202 bool is_connected(Connection *con) const {
203 return conn.get() == con;
206 /// NOTE: must be called with pg lock held
209 uint64_t get_watcher_gid() const {
213 string gen_dbg_prefix();
214 static WatchRef makeWatchRef(
215 PrimaryLogPG *pg, OSDService *osd,
216 ceph::shared_ptr<ObjectContext> obc, uint32_t timeout, uint64_t cookie, entity_name_t entity, const entity_addr_t &addr);
217 void set_self(WatchRef _self) {
221 /// Does not grant a ref count!
222 boost::intrusive_ptr<PrimaryLogPG> get_pg() { return pg; }
224 ceph::shared_ptr<ObjectContext> get_obc() { return obc; }
226 uint64_t get_cookie() const { return cookie; }
227 entity_name_t get_entity() const { return entity; }
228 entity_addr_t get_peer_addr() const { return addr; }
229 uint32_t get_timeout() const { return timeout; }
231 /// Generates context for use if watch timeout is delayed by scrub or recovery
232 Context *get_delayed_cb();
234 /// True if currently connected
237 /// Transitions Watch to connected, unregister_cb, resends pending Notifies
239 ConnectionRef con, ///< [in] Reference to new connection
240 bool will_ping ///< [in] client is new and will send pings
243 /// Transitions watch to disconnected, register_cb
246 /// Called if Watch state is discarded due to new peering interval
249 /// True if removed or discarded
250 bool is_discarded() const;
252 /// Called on unwatch
253 void remove(bool send_disconnect);
255 /// Adds notif as in-progress notify
257 NotifyRef notif ///< [in] Reference to new in-progress notify
260 /// Removes timed out notify
262 NotifyRef notif ///< [in] notify which timed out
265 /// Call when notify_ack received on notify_id
267 uint64_t notify_id, ///< [in] id of acked notify
268 bufferlist& reply_bl ///< [in] notify reply buffer
273 * Holds weak refs to Watch structures corresponding to a connection
274 * Lives in the Session object of an OSD connection
276 class WatchConState {
278 std::set<WatchRef> watches;
281 WatchConState(CephContext* cct) : lock("WatchConState"), cct(cct) {}
285 WatchRef watch ///< [in] Ref to new watch object
290 WatchRef watch ///< [in] Ref to watch object to remove
293 /// Called on session reset, disconnects watchers
294 void reset(Connection *con);