Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / journal / FutureImpl.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_JOURNAL_FUTURE_IMPL_H
5 #define CEPH_JOURNAL_FUTURE_IMPL_H
6
7 #include "include/int_types.h"
8 #include "common/Mutex.h"
9 #include "common/RefCountedObj.h"
10 #include "journal/Future.h"
11 #include <list>
12 #include <map>
13 #include <boost/noncopyable.hpp>
14 #include <boost/intrusive_ptr.hpp>
15 #include "include/assert.h"
16
17 class Context;
18
19 namespace journal {
20
21 class FutureImpl;
22 typedef boost::intrusive_ptr<FutureImpl> FutureImplPtr;
23
24 class FutureImpl : public RefCountedObject, boost::noncopyable {
25 public:
26   struct FlushHandler {
27     virtual ~FlushHandler() {}
28     virtual void flush(const FutureImplPtr &future) = 0;
29     virtual void get() = 0;
30     virtual void put() = 0;
31   };
32   typedef boost::intrusive_ptr<FlushHandler> FlushHandlerPtr;
33
34   FutureImpl(uint64_t tag_tid, uint64_t entry_tid, uint64_t commit_tid);
35
36   void init(const FutureImplPtr &prev_future);
37
38   inline uint64_t get_tag_tid() const {
39     return m_tag_tid;
40   }
41   inline uint64_t get_entry_tid() const {
42     return m_entry_tid;
43   }
44   inline uint64_t get_commit_tid() const {
45     return m_commit_tid;
46   }
47
48   void flush(Context *on_safe = NULL);
49   void wait(Context *on_safe);
50
51   bool is_complete() const;
52   int get_return_value() const;
53
54   inline bool is_flush_in_progress() const {
55     Mutex::Locker locker(m_lock);
56     return (m_flush_state == FLUSH_STATE_IN_PROGRESS);
57   }
58   inline void set_flush_in_progress() {
59     Mutex::Locker locker(m_lock);
60     assert(m_flush_handler);
61     m_flush_handler.reset();
62     m_flush_state = FLUSH_STATE_IN_PROGRESS;
63   }
64
65   bool attach(const FlushHandlerPtr &flush_handler);
66   inline void detach() {
67     Mutex::Locker locker(m_lock);
68     m_flush_handler.reset();
69   }
70   inline FlushHandlerPtr get_flush_handler() const {
71     Mutex::Locker locker(m_lock);
72     return m_flush_handler;
73   }
74
75   void safe(int r);
76
77 private:
78   friend std::ostream &operator<<(std::ostream &, const FutureImpl &);
79
80   typedef std::map<FlushHandlerPtr, FutureImplPtr> FlushHandlers;
81   typedef std::list<Context *> Contexts;
82
83   enum FlushState {
84     FLUSH_STATE_NONE,
85     FLUSH_STATE_REQUESTED,
86     FLUSH_STATE_IN_PROGRESS
87   };
88
89   struct C_ConsistentAck : public Context {
90     FutureImplPtr future;
91     C_ConsistentAck(FutureImpl *_future) : future(_future) {}
92     void complete(int r) override {
93       future->consistent(r);
94       future.reset();
95     }
96     void finish(int r) override {}
97   };
98
99   uint64_t m_tag_tid;
100   uint64_t m_entry_tid;
101   uint64_t m_commit_tid;
102
103   mutable Mutex m_lock;
104   FutureImplPtr m_prev_future;
105   bool m_safe;
106   bool m_consistent;
107   int m_return_value;
108
109   FlushHandlerPtr m_flush_handler;
110   FlushState m_flush_state;
111
112   C_ConsistentAck m_consistent_ack;
113   Contexts m_contexts;
114
115   FutureImplPtr prepare_flush(FlushHandlers *flush_handlers);
116   FutureImplPtr prepare_flush(FlushHandlers *flush_handlers, Mutex &lock);
117
118   void consistent(int r);
119   void finish_unlock();
120 };
121
122 void intrusive_ptr_add_ref(FutureImpl::FlushHandler *p);
123 void intrusive_ptr_release(FutureImpl::FlushHandler *p);
124
125 std::ostream &operator<<(std::ostream &os, const FutureImpl &future);
126
127 } // namespace journal
128
129 using journal::operator<<;
130
131 #endif // CEPH_JOURNAL_FUTURE_IMPL_H