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