Commit 0a9f3bc0 authored by Sven Over's avatar Sven Over Committed by Facebook Github Bot 6

Subprocess: allow non-copyable callbacks

Summary:Instead of std::function<bool(int, int)>, 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
parent 12244d01
...@@ -111,6 +111,7 @@ ...@@ -111,6 +111,7 @@
#include <folly/Exception.h> #include <folly/Exception.h>
#include <folly/File.h> #include <folly/File.h>
#include <folly/FileUtil.h> #include <folly/FileUtil.h>
#include <folly/Function.h>
#include <folly/gen/String.h> #include <folly/gen/String.h>
#include <folly/io/IOBufQueue.h> #include <folly/io/IOBufQueue.h>
#include <folly/MapUtil.h> #include <folly/MapUtil.h>
...@@ -613,7 +614,7 @@ class Subprocess { ...@@ -613,7 +614,7 @@ class Subprocess {
* expensive implementation choice, in order to make closeParentFd() * expensive implementation choice, in order to make closeParentFd()
* thread-safe. * thread-safe.
*/ */
typedef std::function<bool(int, int)> FdCallback; using FdCallback = folly::Function<bool(int, int)>;
void communicate(FdCallback readCallback, FdCallback writeCallback); void communicate(FdCallback readCallback, FdCallback writeCallback);
/** /**
...@@ -622,17 +623,13 @@ class Subprocess { ...@@ -622,17 +623,13 @@ class Subprocess {
* descriptors. Use the readLinesCallback() helper to get template * descriptors. Use the readLinesCallback() helper to get template
* deduction. For example: * 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( * subprocess.communicate(
* // ReadLinesCallback contains StreamSplitter contains IOBuf, making * Subprocess::readLinesCallback(
* // it noncopyable, whereas std::function must be copyable. So, we * [](int fd, folly::StringPiece s) {
* // keep the callback in a local, and instead pass a reference. * std::cout << fd << " said: " << s;
* std::ref(read_cb), * return false; // Keep reading from the child
* }
* ),
* [](int pdf, int cfd){ return true; } // Don't write to the child * [](int pdf, int cfd){ return true; } // Don't write to the child
* ); * );
* *
...@@ -706,14 +703,14 @@ class Subprocess { ...@@ -706,14 +703,14 @@ class Subprocess {
// Helper to enable template deduction // Helper to enable template deduction
template <class Callback> template <class Callback>
static ReadLinesCallback<Callback> readLinesCallback( static auto readLinesCallback(
Callback&& fdLineCb, 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', char delimiter = '\n',
uint64_t bufSize = 1024) { uint64_t bufSize = 1024)
return ReadLinesCallback<Callback>( -> ReadLinesCallback<typename std::decay<Callback>::type> {
std::move(fdLineCb), maxLineLength, delimiter, bufSize return ReadLinesCallback<typename std::decay<Callback>::type>(
); std::forward<Callback>(fdLineCb), maxLineLength, delimiter, bufSize);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment