]>
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) 2004-2012 Sage Weil <sage@newdream.net> | |
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_LIBRADOS_POOLASYNCCOMPLETIONIMPL_H | |
16 | #define CEPH_LIBRADOS_POOLASYNCCOMPLETIONIMPL_H | |
17 | ||
18 | #include "common/Cond.h" | |
19 | #include "common/Mutex.h" | |
20 | #include "include/Context.h" | |
21 | #include "include/rados/librados.h" | |
22 | #include "include/rados/librados.hpp" | |
23 | ||
24 | namespace librados { | |
25 | struct PoolAsyncCompletionImpl { | |
26 | Mutex lock; | |
27 | Cond cond; | |
28 | int ref, rval; | |
29 | bool released; | |
30 | bool done; | |
31 | ||
32 | rados_callback_t callback; | |
33 | void *callback_arg; | |
34 | ||
35 | PoolAsyncCompletionImpl() : lock("PoolAsyncCompletionImpl lock"), | |
36 | ref(1), rval(0), released(false), done(false), | |
37 | callback(0), callback_arg(0) {} | |
38 | ||
39 | int set_callback(void *cb_arg, rados_callback_t cb) { | |
40 | lock.Lock(); | |
41 | callback = cb; | |
42 | callback_arg = cb_arg; | |
43 | lock.Unlock(); | |
44 | return 0; | |
45 | } | |
46 | int wait() { | |
47 | lock.Lock(); | |
48 | while (!done) | |
49 | cond.Wait(lock); | |
50 | lock.Unlock(); | |
51 | return 0; | |
52 | } | |
53 | int is_complete() { | |
54 | lock.Lock(); | |
55 | int r = done; | |
56 | lock.Unlock(); | |
57 | return r; | |
58 | } | |
59 | int get_return_value() { | |
60 | lock.Lock(); | |
61 | int r = rval; | |
62 | lock.Unlock(); | |
63 | return r; | |
64 | } | |
65 | void get() { | |
66 | lock.Lock(); | |
67 | assert(ref > 0); | |
68 | ref++; | |
69 | lock.Unlock(); | |
70 | } | |
71 | void release() { | |
72 | lock.Lock(); | |
73 | assert(!released); | |
74 | released = true; | |
75 | put_unlock(); | |
76 | } | |
77 | void put() { | |
78 | lock.Lock(); | |
79 | put_unlock(); | |
80 | } | |
81 | void put_unlock() { | |
82 | assert(ref > 0); | |
83 | int n = --ref; | |
84 | lock.Unlock(); | |
85 | if (!n) | |
86 | delete this; | |
87 | } | |
88 | }; | |
89 | ||
90 | class C_PoolAsync_Safe : public Context { | |
91 | PoolAsyncCompletionImpl *c; | |
92 | ||
93 | public: | |
94 | explicit C_PoolAsync_Safe(PoolAsyncCompletionImpl *_c) : c(_c) { | |
95 | c->get(); | |
96 | } | |
97 | ~C_PoolAsync_Safe() override { | |
98 | c->put(); | |
99 | } | |
100 | ||
101 | void finish(int r) override { | |
102 | c->lock.Lock(); | |
103 | c->rval = r; | |
104 | c->done = true; | |
105 | c->cond.Signal(); | |
106 | ||
107 | if (c->callback) { | |
108 | rados_callback_t cb = c->callback; | |
109 | void *cb_arg = c->callback_arg; | |
110 | c->lock.Unlock(); | |
111 | cb(c, cb_arg); | |
112 | c->lock.Lock(); | |
113 | } | |
114 | ||
115 | c->lock.Unlock(); | |
116 | } | |
117 | }; | |
118 | } | |
119 | #endif |