1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "precompiled_sd.hxx" 25 26 #include "ChangeRequestQueueProcessor.hxx" 27 #include "ConfigurationTracer.hxx" 28 29 #include "framework/ConfigurationController.hxx" 30 #include "ConfigurationUpdater.hxx" 31 32 #include <vcl/svapp.hxx> 33 #include <com/sun/star/container/XNamed.hpp> 34 #include <com/sun/star/drawing/framework/XConfiguration.hpp> 35 #include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp> 36 37 using namespace ::com::sun::star; 38 using namespace ::com::sun::star::uno; 39 using namespace ::com::sun::star::drawing::framework; 40 41 #undef VERBOSE 42 //#define VERBOSE 1 43 44 namespace { 45 46 #ifdef VERBOSE 47 48 void TraceRequest (const Reference<XConfigurationChangeRequest>& rxRequest) 49 { 50 Reference<container::XNamed> xNamed (rxRequest, UNO_QUERY); 51 if (xNamed.is()) 52 OSL_TRACE(" %s\n", 53 ::rtl::OUStringToOString(xNamed->getName(), RTL_TEXTENCODING_UTF8).getStr()); 54 } 55 56 #endif 57 58 } // end of anonymous namespace 59 60 61 namespace sd { namespace framework { 62 63 ChangeRequestQueueProcessor::ChangeRequestQueueProcessor ( 64 const ::rtl::Reference<ConfigurationController>& rpConfigurationController, 65 const ::boost::shared_ptr<ConfigurationUpdater>& rpConfigurationUpdater) 66 : maMutex(), 67 maQueue(), 68 mnUserEventId(0), 69 mxConfiguration(), 70 mpConfigurationController(rpConfigurationController), 71 mpConfigurationUpdater(rpConfigurationUpdater) 72 { 73 } 74 75 76 77 78 ChangeRequestQueueProcessor::~ChangeRequestQueueProcessor (void) 79 { 80 if (mnUserEventId != 0) 81 Application::RemoveUserEvent(mnUserEventId); 82 } 83 84 85 86 87 void ChangeRequestQueueProcessor::SetConfiguration ( 88 const Reference<XConfiguration>& rxConfiguration) 89 { 90 ::osl::MutexGuard aGuard (maMutex); 91 92 mxConfiguration = rxConfiguration; 93 StartProcessing(); 94 } 95 96 97 98 99 void ChangeRequestQueueProcessor::AddRequest ( 100 const Reference<XConfigurationChangeRequest>& rxRequest) 101 { 102 ::osl::MutexGuard aGuard (maMutex); 103 104 #ifdef VERBOSE 105 if (maQueue.empty()) 106 { 107 OSL_TRACE("Adding requests to empty queue\n"); 108 ConfigurationTracer::TraceConfiguration( 109 mxConfiguration, "current configuration of queue processor"); 110 } 111 OSL_TRACE("Adding request\n"); 112 TraceRequest(rxRequest); 113 #endif 114 115 maQueue.push_back(rxRequest); 116 StartProcessing(); 117 } 118 119 120 121 122 void ChangeRequestQueueProcessor::StartProcessing (void) 123 { 124 ::osl::MutexGuard aGuard (maMutex); 125 126 if (mnUserEventId == 0 127 && mxConfiguration.is() 128 && ! maQueue.empty()) 129 { 130 #ifdef VERBOSE 131 OSL_TRACE("ChangeRequestQueueProcessor scheduling processing\n"); 132 #endif 133 mnUserEventId = Application::PostUserEvent( 134 LINK(this,ChangeRequestQueueProcessor,ProcessEvent)); 135 } 136 } 137 138 139 140 141 IMPL_LINK(ChangeRequestQueueProcessor, ProcessEvent, void*, pUnused) 142 { 143 (void)pUnused; 144 145 ::osl::MutexGuard aGuard (maMutex); 146 147 mnUserEventId = 0; 148 149 ProcessOneEvent(); 150 151 if ( ! maQueue.empty()) 152 { 153 // Schedule the processing of the next event. 154 StartProcessing(); 155 } 156 157 return 0; 158 } 159 160 161 162 163 void ChangeRequestQueueProcessor::ProcessOneEvent (void) 164 { 165 ::osl::MutexGuard aGuard (maMutex); 166 167 #ifdef VERBOSE 168 OSL_TRACE("ProcessOneEvent\n"); 169 #endif 170 171 if (mxConfiguration.is() 172 && ! maQueue.empty()) 173 { 174 // Get and remove the first entry from the queue. 175 Reference<XConfigurationChangeRequest> xRequest (maQueue.front()); 176 maQueue.pop_front(); 177 178 // Execute the change request. 179 if (xRequest.is()) 180 { 181 #ifdef VERBOSE 182 TraceRequest(xRequest); 183 #endif 184 xRequest->execute(mxConfiguration); 185 } 186 187 if (maQueue.empty()) 188 { 189 #ifdef VERBOSE 190 OSL_TRACE("All requests are processed\n"); 191 #endif 192 // The queue is empty so tell the ConfigurationManager to update 193 // its state. 194 if (mpConfigurationUpdater.get() != NULL) 195 { 196 #ifdef VERBOSE 197 ConfigurationTracer::TraceConfiguration ( 198 mxConfiguration, "updating to configuration"); 199 #endif 200 mpConfigurationUpdater->RequestUpdate(mxConfiguration); 201 } 202 } 203 } 204 } 205 206 207 208 209 bool ChangeRequestQueueProcessor::IsEmpty (void) const 210 { 211 return maQueue.empty(); 212 } 213 214 215 216 217 void ChangeRequestQueueProcessor::ProcessUntilEmpty (void) 218 { 219 while ( ! IsEmpty()) 220 ProcessOneEvent(); 221 } 222 223 224 225 226 void ChangeRequestQueueProcessor::Clear (void) 227 { 228 ::osl::MutexGuard aGuard (maMutex); 229 maQueue.clear(); 230 } 231 232 233 } } // end of namespace sd::framework::configuration 234