Fix copyright lines
[folly.git] / folly / futures / SharedPromise.h
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <folly/Portability.h>
20 #include <folly/executors/InlineExecutor.h>
21 #include <folly/futures/Promise.h>
22
23 namespace folly {
24
25 /*
26  * SharedPromise provides the same interface as Promise, but you can extract
27  * multiple Futures from it, i.e. you can call getFuture() as many times as
28  * you'd like. When the SharedPromise is fulfilled, all of the Futures will be
29  * called back. Calls to getFuture() after the SharedPromise is fulfilled return
30  * a completed Future. If you find yourself constructing collections of Promises
31  * and fulfilling them simultaneously with the same value, consider this
32  * utility instead. Likewise, if you find yourself in need of setting multiple
33  * callbacks on the same Future (which is indefinitely unsupported), consider
34  * refactoring to use SharedPromise to "split" the Future.
35  */
36 template <class T>
37 class SharedPromise {
38  public:
39   SharedPromise() = default;
40   ~SharedPromise() = default;
41
42   // not copyable
43   SharedPromise(SharedPromise const&) = delete;
44   SharedPromise& operator=(SharedPromise const&) = delete;
45
46   // movable
47   SharedPromise(SharedPromise<T>&&) noexcept;
48   SharedPromise& operator=(SharedPromise<T>&&) noexcept;
49
50   /**
51    * Return a Future tied to the shared core state. Unlike Promise::getFuture,
52    * this can be called an unlimited number of times per SharedPromise.
53    */
54   SemiFuture<T> getSemiFuture();
55
56   /**
57    * Return a Future tied to the shared core state. Unlike Promise::getFuture,
58    * this can be called an unlimited number of times per SharedPromise.
59    * NOTE: This function is deprecated. Please use getSemiFuture and pass the
60    *       appropriate executor to .via on the returned SemiFuture to get a
61    *       valid Future where necessary.
62    */
63   Future<T> getFuture();
64
65   /** Return the number of Futures associated with this SharedPromise */
66   size_t size();
67
68   /** Fulfill the SharedPromise with an exception_wrapper */
69   void setException(exception_wrapper ew);
70
71   /** Fulfill the SharedPromise with an exception_ptr, e.g.
72     try {
73       ...
74     } catch (...) {
75       p.setException(std::current_exception());
76     }
77     */
78   FOLLY_DEPRECATED("use setException(exception_wrapper)")
79   void setException(std::exception_ptr const&);
80
81   /** Fulfill the SharedPromise with an exception type E, which can be passed to
82     std::make_exception_ptr(). Useful for originating exceptions. If you
83     caught an exception the exception_wrapper form is more appropriate.
84     */
85   template <class E>
86   typename std::enable_if<std::is_base_of<std::exception, E>::value>::type
87   setException(E const&);
88
89   /// Set an interrupt handler to handle interrupts. See the documentation for
90   /// Future::raise(). Your handler can do whatever it wants, but if you
91   /// bother to set one then you probably will want to fulfill the SharedPromise with
92   /// an exception (or special value) indicating how the interrupt was
93   /// handled.
94   void setInterruptHandler(std::function<void(exception_wrapper const&)>);
95
96   /// Sugar to fulfill this SharedPromise<Unit>
97   template <class B = T>
98   typename std::enable_if<std::is_same<Unit, B>::value, void>::type
99   setValue() {
100     setTry(Try<T>(T()));
101   }
102
103   /** Set the value (use perfect forwarding for both move and copy) */
104   template <class M>
105   void setValue(M&& value);
106
107   void setTry(Try<T>&& t);
108
109   /** Fulfill this SharedPromise with the result of a function that takes no
110     arguments and returns something implicitly convertible to T.
111     Captures exceptions. e.g.
112
113     p.setWith([] { do something that may throw; return a T; });
114   */
115   template <class F>
116   void setWith(F&& func);
117
118   bool isFulfilled();
119
120  private:
121   std::mutex mutex_;
122   size_t size_{0};
123   bool hasValue_{false};
124   Try<T> try_;
125   std::vector<Promise<T>> promises_;
126   std::function<void(exception_wrapper const&)> interruptHandler_;
127 };
128
129 } // namespace folly
130
131 #include <folly/futures/Future.h>
132 #include <folly/futures/SharedPromise-inl.h>