Blame view

3rdparty/boost_1_81_0/boost/process/v2/execute.hpp 3.84 KB
0b6a182c   Hu Chunming   添加无鉴权注册和注销
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  // Copyright (c) 2022 Klemens D. Morgenstern
  //
  // Distributed under the Boost Software License, Version 1.0. (See accompanying
  // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  #ifndef BOOST_PROCESS_V2_EXECUTE_HPP
  #define BOOST_PROCESS_V2_EXECUTE_HPP
  
  #include <boost/process/v2/process.hpp>
  
  #if defined(BOOST_PROCESS_V2_STANDALONE)
  #include <asio/bind_cancellation_slot.hpp>
  #else
  #include <boost/asio/bind_cancellation_slot.hpp>
  #endif
  
  BOOST_PROCESS_V2_BEGIN_NAMESPACE
  
  
  /**
   * @brief Run a process and wait for it to complete.
   * 
   * @tparam Executor The asio executor of the process handle
   * @param proc The process to be run.
   * @return int The exit code of the process
   * @exception system_error An error that might have occured during the wait.
   */
  template<typename Executor>
  inline int execute(basic_process<Executor> proc)
  {
      return proc.wait();
  }
  
  /** \overload int execute(const basic_process<Executor> proc) */
  template<typename Executor>
  inline int execute(basic_process<Executor> proc, error_code & ec)
  {
      return proc.wait(ec);
  }
  
  namespace detail
  {
  
  template<typename Executor>
  struct execute_op
  {
      std::unique_ptr<basic_process<Executor>> proc;
  
      struct cancel
      {
          using cancellation_type = BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_type;
          basic_process<Executor> * proc;
          cancel(basic_process<Executor> * proc) : proc(proc) {}
  
          void operator()(cancellation_type tp)
          {
              error_code ign;
              if ((tp & cancellation_type::total) != cancellation_type::none)
                  proc->interrupt(ign);
              else if ((tp & cancellation_type::partial) != cancellation_type::none)
                  proc->request_exit(ign);
              else if ((tp & cancellation_type::terminal) != cancellation_type::none)
                  proc->terminate(ign);
          }
      };
  
      template<typename Self>
      void operator()(Self && self)
      {
          self.reset_cancellation_state();
          BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_slot s = self.get_cancellation_state().slot();
          if (s.is_connected())
              s.emplace<cancel>(proc.get());
  
          auto pro_ = proc.get();
          pro_->async_wait(
                  BOOST_PROCESS_V2_ASIO_NAMESPACE::bind_cancellation_slot(
                      BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_slot(),
                      std::move(self)));
      }
  
      template<typename Self>
      void operator()(Self && self, error_code ec, int res)
      { 
          self.get_cancellation_state().slot().clear();
          self.complete(ec, res);
      }
  };
  
  }
  
  /// Execute a process asynchronously
  /** This function asynchronously for a process to complete.
   * 
   * Cancelling the execution will signal the child process to exit
   * with the following intepretations:
   * 
   *  - cancellation_type::total    -> interrupt
   *  - cancellation_type::partial  -> request_exit
   *  - cancellation_type::terminal -> terminate
   * 
   * It is to note that `async_execute` will us the lowest seelected cancellation 
   * type. A subprocess might ignore anything not terminal.
   */
  template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor,
          BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void (error_code, int))
              WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
  inline
  BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, int))
  async_execute(basic_process<Executor> proc,
                           WaitHandler && handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
  {
      std::unique_ptr<basic_process<Executor>> pro_(new basic_process<Executor>(std::move(proc)));
      auto exec = proc.get_executor();
      return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, int)>(
              detail::execute_op<Executor>{std::move(pro_)}, handler, exec);
  }
  
  BOOST_PROCESS_V2_END_NAMESPACE
  
  #endif //BOOST_PROCESS_V2_EXECUTE_HPP