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 :
> >

> > typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const
> > {
> >     //void* obj =
> > oro_rt_malloc(sizeof(LocalOperationCallerImpl<Signature>));
> >     //return new(obj) LocalOperationCaller<Signature>(*this);
> >     return boost::allocate_shared<LocalOperationCaller<Signature>
> >>(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
> > }
> > 

> > 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:

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

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?

[1]
http://www.boost.org/doc/libs/1_46_1/doc/html/program_options/howto.html...

Philippe