blob: 820cdb6697df347230fd2415f02319698816d46e [file] [log] [blame]
/*
* 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