| /* |
| * Copyright 2015 Facebook, 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. |
| */ |
| |
| #pragma once |
| |
| #include <folly/futures/Promise.h> |
| |
| namespace folly { |
| |
| /// These classes help you wrap an existing C style callback function |
| /// into a Future. |
| /// |
| /// void legacy_send_async(..., void (*cb)(void*), void*); |
| /// |
| /// Future<T> wrappedSendAsync(T&& obj) { |
| /// auto handle = new OpaqueCallbackShunt<T>(obj); |
| /// auto future = handle->promise_.getFuture(); |
| /// legacy_send_async(..., OpaqueCallbackShunt<T>::callback, handle) |
| /// return future; |
| /// } |
| /// |
| /// If the legacy function doesn't conform to void (*cb)(void*), use a lambda: |
| /// |
| /// auto cb = [](t1*, t2*, void* arg) { |
| /// OpaqueCallbackShunt<T>::callback(arg); |
| /// }; |
| /// legacy_send_async(..., cb, handle); |
| |
| template <typename T> |
| class OpaqueCallbackShunt { |
| public: |
| explicit OpaqueCallbackShunt(T&& obj) |
| : obj_(std::move(obj)) { } |
| static void callback(void* arg) { |
| std::unique_ptr<OpaqueCallbackShunt<T>> handle( |
| static_cast<OpaqueCallbackShunt<T>*>(arg)); |
| handle->promise_.setValue(std::move(handle->obj_)); |
| } |
| folly::Promise<T> promise_; |
| private: |
| T obj_; |
| }; |
| |
| } // folly |