1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_WATCHER_H
5 #define CEPH_LIBRBD_WATCHER_H
7 #include "common/AsyncOpTracker.h"
8 #include "common/Mutex.h"
9 #include "common/RWLock.h"
10 #include "include/rados/librados.hpp"
11 #include "librbd/watcher/Notifier.h"
12 #include "librbd/watcher/Types.h"
20 namespace watcher
{ struct NotifyResponse
; }
24 struct C_NotifyAck
: public Context
{
31 C_NotifyAck(Watcher
*watcher
, uint64_t notify_id
, uint64_t handle
);
32 void finish(int r
) override
;
35 Watcher(librados::IoCtx
& ioctx
, ContextWQ
*work_queue
,
36 const std::string
& oid
);
39 void register_watch(Context
*on_finish
);
40 virtual void unregister_watch(Context
*on_finish
);
41 void flush(Context
*on_finish
);
43 bool notifications_blocked() const;
44 virtual void block_notifies(Context
*on_finish
);
45 void unblock_notifies();
47 std::string
get_oid() const;
48 void set_oid(const string
& oid
);
50 uint64_t get_watch_handle() const {
51 RWLock::RLocker
watch_locker(m_watch_lock
);
52 return m_watch_handle
;
55 bool is_registered() const {
56 RWLock::RLocker
locker(m_watch_lock
);
57 return is_registered(m_watch_lock
);
59 bool is_unregistered() const {
60 RWLock::RLocker
locker(m_watch_lock
);
61 return is_unregistered(m_watch_lock
);
67 WATCH_STATE_REGISTERING
,
68 WATCH_STATE_REWATCHING
71 librados::IoCtx
& m_ioctx
;
72 ContextWQ
*m_work_queue
;
75 mutable RWLock m_watch_lock
;
76 uint64_t m_watch_handle
;
77 watcher::Notifier m_notifier
;
78 WatchState m_watch_state
;
79 AsyncOpTracker m_async_op_tracker
;
81 bool is_registered(const RWLock
&) const {
82 return (m_watch_state
== WATCH_STATE_IDLE
&& m_watch_handle
!= 0);
84 bool is_unregistered(const RWLock
&) const {
85 return (m_watch_state
== WATCH_STATE_IDLE
&& m_watch_handle
== 0);
88 void send_notify(bufferlist
&payload
,
89 watcher::NotifyResponse
*response
= nullptr,
90 Context
*on_finish
= nullptr);
92 virtual void handle_notify(uint64_t notify_id
, uint64_t handle
,
93 uint64_t notifier_id
, bufferlist
&bl
) = 0;
95 virtual void handle_error(uint64_t cookie
, int err
);
97 void acknowledge_notify(uint64_t notify_id
, uint64_t handle
,
100 virtual void handle_rewatch_complete(int r
) { }
116 * REGISTERED * * * * * * * > ERROR
123 * | \---------------------/
125 * | (unregister_watch)
136 struct WatchCtx
: public librados::WatchCtx2
{
139 WatchCtx(Watcher
&parent
) : watcher(parent
) {}
141 void handle_notify(uint64_t notify_id
,
143 uint64_t notifier_id
,
144 bufferlist
& bl
) override
;
145 void handle_error(uint64_t handle
, int err
) override
;
148 struct C_RegisterWatch
: public Context
{
152 C_RegisterWatch(Watcher
*watcher
, Context
*on_finish
)
153 : watcher(watcher
), on_finish(on_finish
) {
155 void finish(int r
) override
{
156 watcher
->handle_register_watch(r
, on_finish
);
160 WatchCtx m_watch_ctx
;
161 Context
*m_unregister_watch_ctx
= nullptr;
163 bool m_watch_error
= false;
165 uint32_t m_blocked_count
= 0;
167 void handle_register_watch(int r
, Context
*on_finish
);
170 void handle_rewatch(int r
);
171 void handle_rewatch_callback(int r
);
175 } // namespace librbd
177 #endif // CEPH_LIBRBD_WATCHER_H