Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:14

0001 // Copyright (c) 2016 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 /**
0007  * \file boost/process/group.hpp
0008  *
0009  * Defines a group process class.
0010  * For additional information see the platform specific implementations:
0011  *
0012  *   - [windows - job object](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684161.aspx)
0013  *   - [posix - process group](http://pubs.opengroup.org/onlinepubs/009695399/functions/setpgid.html)
0014  *
0015  */
0016 
0017 #ifndef BOOST_PROCESS_GROUP_HPP
0018 #define BOOST_PROCESS_GROUP_HPP
0019 
0020 #include <boost/process/detail/config.hpp>
0021 #include <boost/process/child.hpp>
0022 #include <chrono>
0023 #include <memory>
0024 
0025 #include <boost/none.hpp>
0026 #include <atomic>
0027 
0028 
0029 #if defined(BOOST_POSIX_API)
0030 #include <boost/process/detail/posix/group_handle.hpp>
0031 #include <boost/process/detail/posix/group_ref.hpp>
0032 #include <boost/process/detail/posix/wait_group.hpp>
0033 #elif defined(BOOST_WINDOWS_API)
0034 #include <boost/process/detail/windows/group_handle.hpp>
0035 #include <boost/process/detail/windows/group_ref.hpp>
0036 #include <boost/process/detail/windows/wait_group.hpp>
0037 #endif
0038 
0039 namespace boost {
0040 
0041 namespace process {
0042 
0043 namespace detail {
0044     struct group_builder;
0045 }
0046 
0047 /**
0048  * Represents a process group.
0049  *
0050  * Groups are movable but non-copyable. The destructor
0051  * automatically closes handles to the group process.
0052  *
0053  * The group will have the same interface as std::thread.
0054  *
0055  * \note If the destructor is called without a previous detach or wait, the group will be terminated.
0056  *
0057  * \attention If a default-constructed group is used before being used in a process launch, the behaviour is undefined.
0058  *
0059  * \attention Waiting for groups is currently broken on windows and will most likely result in a dead-lock.
0060  */
0061 class group
0062 {
0063     ::boost::process::detail::api::group_handle _group_handle;
0064     bool _attached = true;
0065 public:
0066     typedef ::boost::process::detail::api::group_handle group_handle;
0067     ///Native representation of the handle.
0068     typedef group_handle::handle_t native_handle_t;
0069     explicit group(group_handle &&ch) : _group_handle(std::move(ch)) {}
0070     ///Construct the group from a native_handle
0071     explicit group(native_handle_t & handle) : _group_handle(handle) {};
0072     group(const group&) = delete;
0073     ///Move constructor
0074     group(group && lhs)
0075         : _group_handle(std::move(lhs._group_handle)),
0076           _attached (lhs._attached)
0077     {
0078         lhs._attached = false;
0079     }
0080     ///Default constructor
0081     group() = default;
0082     group& operator=(const group&) = delete;
0083     ///Move assign
0084     group& operator=(group && lhs)
0085     {
0086         _group_handle= std::move(lhs._group_handle);
0087         _attached    = lhs._attached;
0088 
0089         return *this;
0090     };
0091 
0092     ///Detach the group
0093     void detach() {_attached = false; }
0094 
0095     /** Join the child. This just calls wait, but that way the naming is similar to std::thread */
0096     void join() {wait();}
0097     /** Check if the child is joinable. */
0098     bool joinable() {return _attached;}
0099 
0100     /** Destructor
0101      *
0102      * \note If the destructor is called without a previous detach or wait, the group will be terminated.
0103      *
0104      */
0105     ~group()
0106     {
0107         std::error_code ec;
0108         if ( _attached && valid())
0109             terminate(ec);
0110     }
0111 
0112     ///Obtain the native handle of the group.
0113     native_handle_t native_handle() const { return _group_handle.handle(); }
0114 
0115     ///Wait for the process group to exit.
0116     void wait()
0117     {
0118         boost::process::detail::api::wait(_group_handle);
0119     }
0120     ///\overload void wait()
0121     void wait(std::error_code & ec) noexcept
0122     {
0123         boost::process::detail::api::wait(_group_handle, ec);
0124     }
0125 #if !defined(BOOST_PROCESS_NO_DEPRECATED)
0126     /** Wait for the process group to exit for period of time.
0127       *  \return True if all child processes exited while waiting.*/
0128     template< class Rep, class Period >
0129     BOOST_DEPRECATED("wait_for is unreliable")
0130     bool wait_for  (const std::chrono::duration<Rep, Period>& rel_time)
0131     {
0132         return boost::process::detail::api::wait_for(_group_handle, rel_time);
0133     }
0134 
0135     /** \overload bool wait_for(const std::chrono::duration<Rep, Period>& timeout_time ) */
0136     template< class Rep, class Period >
0137     BOOST_DEPRECATED("wait_for is unreliable")
0138     bool wait_for  (const std::chrono::duration<Rep, Period>& rel_time, std::error_code & ec) noexcept
0139     {
0140         return boost::process::detail::api::wait_for(_group_handle, rel_time, ec);
0141     }
0142 
0143     /** Wait for the process group to exit until a point in time.
0144       *  \return True if all child processes exited while waiting.*/
0145     template< class Clock, class Duration >
0146     BOOST_DEPRECATED("wait_until is unreliable")
0147     bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time )
0148     {
0149         return boost::process::detail::api::wait_until(_group_handle, timeout_time);
0150     }
0151     /** \overload bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time ) */
0152     template< class Clock, class Duration >
0153     BOOST_DEPRECATED("wait_until is unreliable")
0154     bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, std::error_code & ec) noexcept
0155     {
0156         return boost::process::detail::api::wait_until(_group_handle, timeout_time, ec);
0157     }
0158 #endif
0159     ///Check if the group has a valid handle.
0160     bool valid() const
0161     {
0162         return _group_handle.valid();
0163     }
0164     ///Convenience to call valid.
0165     explicit operator bool() const {return valid();}
0166 
0167     ///Terminate the process group, i.e. all processes in the group
0168     void terminate()
0169     {
0170         ::boost::process::detail::api::terminate(_group_handle);
0171     }
0172     ///\overload void terminate()
0173     void terminate(std::error_code & ec) noexcept
0174     {
0175         ::boost::process::detail::api::terminate(_group_handle, ec);
0176     }
0177 
0178     ///Assign a child process to the group
0179     void add(const child &c)
0180     {
0181         _group_handle.add(c.native_handle());
0182     }
0183     ///\overload void assign(const child & c)
0184     void add(const child &c, std::error_code & ec) noexcept
0185     {
0186         _group_handle.add(c.native_handle(), ec);
0187     }
0188 
0189     ///Check if the child process is in the group
0190     bool has(const child &c)
0191     {
0192         return _group_handle.has(c.native_handle());
0193     }
0194     ///\overload bool has(const child &)
0195     bool has(const child &c, std::error_code & ec) noexcept
0196     {
0197         return _group_handle.has(c.native_handle(), ec);
0198 
0199     }
0200 
0201     friend struct detail::group_builder;
0202 };
0203 
0204 namespace detail
0205 {
0206 
0207 struct group_tag;
0208 struct group_builder
0209 {
0210     group * group_p;
0211 
0212     void operator()(group & grp) {this->group_p = &grp;};
0213 
0214     typedef api::group_ref result_type;
0215     api::group_ref get_initializer() {return api::group_ref (group_p->_group_handle);};
0216 };
0217 
0218 template<>
0219 struct initializer_tag<group>
0220 {
0221     typedef group_tag type;
0222 };
0223 
0224 template<>
0225 struct initializer_builder<group_tag>
0226 {
0227     typedef group_builder type;
0228 };
0229 
0230 }
0231 }}
0232 #endif
0233