In "unopkg gui" dispose component context from DeInitVCL

...the same way it is done in soffice.bin.  framework's Desktop::dispose()
requires the solar mutex to be still alive, which is destroyed in DeInitVCL, so
if the component context/service manager is only disposed afterwards, the solar
mutex is already gone.

This required moving disposeBridges() around, but it allowed to get rid of
DisposeGuard.

Change-Id: Ibec3d19040fdae23f492cd1e29084e673403e00b
diff --git a/desktop/source/deployment/gui/dp_gui_service.cxx b/desktop/source/deployment/gui/dp_gui_service.cxx
index 71c6ccd..7c83aab 100644
--- a/desktop/source/deployment/gui/dp_gui_service.cxx
+++ b/desktop/source/deployment/gui/dp_gui_service.cxx
@@ -33,6 +33,7 @@
#include "cppuhelper/implbase2.hxx"
#include "cppuhelper/implementationentry.hxx"
#include "unotools/configmgr.hxx"
#include "comphelper/processfactory.hxx"
#include "comphelper/servicedecl.hxx"
#include "comphelper/unwrapargs.hxx"
#include <i18npool/mslangid.hxx>
@@ -66,6 +67,7 @@ public:

    // Application
    virtual int Main();
    virtual void DeInit();
};

//______________________________________________________________________________
@@ -84,6 +86,15 @@ int MyApp::Main()
    return EXIT_SUCCESS;
}

void MyApp::DeInit()
{
    css::uno::Reference< css::uno::XComponentContext > context(
        comphelper::getProcessComponentContext());
    dp_misc::disposeBridges(context);
    css::uno::Reference< css::lang::XComponent >(
        context, css::uno::UNO_QUERY_THROW)->dispose();
    comphelper::setProcessServiceFactory(0);
}

namespace
{
diff --git a/desktop/source/deployment/inc/dp_misc.h b/desktop/source/deployment/inc/dp_misc.h
index 248b81f..cf17cb5 100644
--- a/desktop/source/deployment/inc/dp_misc.h
+++ b/desktop/source/deployment/inc/dp_misc.h
@@ -159,6 +159,14 @@ void syncRepositories(
    ::com::sun::star::uno::Reference<
        ::com::sun::star::ucb::XCommandEnvironment> const & xCmdEnv);

/** workaround: for some reason the bridge threads which communicate with the
    uno.exe process are not released on time
*/
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
void disposeBridges(
    com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
        const & ctx);

}

#endif
diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx
index 31cb38c..55d3724 100644
--- a/desktop/source/deployment/misc/dp_misc.cxx
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -41,6 +41,7 @@
#include "osl/mutex.hxx"
#include "com/sun/star/ucb/CommandAbortedException.hpp"
#include "com/sun/star/task/XInteractionHandler.hpp"
#include "com/sun/star/bridge/BridgeFactory.hpp"
#include "com/sun/star/bridge/UnoUrlResolver.hpp"
#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
#include "com/sun/star/deployment/ExtensionManager.hpp"
@@ -586,7 +587,28 @@ void syncRepositories(
     }
}

void disposeBridges(Reference<css::uno::XComponentContext> const & ctx)
{
    if (!ctx.is())
        return;

    Reference<css::bridge::XBridgeFactory2> bridgeFac( css::bridge::BridgeFactory::create(ctx) );

    const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
    for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
    {
        Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
        if (comp.is())
        {
            try {
                comp->dispose();
            }
            catch ( const css::lang::DisposedException& )
            {
            }
        }
    }
}

}

diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
index c3387f0..db3f658 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_app.cxx
+++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
@@ -48,11 +48,9 @@

#include "com/sun/star/deployment/ui/PackageManagerDialog.hpp"
#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
#include "com/sun/star/lang/DisposedException.hpp"
#include "boost/scoped_array.hpp"
#include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp"
#include "com/sun/star/bridge/BridgeFactory.hpp"
#include "com/sun/star/bridge/XBridgeFactory.hpp"
#include <stdio.h>
#include <vector>

@@ -190,36 +188,9 @@ Reference<deployment::XPackage> findPackage(

} // anon namespace


//workaround for some reason the bridge threads which communicate with the uno.exe
//process are not releases on time
void disposeBridges(Reference<css::uno::XComponentContext> ctx)
{
    if (!ctx.is())
        return;

    Reference<css::bridge::XBridgeFactory2> bridgeFac( css::bridge::BridgeFactory::create(ctx) );

    const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
    for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
    {
        Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
        if (comp.is())
        {
            try {
                comp->dispose();
            }
            catch ( const css::lang::DisposedException& )
            {
            }
        }
    }
}

extern "C" DESKTOP_DLLPUBLIC int unopkg_main()
{
    tools::extendApplicationEnvironment();
    DisposeGuard disposeGuard;
    bool bNoOtherErrorMsg = false;
    OUString subCommand;
    bool option_shared = false;
@@ -371,8 +342,7 @@ extern "C" DESKTOP_DLLPUBLIC int unopkg_main()
        }

        xComponentContext = getUNO(
            disposeGuard, option_verbose, option_shared, subcmd_gui,
            xLocalComponentContext );
            option_verbose, option_shared, subcmd_gui, xLocalComponentContext );

        Reference<deployment::XExtensionManager> xExtensionManager(
            deployment::ExtensionManager::get( xComponentContext ) );
@@ -575,6 +545,7 @@ extern "C" DESKTOP_DLLPUBLIC int unopkg_main()

            xDialog->startExecuteModal(xListener);
            dialogEnded.wait();
            return 0;
        }
        else
        {
@@ -591,7 +562,7 @@ extern "C" DESKTOP_DLLPUBLIC int unopkg_main()
        if (option_verbose)
            dp_misc::writeConsole(OUSTR("\n" APP_NAME " done.\n"));
        //Force to release all bridges which connect us to the child processes
        disposeBridges(xLocalComponentContext);
        dp_misc::disposeBridges(xLocalComponentContext);
        return 0;
    }
    catch (const ucb::CommandFailedException &e)
@@ -640,7 +611,7 @@ extern "C" DESKTOP_DLLPUBLIC int unopkg_main()
    }
    if (!bNoOtherErrorMsg)
        dp_misc::writeConsoleError("\n" APP_NAME " failed.\n");
    disposeBridges(xLocalComponentContext);
    dp_misc::disposeBridges(xLocalComponentContext);
    return 1;
}

diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
index a034828..932d1cd 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
+++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
@@ -368,16 +368,11 @@ void printf_packages(
namespace {

//------------------------------------------------------------------------------
Reference<XComponentContext> bootstrapStandAlone(
    DisposeGuard & disposeGuard, bool /*verbose */)
Reference<XComponentContext> bootstrapStandAlone()
{
    Reference<XComponentContext> xContext =
        ::cppu::defaultBootstrap_InitialComponentContext();

    // assure disposing of local component context:
    disposeGuard.reset(
        Reference<lang::XComponent>( xContext, UNO_QUERY ) );

    Reference<lang::XMultiServiceFactory> xServiceManager(
        xContext->getServiceManager(), UNO_QUERY_THROW );
    // set global process service factory used by unotools config helpers
@@ -462,7 +457,7 @@ OUString getLockFilePath()
}
//==============================================================================
Reference<XComponentContext> getUNO(
    DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
    bool verbose, bool shared, bool bGui,
    Reference<XComponentContext> & out_localContext)
{
    // do not create any user data (for the root user) in --shared mode:
@@ -474,8 +469,7 @@ Reference<XComponentContext> getUNO(

    // hold lock during process runtime:
    static ::desktop::Lockfile s_lockfile( false /* no IPC server */ );
    Reference<XComponentContext> xComponentContext(
        bootstrapStandAlone( disposeGuard, verbose ) );
    Reference<XComponentContext> xComponentContext( bootstrapStandAlone() );
    out_localContext = xComponentContext;
    if (::dp_misc::office_is_running()) {
        xComponentContext.set(
diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h
index c8cdc3c..adc6e8b 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_shared.h
+++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h
@@ -28,7 +28,6 @@

#include "dp_misc.h"
#include "com/sun/star/uno/Exception.hpp"
#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/ucb/XCommandEnvironment.hpp"
#include "com/sun/star/deployment/XPackage.hpp"
@@ -121,25 +120,6 @@ bool isBootstrapVariable(sal_uInt32 * pIndex);
//##############################################################################

//==============================================================================
class DisposeGuard
{
    css::uno::Reference<css::lang::XComponent> m_xComp;

public:
    inline ~DisposeGuard()
    {
        if (m_xComp.is())
            m_xComp->dispose();
    }

    inline void reset(
        css::uno::Reference<css::lang::XComponent> const & xComp )
    {
        m_xComp = xComp;
    }
};

//==============================================================================
css::uno::Reference<css::ucb::XCommandEnvironment> createCmdEnv(
    css::uno::Reference<css::uno::XComponentContext> const & xContext,
    ::rtl::OUString const & logFile,
@@ -158,7 +138,7 @@ void printf_packages(

//==============================================================================
css::uno::Reference<css::uno::XComponentContext> getUNO(
    DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
    bool verbose, bool shared, bool bGui,
    css::uno::Reference<css::uno::XComponentContext> & out_LocalComponentContext);

}