blob: 17f8cecc4fae2208bfbfbef6d70e796a0e320a44 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 */