Re: [boost] [gsoc] Boost.Process done

I noticed that the boost::process::child does not have a default constructor. If I have a coding requirements like the following example, I would be stuck: // Note the required default constructor boost::process::child child; // Create a scope for the mutex guard { boost::lock_guard<boost::mutex> guard(process_launch); // Here I must do something within guard scope // that must be done with the boost::process::launch do_something(); child = boost::process::launch(exec, args, ctx); } // ... boost::process::status s = child.wait(); // ...

Hi Claude, On Tue, Feb 1, 2011 at 2:37 PM, Claude Quézel <cquezel@gmail.com> wrote:
I noticed that the boost::process::child does not have a default constructor. If I have a coding requirements like the following example, I would be stuck:
// Note the required default constructor boost::process::child child;
// Create a scope for the mutex guard { boost::lock_guard<boost::mutex> guard(process_launch);
// Here I must do something within guard scope // that must be done with the boost::process::launch do_something();
child = boost::process::launch(exec, args, ctx); }
The author may have his own reasons for this, but making process::child default constructable would probably break an invariant. Some libraries choose to do so and add isValid() member functions to test for true initialization. In my experience this leads to lots of testing, asserts, and generally less readable code as those objects are passed to functions, etc. In the case you mentioned, you could declare a scoped_ptr<> to the child, or if you don't want dynamic memory allocations, a boost::optional<>. This would allow child to keep its invariants and use a well-known idiom for testing validity. HTH, Nate

On 01/02/2011 22:37, Claude Quézel wrote:
I noticed that the boost::process::child does not have a default constructor. If I have a coding requirements like the following example, I would be stuck:
// Note the required default constructor boost::process::child child;
// Create a scope for the mutex guard { boost::lock_guard<boost::mutex> guard(process_launch);
// Here I must do something within guard scope // that must be done with the boost::process::launch do_something();
child = boost::process::launch(exec, args, ctx); }
// ...
boost::process::status s = child.wait();
How about template<typename Lockable> struct lock_maybe_guard { explicit lock_maybe_guard(Lockable& m_) : m(m_), locked(false) { lock(); } void lock() { if(!locked) { m.lock(); locked = true; } } unlock() { if(locked) { m.unlock(); locked = false; } } ~lock_guard() { unlock(); } private: Lockable& m; bool locked; }; boost::process::child child; lock_maybe_guard<boost::mutex> guard(process_launch); // Here I must do something within guard scope // that must be done with the boost::process::launch do_something(); guard.unlock(); child = boost::process::launch(exec, args, ctx);

Mathias Gaunard wrote:
On 01/02/2011 22:37, Claude Quézel wrote:
I noticed that the boost::process::child does not have a default constructor. If I have a coding requirements like the following example, I would be stuck:
// Note the required default constructor boost::process::child child; { boost::lock_guard<boost::mutex> guard(process_launch); [snip] child = boost::process::launch(exec, args, ctx); }
How about
template<typename Lockable> struct lock_maybe_guard { [snip] };
boost::process::child child;
The default ctor is still needed, which was the OP's concern. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

The code is not exception safe if you have to call unlock explicitly. Claude 2011/2/2 Mathias Gaunard <mathias.gaunard@ens-lyon.org>
On 01/02/2011 22:37, Claude Quézel wrote:
I noticed that the boost::process::child does not have a default constructor. If I have a coding requirements like the following example, I would be stuck:
// Note the required default constructor boost::process::child child;
// Create a scope for the mutex guard { boost::lock_guard<boost::mutex> guard(process_launch);
// Here I must do something within guard scope // that must be done with the boost::process::launch do_something();
child = boost::process::launch(exec, args, ctx); }
// ...
boost::process::status s = child.wait();
How about
template<typename Lockable> struct lock_maybe_guard { explicit lock_maybe_guard(Lockable& m_) : m(m_), locked(false) { lock(); }
void lock() { if(!locked) { m.lock(); locked = true; } }
unlock() { if(locked) { m.unlock(); locked = false; } }
~lock_guard() { unlock(); }
private: Lockable& m; bool locked; };
boost::process::child child;
lock_maybe_guard<boost::mutex> guard(process_launch);
// Here I must do something within guard scope // that must be done with the boost::process::launch do_something();
guard.unlock();
child = boost::process::launch(exec, args, ctx);
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Claude Quézel wrote:
The code is not exception safe if you have to call unlock explicitly.
Please don't top post (<http://www.boost.org/community/policy.html#quoting>).
2011/2/2 Mathias Gaunard <mathias.gaunard@ens-lyon.org> [snip]
boost::process::child child; lock_maybe_guard<boost::mutex> guard(process_launch); do_something(); guard.unlock(); child = boost::process::launch(exec, args, ctx);
The last two lines should be reversed to get the desired effect. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On Tue, 01 Feb 2011 22:37:59 +0100, Claude Quézel <cquezel@gmail.com> wrote:
I noticed that the boost::process::child does not have a default constructor. If I have a coding requirements like the following example, I would be stuck:
// Note the required default constructor boost::process::child child;
If I remember correctly, originally the idea was that a child instance always represents a live child process. You would always need to use a factory function like create_child() to get a child instance. But then of course when a child process terminates a child instance does not automatically disappear. So it's a bit difficult to argue against a default constructor on that ground. :) Looking at the code I think it should be no problem either to add a default constructor (also to child's parent class process). If it helps and if there is no good reason against it I'll add a default constructor? Boris
[...]
participants (6)
-
Boris Schaeling
-
Claude Quézel
-
Claude Quézel
-
Mathias Gaunard
-
Nathan Crookston
-
Stewart, Robert