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.
18 #include "msg/Connection.h"
19 #include "include/Context.h"
28 void intrusive_ptr_add_ref(PrimaryLogPG
*pg
);
29 void intrusive_ptr_release(PrimaryLogPG
*pg
);
34 typedef std::shared_ptr
<Watch
> WatchRef
;
35 typedef std::weak_ptr
<Watch
> WWatchRef
;
38 typedef std::shared_ptr
<Notify
> NotifyRef
;
39 typedef std::weak_ptr
<Notify
> WNotifyRef
;
41 struct CancelableContext
;
44 * Notify tracks the progress of a particular notify
46 * References are held by Watch and the timeout callback.
49 friend class NotifyTimeoutCB
;
56 bool timed_out
; ///< true if the notify timed out
57 std::set
<WatchRef
> watchers
;
59 ceph::buffer::list payload
;
66 CancelableContext
*cb
;
67 ceph::mutex lock
= ceph::make_mutex("Notify::lock");
69 /// (gid,cookie) -> reply_bl for everyone who acked the notify
70 std::multimap
<std::pair
<uint64_t,uint64_t>, ceph::buffer::list
> notify_replies
;
72 /// true if this notify is being discarded
74 return discarded
|| complete
;
77 /// Sends notify completion if watchers.empty() or timeout
78 void maybe_complete_notify();
80 /// Called on Notify timeout
86 ceph::buffer::list
& payload
,
93 /// registers a timeout callback with the watch_timer
96 /// removes the timeout callback, called on completion or cancellation
100 std::ostream
& gen_dbg_prefix(std::ostream
& out
) {
101 return out
<< "Notify(" << std::make_pair(cookie
, notify_id
) << " "
102 << " watchers=" << watchers
.size()
105 void set_self(NotifyRef _self
) {
108 static NotifyRef
makeNotifyRef(
109 ConnectionRef client
,
111 ceph::buffer::list
&payload
,
118 /// Call after creation to initialize
121 /// Called once per watcher prior to init()
123 WatchRef watcher
///< [in] watcher to complete
126 /// Called once per NotifyAck
127 void complete_watcher(
128 WatchRef watcher
, ///< [in] watcher to complete
129 ceph::buffer::list
& reply_bl
///< [in] reply buffer from the notified watcher
131 /// Called when a watcher unregisters or times out
132 void complete_watcher_remove(
133 WatchRef watcher
///< [in] watcher to complete
136 /// Called when the notify is canceled due to a new peering interval
141 * Watch is a mapping between a Connection and an ObjectContext
143 * References are held by ObjectContext and the timeout callback
145 class HandleWatchTimeout
;
146 class HandleDelayedWatchTimeout
;
149 friend class HandleWatchTimeout
;
150 friend class HandleDelayedWatchTimeout
;
152 CancelableContext
*cb
;
155 boost::intrusive_ptr
<PrimaryLogPG
> pg
;
156 std::shared_ptr
<ObjectContext
> obc
;
158 std::map
<uint64_t, NotifyRef
> in_progress_notifies
;
160 // Could have watch_info_t here, but this file includes osd_types.h
161 uint32_t timeout
; ///< timeout in seconds
165 bool will_ping
; ///< is client new enough to ping the watch
166 utime_t last_ping
; ///< last client ping
168 entity_name_t entity
;
172 PrimaryLogPG
*pg
, OSDService
*osd
,
173 std::shared_ptr
<ObjectContext
> obc
, uint32_t timeout
,
174 uint64_t cookie
, entity_name_t entity
,
175 const entity_addr_t
& addr
);
177 /// Registers the timeout callback with watch_timer
180 /// send a Notify message when connected for notif
181 void send_notify(NotifyRef notif
);
183 /// Cleans up state on discard or remove (including Connection state, obc)
184 void discard_state();
186 /// Unregisters the timeout callback
187 void unregister_cb();
189 /// note receipt of a ping
190 void got_ping(utime_t t
);
191 utime_t
get_last_ping() const {
195 /// True if currently connected
196 bool is_connected() const {
197 return conn
.get() != NULL
;
199 bool is_connected(Connection
*con
) const {
200 return conn
.get() == con
;
203 /// NOTE: must be called with pg lock held
206 uint64_t get_watcher_gid() const {
210 std::ostream
& gen_dbg_prefix(std::ostream
& out
);
211 static WatchRef
makeWatchRef(
212 PrimaryLogPG
*pg
, OSDService
*osd
,
213 std::shared_ptr
<ObjectContext
> obc
, uint32_t timeout
, uint64_t cookie
, entity_name_t entity
, const entity_addr_t
&addr
);
214 void set_self(WatchRef _self
) {
218 /// Does not grant a ref count!
219 boost::intrusive_ptr
<PrimaryLogPG
> get_pg() { return pg
; }
221 std::shared_ptr
<ObjectContext
> get_obc() { return obc
; }
223 uint64_t get_cookie() const { return cookie
; }
224 entity_name_t
get_entity() const { return entity
; }
225 entity_addr_t
get_peer_addr() const { return addr
; }
226 uint32_t get_timeout() const { return timeout
; }
228 /// Generates context for use if watch timeout is delayed by scrub or recovery
229 Context
*get_delayed_cb();
231 /// Transitions Watch to connected, unregister_cb, resends pending Notifies
233 ConnectionRef con
, ///< [in] Reference to new connection
234 bool will_ping
///< [in] client is new and will send pings
237 /// Transitions watch to disconnected, register_cb
240 /// Called if Watch state is discarded due to new peering interval
243 /// True if removed or discarded
244 bool is_discarded() const;
246 /// Called on unwatch
247 void remove(bool send_disconnect
);
249 /// Adds notif as in-progress notify
251 NotifyRef notif
///< [in] Reference to new in-progress notify
254 /// Removes timed out notify
256 NotifyRef notif
///< [in] notify which timed out
259 /// Call when notify_ack received on notify_id
261 uint64_t notify_id
, ///< [in] id of acked notify
262 ceph::buffer::list
& reply_bl
///< [in] notify reply buffer
267 * Holds weak refs to Watch structures corresponding to a connection
268 * Lives in the Session object of an OSD connection
270 class WatchConState
{
271 ceph::mutex lock
= ceph::make_mutex("WatchConState");
272 std::set
<WatchRef
> watches
;
275 explicit WatchConState(CephContext
* cct
) : cct(cct
) {}
279 WatchRef watch
///< [in] Ref to new watch object
284 WatchRef watch
///< [in] Ref to watch object to remove
287 /// Called on session reset, disconnects watchers
288 void reset(Connection
*con
);