Efficient UNO component linkage & GC ...

Stephan Bergmann sbergman at redhat.com
Thu Dec 19 01:51:56 PST 2013


thought-dump:

* loader != "com.sun.star.loader.SharedLibrary" (i.e., Java, Python, 
...) remains unchanged

* external code (extensions) remains unchanged (i.e., stuck with the 
original .component XML format for now; no prefix="...", 
extension="...", constructor="..."; mandatory 
component_getImplementationEnvironment); this allows to experiment with 
the new features internally

* assume all LO-internal C++ implementations are ComponentContext-based 
(i.e., use cppu::createSingleComponentFactory or 
cppu::createOneInstanceComponentFactory rather than legacy 
ServiceManager-based cppu::createSingleFactory or 
cppu::createOneInstanceFactory); reaching this state is effectively an 
easy hack

* implementations of non-single-instance services can be rewritten using 
the new .component XML <implementation constructor="..." feature, cf. 
<http://cgit.freedesktop.org/libreoffice/core/commit/?id=ae3a0c8da50b36db395984637f5ad74d3b4887bc> 
"Add .component <implementation constructor='...' feature"; this is 
effectively an easy hack (note that service manager's 
createInstanceWithArguments[andContext] no longer uses the 
css.lang.XInitialization protocol on those implementations)

* for implementations of single-instance services/singletons, we can:

** either stick with the recently introduced prefix="direct" feature, 
where the service manager obtains a factory for them; any instantiated 
object instances will continue to be disposed well ahead of exit via 
disposing the ComponentContext in desktop::Desktop::DeInit 
(desktop/source/app/app.cxx)

** or also use the constructor="..." feature, in which case the 
individual constructor functions would need to hold a single instance, 
which could postpone that instance's destruction to atexit, with all 
dreaded consequences (an option might be to hold the single instance weakly)

** or use some <implementation single-instance="true" flag in .component 
XML and implement the logic of holding a single instance in the service 
manager, which would dispose them when it gets disposed well ahead of exit

* next step is to let certain occurrences of UNO service constructor 
(and singleton getter) calls in C++ code call corresponding constructor 
functions directly (instead of going via service manager's 
createInstanceWith[ArgumentsAnd]Context); conditions under which this 
simplification can be done:

** caller and implementation use the same environment (e.g., both gcc3; 
this is not the case e.g. for 
connectivity/source/drivers/jdbc/jdbc.component's 
environment="@CPPU_ENV@:affine")

** and caller knows that the constructor function is visible (i.e., the 
library/executable supplying it is loaded)

** note that there are always situations where UNO services are not 
called via constructor, though; e.g., the constructor-less 
css.uri.UriSchemeParser_* services are always created via dynamically 
computed name

* idea is to set aside for every UNO service/singleton S two macros 
LO_URE_CTOR_ENV_<S'> and LO_URE_CTOR_FUN_<S'>, and a macro 
LO_URE_CURRENT_ENV, and modify cppumaker to generate constructor code as

> #if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_<S'> \
>     && defined LO_URE_CTOR_FUN<S'> && LO_URE_CURRENT_ENV == LO_URE_CTOR_ENV_<S'>
>
> extern "C" cppu::ConstructorFunction_type LO_URE_CTOR_FUN<S'>;
>
> static css::uno::Reference<X> S::create(
>     css::uno::Reference<css::uno::XComponentContext> const & the_context)
> {
>     return LO_URE_CTOR_FUN<S'>(
>         the_context, css::uno::Sequence<css::uno::Any>());
> }
>
> #else
>
> // ... existing code ...
>
> #endif

and

** when compiling .cxx files for which the env in which they will be run 
is statically known (which could e.g. be the case for /every/ .cxx file 
for Android/iOS when we restrict ourselves to just that env there, as we 
already effectively do), pass -DLO_URE_CURRENT_ENV=...

** when compiling .cxx files for which it is known that the constructor 
function for some S will be visible (which could e.g. be ~always the 
case when compiling for a single big executable on Android/iOS), define 
the LO_URE_CTOR_ENV_<S'> and LO_URE_CTOR_FUN_<S'> macros, either via -D 
or via some strategically included header

where S' is some schema to convert UNOIDL service/singleton names into 
legal yet unambiguous parts of C++ identifiers, and the encoding of 
environments (which are normally strings) in LO_URE_CURRENT_ENV and 
LO_URE_CTOR_ENV_<S'> macros must be such that they can be used in the 
preprocessor == expression above

Stephan


More information about the LibreOffice mailing list