81fa04f63e6450c3db3c25ccbb7466ae4aa73ee8
[folly.git] / folly / futures / OpaqueCallbackShunt.h
1 /*
2  * Copyright 2017 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/futures/Promise.h>
20
21 namespace folly {
22
23 /// These classes help you wrap an existing C style callback function
24 /// into a Future.
25 ///
26 ///   void legacy_send_async(..., void (*cb)(void*), void*);
27 ///
28 ///   Future<T> wrappedSendAsync(T&& obj) {
29 ///     auto handle = new OpaqueCallbackShunt<T>(obj);
30 ///     auto future = handle->promise_.getFuture();
31 ///     legacy_send_async(..., OpaqueCallbackShunt<T>::callback, handle)
32 ///     return future;
33 ///   }
34 ///
35 /// If the legacy function doesn't conform to void (*cb)(void*), use a lambda:
36 ///
37 ///   auto cb = [](t1*, t2*, void* arg) {
38 ///     OpaqueCallbackShunt<T>::callback(arg);
39 ///   };
40 ///   legacy_send_async(..., cb, handle);
41
42 template <typename T>
43 class OpaqueCallbackShunt {
44 public:
45   explicit OpaqueCallbackShunt(T&& obj)
46     : obj_(std::move(obj)) { }
47   static void callback(void* arg) {
48     std::unique_ptr<OpaqueCallbackShunt<T>> handle(
49       static_cast<OpaqueCallbackShunt<T>*>(arg));
50     handle->promise_.setValue(std::move(handle->obj_));
51   }
52   folly::Promise<T> promise_;
53 private:
54   T obj_;
55 };
56
57 } // folly