A case when this would come in handy is
* When there is a design guarantee that an object will always be owned by a shared pointer.
* In this case, we can blindly use shared_from_this() to return our own shared instance to another function which accepts a shared_ptr<> version of our class.
For example,
The DBusConnection object is always shared by many instances which means that is is always passed through shared_ptr<DBUsConnection> everywhere. So in that case we can write a code snippet like this:
In the git source of CommonAPI we can see the references:
capicxx-dbus-runtime/DBusServiceRegistry.cpp at 77fd3ae09034b6f7cb87be7fd77d08cf106f53cb · GENIVI/capicxx-dbus-runtime · GitHub[
^]
void DBusConnection::notifyDBusSignalHandlers(DBusSignalHandlerPath handlerPath,
const DBusMessage& dbusMessage,
::DBusHandlerResult& dbusHandlerResult) {
std::shared_ptr<DBusServiceRegistry> itsRegistry_ = DBusServiceRegistry::get(shared_from_this());
std::map<const DBusSignalHandler*,
std::weak_ptr<DBusProxyConnection::DBusSignalHandler>> itsHandlers;
{
std::lock_guard<std::mutex> dbusSignalHandlersLock(signalHandlersGuard_);
auto signalHandlerPathIt = dbusSignalHandlers_.find(handlerPath);
if(signalHandlerPathIt != dbusSignalHandlers_.end()) {
itsHandlers = signalHandlerPathIt->second;
}
}
If we inspect the DBusServiceRegistry::get(..) and DBusServiceRegistry::Remove(..) static functions, we can notice that the shared pointer instance is getting added into a static registry map and removed respectively.
std::shared_ptr<DBusServiceRegistry>
DBusServiceRegistry::get(std::shared_ptr<DBusProxyConnection> _connection, bool _insert) {
std::unique_lock<std::mutex> itsGuard(registriesMutex_);
auto registries = getRegistryMap();
auto registryIterator = registries->find(_connection.get());
if (registryIterator != registries->end())
return registryIterator->second;
std::shared_ptr<DBusServiceRegistry> registry
= std::make_shared<DBusServiceRegistry>(_connection);
if (registry) {
if(_insert) {
registries->insert( { _connection.get(), registry } );
}
itsGuard.unlock();
registry->init();
}
return registry;
}
void
DBusServiceRegistry::remove(std::shared_ptr<DBusProxyConnection> _connection) {
std::lock_guard<std::mutex> itsGuard(registriesMutex_);
auto registries = getRegistryMap();
registries->erase(_connection.get());
}
As we can see here that when the desktop bus connection is getting disconnected, we see that the instance is getting removed from the registry map.
void DBusConnection::disconnect() {
std::unique_lock<std::recursive_mutex> dbusConnectionLock(connectionGuard_);
std::shared_ptr<DBusServiceRegistry> itsRegistry = DBusServiceRegistry::get(shared_from_this());
isDisconnecting_ = true;
if (std::shared_ptr<CommonAPI::MainLoopContext> mainLoopContext = mainLoopContext_.lock()) {
DBusServiceRegistry::remove(shared_from_this());
Factory::get()->releaseConnection(connectionId_);
}