]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/Cond.h
Import ceph 15.2.8
[ceph.git] / ceph / src / common / Cond.h
CommitLineData
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-2006 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
16#ifndef CEPH_COND_H
17#define CEPH_COND_H
18
11fdf7f2 19#include "common/Clock.h"
9f95a23c 20#include "common/ceph_mutex.h"
7c673cae 21#include "include/Context.h"
11fdf7f2 22
7c673cae
FG
23/**
24 * context to signal a cond
25 *
26 * Generic context to signal a cond and store the return value. We
27 * assume the caller is holding the appropriate lock.
28 */
29class C_Cond : public Context {
9f95a23c 30 ceph::condition_variable& cond; ///< Cond to signal
7c673cae
FG
31 bool *done; ///< true if finish() has been called
32 int *rval; ///< return value
33public:
9f95a23c 34 C_Cond(ceph::condition_variable &c, bool *d, int *r) : cond(c), done(d), rval(r) {
7c673cae
FG
35 *done = false;
36 }
37 void finish(int r) override {
38 *done = true;
39 *rval = r;
9f95a23c 40 cond.notify_all();
7c673cae
FG
41 }
42};
43
44/**
45 * context to signal a cond, protected by a lock
46 *
47 * Generic context to signal a cond under a specific lock. We take the
48 * lock in the finish() callback, so the finish() caller must not
49 * already hold it.
50 */
51class C_SafeCond : public Context {
9f95a23c
TL
52 ceph::mutex& lock; ///< Mutex to take
53 ceph::condition_variable& cond; ///< Cond to signal
7c673cae
FG
54 bool *done; ///< true after finish() has been called
55 int *rval; ///< return value (optional)
56public:
9f95a23c
TL
57 C_SafeCond(ceph::mutex& l, ceph::condition_variable& c, bool *d, int *r=0)
58 : lock(l), cond(c), done(d), rval(r) {
7c673cae
FG
59 *done = false;
60 }
61 void finish(int r) override {
9f95a23c 62 std::lock_guard l{lock};
7c673cae
FG
63 if (rval)
64 *rval = r;
65 *done = true;
9f95a23c 66 cond.notify_all();
7c673cae
FG
67 }
68};
69
70/**
71 * Context providing a simple wait() mechanism to wait for completion
72 *
73 * The context will not be deleted as part of complete and must live
74 * until wait() returns.
75 */
76class C_SaferCond : public Context {
9f95a23c
TL
77 ceph::mutex lock; ///< Mutex to take
78 ceph::condition_variable cond; ///< Cond to signal
79 bool done = false; ///< true after finish() has been called
80 int rval = 0; ///< return value
7c673cae 81public:
9f95a23c
TL
82 C_SaferCond() :
83 C_SaferCond("C_SaferCond")
84 {}
85 explicit C_SaferCond(const std::string &name)
86 : lock(ceph::make_mutex(name)) {}
7c673cae
FG
87 void finish(int r) override { complete(r); }
88
89 /// We overload complete in order to not delete the context
90 void complete(int r) override {
11fdf7f2 91 std::lock_guard l(lock);
7c673cae
FG
92 done = true;
93 rval = r;
9f95a23c 94 cond.notify_all();
7c673cae
FG
95 }
96
97 /// Returns rval once the Context is called
98 int wait() {
9f95a23c
TL
99 std::unique_lock l{lock};
100 cond.wait(l, [this] { return done;});
7c673cae
FG
101 return rval;
102 }
11fdf7f2
TL
103
104 /// Wait until the \c secs expires or \c complete() is called
105 int wait_for(double secs) {
f91f0fd5
TL
106 return wait_for(ceph::make_timespan(secs));
107 }
108
109 int wait_for(ceph::timespan secs) {
9f95a23c 110 std::unique_lock l{lock};
11fdf7f2
TL
111 if (done) {
112 return rval;
113 }
f91f0fd5 114 if (cond.wait_for(l, secs, [this] { return done; })) {
9f95a23c
TL
115 return rval;
116 } else {
117 return ETIMEDOUT;
118 }
11fdf7f2 119 }
7c673cae
FG
120};
121
122#endif