blob: 2bf7e799e9231d92f73169515cbe31d87cc35da9 [file] [log] [blame]
// Copyright 2014 Cloudera, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef KUDU_UTIL_PROMISE_H
#define KUDU_UTIL_PROMISE_H
#include "kudu/gutil/macros.h"
#include "kudu/util/countdown_latch.h"
namespace kudu {
// A promise boxes a value which is to be provided at some time in the future.
// A single producer calls Set(...), and any number of consumers can call Get()
// to retrieve the produced value.
//
// In Guava terms, this is a SettableFuture<T>.
template<typename T>
class Promise {
public:
Promise() : latch_(1) {}
~Promise() {}
// Reset the promise to be used again.
// For this to be safe, there must be some kind of external synchronization
// ensuring that no threads are still accessing the value from the previous
// incarnation of the promise.
void Reset() {
latch_.Reset(1);
val_ = T();
}
// Block until a value is available, and return a reference to it.
const T& Get() const {
latch_.Wait();
return val_;
}
// Wait for the promised value to become available with the given timeout.
//
// Returns NULL if the timeout elapses before a value is available.
// Otherwise returns a pointer to the value. This pointer's lifetime is
// tied to the lifetime of the Promise object.
const T* WaitFor(const MonoDelta& delta) const {
if (latch_.WaitFor(delta)) {
return &val_;
} else {
return NULL;
}
}
// Set the value of this promise.
// This may be called at most once.
void Set(const T& val) {
DCHECK_EQ(latch_.count(), 1) << "Already set!";
val_ = val;
latch_.CountDown();
}
private:
CountDownLatch latch_;
T val_;
DISALLOW_COPY_AND_ASSIGN(Promise);
};
} // namespace kudu
#endif /* KUDU_UTIL_PROMISE_H */