| 142 | } |
| 143 | |
| 144 | void ServiceRegistrationBase::Unregister() |
| 145 | { |
| 146 | if (!d) throw std::logic_error("ServiceRegistrationBase object invalid"); |
| 147 | |
| 148 | if (d->unregistering) return; // Silently ignore redundant unregistration. |
| 149 | { |
| 150 | MutexLock lock(d->eventLock); |
| 151 | if (d->unregistering) return; |
| 152 | d->unregistering = true; |
| 153 | |
| 154 | if (d->available) |
| 155 | { |
| 156 | if (d->module) |
| 157 | { |
| 158 | d->module->coreCtx->services.RemoveServiceRegistration(*this); |
| 159 | } |
| 160 | } |
| 161 | else |
| 162 | { |
| 163 | throw std::logic_error("Service is unregistered"); |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | if (d->module) |
| 168 | { |
| 169 | ServiceListeners::ServiceListenerEntries listeners; |
| 170 | ServiceEvent unregisteringEvent(ServiceEvent::UNREGISTERING, d->reference); |
| 171 | d->module->coreCtx->listeners.GetMatchingServiceListeners(unregisteringEvent, listeners); |
| 172 | d->module->coreCtx->listeners.ServiceChanged( |
| 173 | listeners, |
| 174 | unregisteringEvent); |
| 175 | } |
| 176 | |
| 177 | // Copy service data under lock, then call UngetService outside the lock |
| 178 | // to avoid potential deadlock if the factory callback accesses properties. |
| 179 | ServiceFactory* serviceFactory = nullptr; |
| 180 | ServiceRegistrationBasePrivate::ModuleToServicesMap prototypesCopy; |
| 181 | ServiceRegistrationBasePrivate::ModuleToServiceMap moduleSvcCopy; |
| 182 | |
| 183 | { |
| 184 | MutexLock lock(d->eventLock); |
| 185 | { |
| 186 | MutexLock lock2(d->propsLock); |
| 187 | d->available = false; |
| 188 | InterfaceMap::const_iterator factoryIter = d->service.find("org.cppmicroservices.factory"); |
| 189 | if (d->module && factoryIter != d->service.end()) |
| 190 | { |
| 191 | serviceFactory = reinterpret_cast<ServiceFactory*>(factoryIter->second); |
| 192 | prototypesCopy = d->prototypeServiceInstances; |
| 193 | moduleSvcCopy = d->moduleServiceInstance; |
| 194 | } |
| 195 | d->module = nullptr; |
| 196 | d->dependents.clear(); |
| 197 | d->service.clear(); |
| 198 | d->prototypeServiceInstances.clear(); |
| 199 | d->moduleServiceInstance.clear(); |
| 200 | // increment the reference count, since "d->reference" was used originally |
| 201 | // to keep d alive. |
no test coverage detected