From 0a9f3bc08e0ddec926411db5958b83449ce27e75 Mon Sep 17 00:00:00 2001 From: Sven Over Date: Fri, 22 Apr 2016 11:00:39 -0700 Subject: [PATCH] Subprocess: allow non-copyable callbacks Summary:Instead of std::function, use folly::Function to pass callbacks to Subprocess::communicate. This makes it possible to pass non-copyable callables, which is especially interesting because Subprocess::readLinesCallback returns a non-copyable object. This diff also fixes the forwarding of the callback passed to readLinesCallback in case you pass an lvalue reference. Reviewed By: snarkmaster Differential Revision: D3169956 fb-gh-sync-id: 7a906f9a3ab50502fc04e0d83a23ca5e0201bb3e fbshipit-source-id: 7a906f9a3ab50502fc04e0d83a23ca5e0201bb3e --- folly/Subprocess.h | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/folly/Subprocess.h b/folly/Subprocess.h index 2b6cbffc..e922ee0d 100644 --- a/folly/Subprocess.h +++ b/folly/Subprocess.h @@ -111,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -613,7 +614,7 @@ class Subprocess { * expensive implementation choice, in order to make closeParentFd() * thread-safe. */ - typedef std::function FdCallback; + using FdCallback = folly::Function; void communicate(FdCallback readCallback, FdCallback writeCallback); /** @@ -622,17 +623,13 @@ class Subprocess { * descriptors. Use the readLinesCallback() helper to get template * deduction. For example: * - * auto read_cb = Subprocess::readLinesCallback( - * [](int fd, folly::StringPiece s) { - * std::cout << fd << " said: " << s; - * return false; // Keep reading from the child - * } - * ); * subprocess.communicate( - * // ReadLinesCallback contains StreamSplitter contains IOBuf, making - * // it noncopyable, whereas std::function must be copyable. So, we - * // keep the callback in a local, and instead pass a reference. - * std::ref(read_cb), + * Subprocess::readLinesCallback( + * [](int fd, folly::StringPiece s) { + * std::cout << fd << " said: " << s; + * return false; // Keep reading from the child + * } + * ), * [](int pdf, int cfd){ return true; } // Don't write to the child * ); * @@ -706,14 +703,14 @@ class Subprocess { // Helper to enable template deduction template - static ReadLinesCallback readLinesCallback( + static auto readLinesCallback( Callback&& fdLineCb, - uint64_t maxLineLength = 0, // No line length limit by default + uint64_t maxLineLength = 0, // No line length limit by default char delimiter = '\n', - uint64_t bufSize = 1024) { - return ReadLinesCallback( - std::move(fdLineCb), maxLineLength, delimiter, bufSize - ); + uint64_t bufSize = 1024) + -> ReadLinesCallback::type> { + return ReadLinesCallback::type>( + std::forward(fdLineCb), maxLineLength, delimiter, bufSize); } /** -- 2.34.1