]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
9f95a23c TL |
18 | #include <list> |
19 | #include <mutex> | |
20 | #include "common/ceph_mutex.h" | |
7c673cae FG |
21 | #include "include/radosstriper/libradosstriper.hpp" |
22 | ||
23 | struct libradosstriper::MultiAioCompletionImpl { | |
24 | ||
9f95a23c TL |
25 | ceph::mutex lock = ceph::make_mutex("MultiAioCompletionImpl lock", false); |
26 | ceph::condition_variable cond; | |
7c673cae FG |
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 | ||
9f95a23c TL |
35 | MultiAioCompletionImpl() |
36 | : ref(1), rval(0), | |
7c673cae FG |
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) { | |
9f95a23c | 53 | std::scoped_lock l{lock}; |
7c673cae FG |
54 | callback_complete = cb; |
55 | callback_complete_arg = cb_arg; | |
7c673cae FG |
56 | return 0; |
57 | } | |
58 | int set_safe_callback(void *cb_arg, rados_callback_t cb) { | |
9f95a23c | 59 | std::scoped_lock l{lock}; |
7c673cae FG |
60 | callback_safe = cb; |
61 | callback_safe_arg = cb_arg; | |
7c673cae FG |
62 | return 0; |
63 | } | |
64 | int wait_for_complete() { | |
9f95a23c TL |
65 | std::unique_lock l{lock}; |
66 | cond.wait(l, [this] { return !pending_complete; }); | |
7c673cae FG |
67 | return 0; |
68 | } | |
69 | int wait_for_safe() { | |
9f95a23c TL |
70 | std::unique_lock l{lock}; |
71 | cond.wait(l, [this] { return !pending_safe; }); | |
7c673cae FG |
72 | return 0; |
73 | } | |
74 | bool is_complete() { | |
9f95a23c TL |
75 | std::scoped_lock l{lock}; |
76 | return pending_complete == 0; | |
7c673cae FG |
77 | } |
78 | bool is_safe() { | |
9f95a23c TL |
79 | std::scoped_lock l{lock}; |
80 | return pending_safe == 0; | |
7c673cae FG |
81 | } |
82 | void wait_for_complete_and_cb() { | |
9f95a23c TL |
83 | std::unique_lock l{lock}; |
84 | cond.wait(l, [this] { return !pending_complete && !callback_complete; }); | |
7c673cae FG |
85 | } |
86 | void wait_for_safe_and_cb() { | |
9f95a23c TL |
87 | std::unique_lock l{lock}; |
88 | cond.wait(l, [this] { return !pending_safe && !callback_safe; }); | |
7c673cae FG |
89 | } |
90 | bool is_complete_and_cb() { | |
9f95a23c TL |
91 | std::scoped_lock l{lock}; |
92 | return ((0 == pending_complete) && !callback_complete); | |
7c673cae FG |
93 | } |
94 | bool is_safe_and_cb() { | |
9f95a23c TL |
95 | std::scoped_lock l{lock}; |
96 | return ((0 == pending_safe) && !callback_safe); | |
7c673cae FG |
97 | } |
98 | int get_return_value() { | |
9f95a23c TL |
99 | std::scoped_lock l{lock}; |
100 | return rval; | |
7c673cae FG |
101 | } |
102 | void get() { | |
9f95a23c | 103 | std::scoped_lock l{lock}; |
7c673cae | 104 | _get(); |
7c673cae FG |
105 | } |
106 | void _get() { | |
9f95a23c | 107 | ceph_assert(ceph_mutex_is_locked(lock)); |
11fdf7f2 | 108 | ceph_assert(ref > 0); |
7c673cae FG |
109 | ++ref; |
110 | } | |
111 | void put() { | |
9f95a23c | 112 | lock.lock(); |
7c673cae FG |
113 | put_unlock(); |
114 | } | |
115 | void put_unlock() { | |
11fdf7f2 | 116 | ceph_assert(ref > 0); |
7c673cae | 117 | int n = --ref; |
9f95a23c | 118 | lock.unlock(); |
7c673cae FG |
119 | if (!n) |
120 | delete this; | |
121 | } | |
122 | void add_request() { | |
9f95a23c | 123 | std::scoped_lock l{lock}; |
7c673cae FG |
124 | pending_complete++; |
125 | _get(); | |
126 | pending_safe++; | |
127 | _get(); | |
7c673cae FG |
128 | } |
129 | void add_safe_request() { | |
9f95a23c | 130 | std::scoped_lock l{lock}; |
7c673cae FG |
131 | pending_complete++; |
132 | _get(); | |
7c673cae FG |
133 | } |
134 | void complete() { | |
9f95a23c | 135 | ceph_assert(ceph_mutex_is_locked(lock)); |
7c673cae FG |
136 | if (callback_complete) { |
137 | callback_complete(this, callback_complete_arg); | |
138 | callback_complete = 0; | |
139 | } | |
9f95a23c | 140 | cond.notify_all(); |
7c673cae FG |
141 | } |
142 | void safe() { | |
9f95a23c | 143 | ceph_assert(ceph_mutex_is_locked(lock)); |
7c673cae FG |
144 | if (callback_safe) { |
145 | callback_safe(this, callback_safe_arg); | |
146 | callback_safe = 0; | |
147 | } | |
9f95a23c | 148 | cond.notify_all(); |
7c673cae FG |
149 | }; |
150 | ||
151 | void complete_request(ssize_t r); | |
152 | void safe_request(ssize_t r); | |
153 | void finish_adding_requests(); | |
154 | ||
155 | }; | |
156 | ||
224ce89b WB |
157 | void intrusive_ptr_add_ref(libradosstriper::MultiAioCompletionImpl*); |
158 | void intrusive_ptr_release(libradosstriper::MultiAioCompletionImpl*); | |
159 | ||
7c673cae | 160 | #endif // CEPH_LIBRADOSSTRIPERSTRIPER_MULTIAIOCOMPLETIONIMPL_H |