Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / libradosstriper / MultiAioCompletionImpl.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2014 Sebastien Ponce <sebastien.ponce@cern.ch>
7  *
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.
12  *
13  */
14
15 #ifndef CEPH_LIBRADOSSTRIPERSTRIPER_MULTIAIOCOMPLETIONIMPL_H
16 #define CEPH_LIBRADOSSTRIPERSTRIPER_MULTIAIOCOMPLETIONIMPL_H
17
18 #include "common/Cond.h"
19 #include "common/Mutex.h"
20
21 #include "include/radosstriper/libradosstriper.hpp"
22
23 struct libradosstriper::MultiAioCompletionImpl {
24
25   Mutex lock;
26   Cond cond;
27   int ref, rval;
28   int pending_complete, pending_safe;
29   rados_callback_t callback_complete, callback_safe;
30   void *callback_complete_arg, *callback_safe_arg;
31   bool building;       ///< true if we are still building this completion
32   bufferlist bl;       /// only used for read case in C api of rados striper
33   std::list<bufferlist*> bllist; /// keep temporary buffer lists used for destriping
34
35   MultiAioCompletionImpl() : lock("MultiAioCompletionImpl lock", false, false),
36     ref(1), rval(0),
37     pending_complete(0), pending_safe(0),
38     callback_complete(0), callback_safe(0),
39     callback_complete_arg(0), callback_safe_arg(0),
40     building(true) {};
41
42   ~MultiAioCompletionImpl() {
43     // deallocate temporary buffer lists
44     for (std::list<bufferlist*>::iterator it = bllist.begin();
45          it != bllist.end();
46          it++) {
47       delete *it;
48     }
49     bllist.clear();
50   }
51
52   int set_complete_callback(void *cb_arg, rados_callback_t cb) {
53     lock.Lock();
54     callback_complete = cb;
55     callback_complete_arg = cb_arg;
56     lock.Unlock();
57     return 0;
58   }
59   int set_safe_callback(void *cb_arg, rados_callback_t cb) {
60     lock.Lock();
61     callback_safe = cb;
62     callback_safe_arg = cb_arg;
63     lock.Unlock();
64     return 0;
65   }
66   int wait_for_complete() {
67     lock.Lock();
68     while (pending_complete)
69       cond.Wait(lock);
70     lock.Unlock();
71     return 0;
72   }
73   int wait_for_safe() {
74     lock.Lock();
75     while (pending_safe)
76       cond.Wait(lock);
77     lock.Unlock();
78     return 0;
79   }
80   bool is_complete() {
81     lock.Lock();
82     int r = pending_complete;
83     lock.Unlock();
84     return 0 == r;
85   }
86   bool is_safe() {
87     lock.Lock();
88     int r = pending_safe;
89     lock.Unlock();
90     return r == 0;
91   }
92   void wait_for_complete_and_cb() {
93     lock.Lock();
94     while (pending_complete || callback_complete)
95       cond.Wait(lock);
96     lock.Unlock();
97   }
98   void wait_for_safe_and_cb() {
99     lock.Lock();
100     while (pending_safe || callback_safe)
101       cond.Wait(lock);
102     lock.Unlock();
103   }
104   bool is_complete_and_cb() {
105     lock.Lock();
106     bool r = ((0 == pending_complete) && !callback_complete);
107     lock.Unlock();
108     return r;
109   }
110   bool is_safe_and_cb() {
111     lock.Lock();
112     int r = ((0 == pending_safe) && !callback_safe);
113     lock.Unlock();
114     return r;
115   }
116   int get_return_value() {
117     lock.Lock();
118     int r = rval;
119     lock.Unlock();
120     return r;
121   }
122   void get() {
123     lock.Lock();
124     _get();
125     lock.Unlock();
126   }
127   void _get() {
128     assert(lock.is_locked());
129     assert(ref > 0);
130     ++ref;
131   }
132   void put() {
133     lock.Lock();
134     put_unlock();
135   }
136   void put_unlock() {
137     assert(ref > 0);
138     int n = --ref;
139     lock.Unlock();
140     if (!n)
141       delete this;
142   }
143   void add_request() {
144     lock.Lock();
145     pending_complete++;
146     _get();
147     pending_safe++;
148     _get();
149     lock.Unlock();
150   }
151   void add_safe_request() {
152     lock.Lock();
153     pending_complete++;
154     _get();
155     lock.Unlock();
156   }
157   void complete() {
158     assert(lock.is_locked());
159     if (callback_complete) {
160       callback_complete(this, callback_complete_arg);
161       callback_complete = 0;
162     }
163     cond.Signal();
164   }
165   void safe() {
166     assert(lock.is_locked());
167     if (callback_safe) {
168       callback_safe(this, callback_safe_arg);
169       callback_safe = 0;
170     }
171     cond.Signal();
172   };
173
174   void complete_request(ssize_t r);
175   void safe_request(ssize_t r);
176   void finish_adding_requests();
177
178 };
179
180 void intrusive_ptr_add_ref(libradosstriper::MultiAioCompletionImpl*);
181 void intrusive_ptr_release(libradosstriper::MultiAioCompletionImpl*);
182
183 #endif // CEPH_LIBRADOSSTRIPERSTRIPER_MULTIAIOCOMPLETIONIMPL_H