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
);