Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "tools/SdGlobalResourceContainer.hxx"
21 :
22 : #include <algorithm>
23 : #include <vector>
24 :
25 : using namespace ::com::sun::star;
26 : using namespace ::com::sun::star::uno;
27 :
28 : namespace sd {
29 :
30 : //===== SdGlobalResourceContainer::Implementation =============================
31 :
32 58 : class SdGlobalResourceContainer::Implementation
33 : {
34 : private:
35 : friend class SdGlobalResourceContainer;
36 : static SdGlobalResourceContainer* mpInstance;
37 :
38 : ::osl::Mutex maMutex;
39 :
40 : /** All instances of SdGlobalResource in this vector are owned by the
41 : container and will be destroyed when the container is destroyed.
42 : */
43 : typedef ::std::vector<SdGlobalResource*> ResourceList;
44 : ResourceList maResources;
45 :
46 : typedef ::std::vector<boost::shared_ptr<SdGlobalResource> > SharedResourceList;
47 : SharedResourceList maSharedResources;
48 :
49 : typedef ::std::vector<Reference<XInterface> > XInterfaceResourceList;
50 : XInterfaceResourceList maXInterfaceResources;
51 : };
52 :
53 : // static
54 52 : SdGlobalResourceContainer& SdGlobalResourceContainer::Instance (void)
55 : {
56 : DBG_ASSERT(Implementation::mpInstance!=NULL,
57 : "SdGlobalResourceContainer::Instance(): instance has been deleted");
58 : // Maybe we should throw an exception when the instance has been deleted.
59 52 : return *Implementation::mpInstance;
60 : }
61 :
62 : SdGlobalResourceContainer*
63 : SdGlobalResourceContainer::Implementation::mpInstance = NULL;
64 :
65 : //===== SdGlobalResourceContainer =============================================
66 :
67 28 : void SdGlobalResourceContainer::AddResource (
68 : ::std::unique_ptr<SdGlobalResource> && pResource)
69 : {
70 28 : ::osl::MutexGuard aGuard (mpImpl->maMutex);
71 :
72 28 : Implementation::ResourceList::iterator iResource;
73 : iResource = ::std::find (
74 28 : mpImpl->maResources.begin(),
75 28 : mpImpl->maResources.end(),
76 84 : pResource.get());
77 28 : if (iResource == mpImpl->maResources.end())
78 28 : mpImpl->maResources.push_back(pResource.get());
79 : else
80 : {
81 : // Because the given resource is a unique_ptr it is highly unlikely
82 : // that we come here. But who knows?
83 : DBG_ASSERT (false,
84 : "SdGlobalResourceContainer:AddResource(): Resource added twice.");
85 : }
86 : // We can not put the unique_ptr into the vector so we release the
87 : // unique_ptr and document that we take ownership explicitly.
88 28 : pResource.release();
89 28 : }
90 :
91 0 : void SdGlobalResourceContainer::AddResource (
92 : ::boost::shared_ptr<SdGlobalResource> pResource)
93 : {
94 0 : ::osl::MutexGuard aGuard (mpImpl->maMutex);
95 :
96 0 : Implementation::SharedResourceList::iterator iResource;
97 : iResource = ::std::find (
98 0 : mpImpl->maSharedResources.begin(),
99 0 : mpImpl->maSharedResources.end(),
100 0 : pResource);
101 0 : if (iResource == mpImpl->maSharedResources.end())
102 0 : mpImpl->maSharedResources.push_back(pResource);
103 : else
104 : {
105 : DBG_ASSERT (false,
106 : "SdGlobalResourceContainer:AddResource(): Resource added twice.");
107 0 : }
108 0 : }
109 :
110 24 : void SdGlobalResourceContainer::AddResource (const Reference<XInterface>& rxResource)
111 : {
112 24 : ::osl::MutexGuard aGuard (mpImpl->maMutex);
113 :
114 24 : Implementation::XInterfaceResourceList::iterator iResource;
115 : iResource = ::std::find (
116 24 : mpImpl->maXInterfaceResources.begin(),
117 24 : mpImpl->maXInterfaceResources.end(),
118 48 : rxResource);
119 24 : if (iResource == mpImpl->maXInterfaceResources.end())
120 24 : mpImpl->maXInterfaceResources.push_back(rxResource);
121 : else
122 : {
123 : DBG_ASSERT (false,
124 : "SdGlobalResourceContainer:AddResource(): Resource added twice.");
125 24 : }
126 24 : }
127 :
128 36 : SdGlobalResourceContainer::SdGlobalResourceContainer (void)
129 36 : : mpImpl (new SdGlobalResourceContainer::Implementation())
130 : {
131 36 : Implementation::mpInstance = this;
132 36 : }
133 :
134 44 : SdGlobalResourceContainer::~SdGlobalResourceContainer (void)
135 : {
136 22 : ::osl::MutexGuard aGuard (mpImpl->maMutex);
137 :
138 : // Release the resources in reversed order of their addition to the
139 : // container. This is because a resource A added before resource B
140 : // may have been created due to a request of B. Thus B depends on A and
141 : // should be destroyed first.
142 22 : Implementation::ResourceList::reverse_iterator iResource;
143 144 : for (iResource = mpImpl->maResources.rbegin();
144 96 : iResource != mpImpl->maResources.rend();
145 : ++iResource)
146 : {
147 26 : delete *iResource;
148 : }
149 :
150 : // The SharedResourceList has not to be released manually. We just
151 : // assert resources that are still held by someone other than us.
152 22 : Implementation::SharedResourceList::reverse_iterator iSharedResource;
153 66 : for (iSharedResource = mpImpl->maSharedResources.rbegin();
154 44 : iSharedResource != mpImpl->maSharedResources.rend();
155 : ++iSharedResource)
156 : {
157 0 : if ( ! iSharedResource->unique())
158 : {
159 0 : SdGlobalResource* pResource = iSharedResource->get();
160 : OSL_TRACE(" %p %d", pResource, iSharedResource->use_count());
161 : DBG_ASSERT(iSharedResource->unique(),
162 : "SdGlobalResource still held in ~SdGlobalResourceContainer");
163 : }
164 : }
165 :
166 22 : Implementation::XInterfaceResourceList::reverse_iterator iXInterfaceResource;
167 126 : for (iXInterfaceResource = mpImpl->maXInterfaceResources.rbegin();
168 84 : iXInterfaceResource != mpImpl->maXInterfaceResources.rend();
169 : ++iXInterfaceResource)
170 : {
171 20 : Reference<lang::XComponent> xComponent (*iXInterfaceResource, UNO_QUERY);
172 20 : *iXInterfaceResource = NULL;
173 20 : if (xComponent.is())
174 0 : xComponent->dispose();
175 20 : }
176 :
177 : DBG_ASSERT(Implementation::mpInstance == this,
178 : "~SdGlobalResourceContainer(): more than one instance of singleton");
179 22 : Implementation::mpInstance = NULL;
180 22 : }
181 :
182 114 : } // end of namespace sd
183 :
184 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|