aboutsummaryrefslogtreecommitdiff
path: root/build2/test/script/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'build2/test/script/builtin')
-rw-r--r--build2/test/script/builtin40
1 files changed, 31 insertions, 9 deletions
diff --git a/build2/test/script/builtin b/build2/test/script/builtin
index 226a0e0..7d902ea 100644
--- a/build2/test/script/builtin
+++ b/build2/test/script/builtin
@@ -18,26 +18,48 @@ namespace build2
{
class scope;
+ // A process/thread-like object representing a running builtin.
+ //
+ // For now, instead of allocating the result storage dynamically, we
+ // expect it to be provided by the caller.
+ //
+ class builtin
+ {
+ public:
+ uint8_t
+ wait () {if (t_.joinable ()) t_.join (); return r_;}
+
+ ~builtin () {wait ();}
+
+ public:
+ builtin (uint8_t& r, thread&& t = thread ()): r_ (r), t_ (move (t)) {}
+
+ builtin (builtin&&) = default;
+ builtin& operator= (builtin&&) = default;
+
+ private:
+ uint8_t& r_;
+ thread t_;
+ };
+
// Start builtin command. Throw system_error on failure.
//
// Note that unlike argc/argv, our args don't include the program name.
//
- // Also note that the future object being returned doesn't block in dtor
- // until the builtin command terminates.
- //
- using builtin = future<uint8_t> (scope&,
- const strings& args,
- auto_fd in, auto_fd out, auto_fd err);
+ using builtin_func = builtin (scope&,
+ uint8_t& result,
+ const strings& args,
+ auto_fd in, auto_fd out, auto_fd err);
- class builtin_map: public std::map<string, builtin*>
+ class builtin_map: public std::map<string, builtin_func*>
{
public:
- using base = std::map<string, builtin*>;
+ using base = std::map<string, builtin_func*>;
using base::base;
// Return NULL if not a builtin.
//
- builtin*
+ builtin_func*
find (const string& n) const
{
auto i (base::find (n));