Refactoring ORO_main [was: Segfault when calling an operation in OwnThread without TSLF initialized]

2011/6/9 Peter Soetens <peter [..] ...>

> On Thu, Jun 9, 2011 at 5:34 PM, Philippe Hamelin
> <philippe [dot] hamelin [..] ...> wrote:
> ...
> > 2011/6/9 Philippe Hamelin <philippe [dot] hamelin [..] ...>
> >> It crashed in oro_rt_malloc so I initialized the memory pool
> >> (init_memory_pool) and the problem is fixed. Why does calling an
> operation
> >> in the component thread require to initialize the TSLF memory pool?
> >>
> >
> > Ok I found why this is happening. The cloneRT() method, which seems to be
> > used for OperationCaller, makes use of the rt_allocator :
> > &#10;&gt; &gt; typename LocalOperationCallerImpl&lt;Signature&gt;::shared_ptr cloneRT() const&#10;&gt; &gt; {&#10;&gt; &gt;     //void* obj =&#10;&gt; &gt; oro_rt_malloc(sizeof(LocalOperationCallerImpl&lt;Signature&gt;));&#10;&gt; &gt;     //return new(obj) LocalOperationCaller&lt;Signature&gt;(*this);&#10;&gt; &gt;     return boost::allocate_shared&lt;LocalOperationCaller&lt;Signature&gt;&#10;&gt; &gt;&gt;(os::rt_allocator&lt;LocalOperationCaller&lt;Signature&gt; &gt;(), *this);&#10;&gt; &gt; }&#10;&gt; &gt;
> > So that means that if Orocos-RTT is compiled with RT_MALLOC support one
> > should always initialize the memory pool before doing anything. I thought
> > wrongly that TLSF was only used for real-time logging. This leads me to
> ask
> > some questions:
> > 1. Is this documented somewhere?
> It's enabled when using the deployers and can be configured using a command
> line option. It's not documented...
> > 2. Does ORO_main should do some default initialization (letting the user
> to
> > resize it afterwhile) of the memory pool if no parameters are given on
> the
> > command line?
> That code in the deployer could move to ORO_main... but it's some work
> since
> we also want to have the options show up when the program is run with
> --help, ie, using boost::program_options
I understand. Unfortunetly I don't have the time to do such a refactor for
now, so I will ensure in my client apps that the TLSF is initialized each
time orocos is used.

I would like to take this discussion about refactoring ORO_main to
propose a new approach, inspired from QT. This could look like:

&#10;class MyOrocosApp : public RTT::OroApplication&#10;{&#10;    // overloaded from OroApplication&#10;    int run(int argc, char **argv) {...}&#10;};&#10;&#10;int main(int argc, char **argv)&#10;{&#10;  MyOrocosApp oroApps(argc, argv);&#10;&#10;  return oroApps.exec();&#10;}&#10;

I see many advantages to that:

- We could remove the ORO_main macro or reduce it to something very simple
and thus allowing easier debugging.
- We could use boost::program_options to add all configurable settings of
orocos (e.g. TSLF memory pool) in a 'RTT' option group [1], still allowing
the user to provide additionnal options through boost::program_options.
- We could put default options value such as TLSF memory pool size and do
the initialization before executing any application-specific code.
- We could also handle the RTT_COMPONENT_PATH stuff, not only through an
environment variable but also through a program option.

To keep backward compatibility, we can still provide a ORO_main macro which
just wraps into the RTT::OroApplication::run(...) method.

What do you think?