Skip to content

Virtualise initializers #2

@hotgloupi

Description

@hotgloupi

First of all, thanks for the good work here, the API is very clean, and yet extensible and practical, which is a good thing when trying to abstract something so different across OSes.

However, I don't fully understand why the code is so much static. Why did you choose to use compile time polymorphism (i.e. templates) instead of runtime polymorphism (i.e. vtables) ? IMHO the overhead of spawning a process makes the cost of a vtable access ridiculous.

My problem, somewhat related to the previous question, is how to create a set of initializers, and then spawn a process. I would like to do something like:

std::vector<Initializer> initializers;
if (some_condition)
    initializers.push_back(some_initializer);
auto child = boost::process::executor()(args, initializers);

In order to create the type Initializer, I would have to do complicated things:

template<typename Executor>
struct InitializerBase
{
      virtual void on_fork_setup(Executor& e) = 0;
     // ... other methods here
};

template<typename Executor, typename ConcreteInitializer>
struct InitializerWrapper : InitializerBase<Executor>
{
    ConcreteInitializer _initializer;
    template<typename... Args
    explicit InitializerWrapper(Args&&... args)
        : _initializer(std::forward<Args>(args)...)
    {}
    void on_fork_setup(Executor& e) override { _initializer.on_fork_setup(e); }
     // ... other methods here
};

template<typename Executor>
struct _Initializer
{
    typedef Executor executor_type;
    std::unique_ptr<InitializerBase> _initializer;
    void on_fork_setup(Executor& e) { _initializer.on_fork_setup(e); }
   // ... other methods here
}

#ifdef POSIX_SOMETHING
typedef _Initializer<PosixExecutor> Initializer;
#else
// something else
#endif

template<typename ConcreteInitializer, typename... Args>
Initializer make_initializer(Args&&... args)
{
  return Initializer(new InitializerWrapper<typename Initializer::executor_type, ConcreteInitializer>(
     std::forward<Args>(args)...);
}

(I omitted the boilerplate code for constructors and destructors)

That's pretty much re-virtualizing your code ... Do you know a better way ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions