summaryrefslogtreecommitdiff
path: root/src/CommonAPI
diff options
context:
space:
mode:
Diffstat (limited to 'src/CommonAPI')
-rw-r--r--src/CommonAPI/DBus/DBusConnection.cpp618
-rw-r--r--src/CommonAPI/DBus/DBusDaemonProxy.cpp63
-rw-r--r--src/CommonAPI/DBus/DBusError.cpp1
-rw-r--r--src/CommonAPI/DBus/DBusFactory.cpp121
-rw-r--r--src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp35
-rw-r--r--src/CommonAPI/DBus/DBusFunctionalHash.cpp21
-rw-r--r--src/CommonAPI/DBus/DBusInputStream.cpp16
-rwxr-xr-xsrc/CommonAPI/DBus/DBusMainLoop.cpp179
-rw-r--r--src/CommonAPI/DBus/DBusMainLoopContext.cpp321
-rw-r--r--src/CommonAPI/DBus/DBusMessage.cpp73
-rw-r--r--src/CommonAPI/DBus/DBusObjectManager.cpp143
-rw-r--r--src/CommonAPI/DBus/DBusObjectManagerStub.cpp151
-rw-r--r--src/CommonAPI/DBus/DBusOutputStream.cpp36
-rw-r--r--src/CommonAPI/DBus/DBusProxy.cpp306
-rw-r--r--src/CommonAPI/DBus/DBusProxyManager.cpp5
-rw-r--r--src/CommonAPI/DBus/DBusServiceRegistry.cpp222
-rw-r--r--src/CommonAPI/DBus/DBusStubAdapter.cpp3
17 files changed, 1746 insertions, 568 deletions
diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp
index 47751cc..6071830 100644
--- a/src/CommonAPI/DBus/DBusConnection.cpp
+++ b/src/CommonAPI/DBus/DBusConnection.cpp
@@ -4,7 +4,6 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <algorithm>
-#include <cassert>
#include <chrono>
#include <future>
#include <sstream>
@@ -44,11 +43,6 @@ const DBusObjectPathVTable* DBusConnection::getDBusObjectPathVTable() {
return &libdbusObjectPathVTable;
}
-//std::bind used to start the dispatch thread holds one reference, and the selfReference
-//created within the thread is the second. If only those two remain, no one but the
-//dispatch thread references the connection, which therefore can be finished.
-const int32_t ownUseCount = 2;
-
void DBusConnection::dispatch() {
loop_->run();
}
@@ -56,10 +50,8 @@ void DBusConnection::dispatch() {
DBusConnection::DBusConnection(DBusType_t busType,
const ConnectionId_t& _connectionId) :
dispatchThread_(NULL),
- stopDispatching_(false),
dispatchSource_(),
watchContext_(NULL),
- pauseDispatching_(false),
connection_(NULL),
busType_(busType),
dbusConnectionStatusEvent_(this),
@@ -68,7 +60,11 @@ DBusConnection::DBusConnection(DBusType_t busType,
connectionNameCount_(),
enforcerThread_(NULL),
enforcerThreadCancelled_(false),
- connectionId_(_connectionId) {
+ connectionId_(_connectionId),
+ activeConnections_(0),
+ isDisconnecting_(false),
+ isDispatching_(false),
+ isWaitingOnFinishedDispatching_(false) {
dbus_threads_init_default();
}
@@ -76,10 +72,8 @@ DBusConnection::DBusConnection(DBusType_t busType,
DBusConnection::DBusConnection(::DBusConnection *_connection,
const ConnectionId_t& _connectionId) :
dispatchThread_(NULL),
- stopDispatching_(false),
dispatchSource_(),
watchContext_(NULL),
- pauseDispatching_(false),
connection_(_connection),
busType_(DBusType_t::WRAPPED),
dbusConnectionStatusEvent_(this),
@@ -88,7 +82,11 @@ DBusConnection::DBusConnection(::DBusConnection *_connection,
connectionNameCount_(),
enforcerThread_(NULL),
enforcerThreadCancelled_(false),
- connectionId_(_connectionId) {
+ connectionId_(_connectionId),
+ activeConnections_(0),
+ isDisconnecting_(false),
+ isDispatching_(false),
+ isWaitingOnFinishedDispatching_(false){
dbus_threads_init_default();
}
@@ -108,14 +106,17 @@ DBusConnection::~DBusConnection() {
dbus_connection_set_timeout_functions(connection_, NULL, NULL, NULL, NULL, NULL);
}
+ lockedContext->deregisterWatch(msgWatch_);
+ lockedContext->deregisterDispatchSource(msgDispatchSource_);
lockedContext->deregisterDispatchSource(dispatchSource_);
delete watchContext_;
- delete dispatchSource_;
}
// ensure, the registry survives until disconnecting is done...
//std::shared_ptr<DBusServiceRegistry> itsRegistry = DBusServiceRegistry::get(shared_from_this());
- disconnect();
+
+ // Disconnecting not possible because of circular dependency, the destructor will be called AFTER disconnect anyway.
+ //disconnect();
//Assert that the enforcerThread_ is in a position to finish itself correctly even after destruction
//of the DBusConnection. Also assert all resources are cleaned up.
@@ -174,8 +175,14 @@ bool DBusConnection::attachMainLoopContext(std::weak_ptr<MainLoopContext> mainLo
mainLoopContext_ = mainLoopContext;
if (auto lockedContext = mainLoopContext_.lock()) {
+ msgWatch_ = new DBusMessageWatch(shared_from_this());
+ msgDispatchSource_ = new DBusMessageDispatchSource(msgWatch_);
+
+ lockedContext->registerDispatchSource(msgDispatchSource_);
+ lockedContext->registerWatch(msgWatch_);
+
dispatchSource_ = new DBusDispatchSource(this);
- watchContext_ = new WatchContext(mainLoopContext_, dispatchSource_);
+ watchContext_ = new WatchContext(mainLoopContext_, dispatchSource_, shared_from_this());
lockedContext->registerDispatchSource(dispatchSource_);
dbus_connection_set_wakeup_main_function(
@@ -216,31 +223,39 @@ bool DBusConnection::attachMainLoopContext(std::weak_ptr<MainLoopContext> mainLo
void DBusConnection::onWakeupMainContext(void* data) {
std::weak_ptr<MainLoopContext>* mainloop = static_cast<std::weak_ptr<MainLoopContext>*>(data);
- assert(mainloop);
- if(auto lockedContext = mainloop->lock()) {
+ if (!mainloop) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "mainloop == nullptr");
+ } else if(auto lockedContext = mainloop->lock()) {
lockedContext->wakeup();
}
}
dbus_bool_t DBusConnection::onAddWatch(::DBusWatch* libdbusWatch, void* data) {
WatchContext* watchContext = static_cast<WatchContext*>(data);
- assert(watchContext);
-
- DBusWatch* dbusWatch = new DBusWatch(libdbusWatch, watchContext->mainLoopContext_);
- dbusWatch->addDependentDispatchSource(watchContext->dispatchSource_);
- dbus_watch_set_data(libdbusWatch, dbusWatch, NULL);
+ if (NULL == watchContext) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "watchContext == NULL");
+ return FALSE;
+ } else {
+ DBusWatch* dbusWatch = new DBusWatch(libdbusWatch, watchContext->mainLoopContext_, watchContext->dbusConnection_);
+ dbusWatch->addDependentDispatchSource(watchContext->dispatchSource_);
+ dbus_watch_set_data(libdbusWatch, dbusWatch, NULL);
- if (dbusWatch->isReadyToBeWatched()) {
- dbusWatch->startWatching();
+ if (dbusWatch->isReadyToBeWatched()) {
+ dbusWatch->startWatching();
+ } else {
+ delete dbusWatch;
+ dbus_watch_set_data(libdbusWatch, NULL, NULL);
+ }
}
return TRUE;
}
void DBusConnection::onRemoveWatch(::DBusWatch* libdbusWatch, void* data) {
- assert(static_cast<WatchContext*>(data));
- (void)data;
+ if (NULL == static_cast<WatchContext*>(data)) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "data (WatchContext) == NULL");
+ }
DBusWatch* dbusWatch = static_cast<DBusWatch*>(dbus_watch_get_data(libdbusWatch));
if (dbusWatch != NULL) {
@@ -254,12 +269,16 @@ void DBusConnection::onRemoveWatch(::DBusWatch* libdbusWatch, void* data) {
void DBusConnection::onToggleWatch(::DBusWatch* libdbusWatch, void* data) {
WatchContext* watchContext = static_cast<WatchContext*>(data);
- assert(watchContext);
+
+ if (NULL == watchContext) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "watchContext == NULL");
+ return;
+ }
DBusWatch* dbusWatch = static_cast<DBusWatch*>(dbus_watch_get_data(libdbusWatch));
if (dbusWatch == NULL) {
- DBusWatch* dbusWatch = new DBusWatch(libdbusWatch, watchContext->mainLoopContext_);
+ DBusWatch* dbusWatch = new DBusWatch(libdbusWatch, watchContext->mainLoopContext_, watchContext->dbusConnection_);
dbusWatch->addDependentDispatchSource(watchContext->dispatchSource_);
dbus_watch_set_data(libdbusWatch, dbusWatch, NULL);
@@ -270,6 +289,8 @@ void DBusConnection::onToggleWatch(::DBusWatch* libdbusWatch, void* data) {
if (!dbusWatch->isReadyToBeWatched()) {
dbusWatch->stopWatching();
dbus_watch_set_data(libdbusWatch, NULL, NULL);
+ } else {
+ dbusWatch->startWatching();
}
}
}
@@ -277,21 +298,28 @@ void DBusConnection::onToggleWatch(::DBusWatch* libdbusWatch, void* data) {
dbus_bool_t DBusConnection::onAddTimeout(::DBusTimeout* libdbusTimeout, void* data) {
std::weak_ptr<MainLoopContext>* mainloop = static_cast<std::weak_ptr<MainLoopContext>*>(data);
- assert(mainloop);
+ if (NULL == mainloop) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "mainloop == NULL");
+ return FALSE;
+ }
DBusTimeout* dbusTimeout = new DBusTimeout(libdbusTimeout, *mainloop);
dbus_timeout_set_data(libdbusTimeout, dbusTimeout, NULL);
if (dbusTimeout->isReadyToBeMonitored()) {
dbusTimeout->startMonitoring();
+ } else {
+ delete dbusTimeout;
+ dbus_timeout_set_data(libdbusTimeout, NULL, NULL);
}
return TRUE;
}
void DBusConnection::onRemoveTimeout(::DBusTimeout* libdbusTimeout, void* data) {
- assert(static_cast<std::weak_ptr<MainLoopContext>*>(data));
- (void)data;
+ if (NULL == static_cast<std::weak_ptr<MainLoopContext>*>(data)) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "MainLoopContext == NULL");
+ }
DBusTimeout* dbusTimeout = static_cast<DBusTimeout*>(dbus_timeout_get_data(libdbusTimeout));
if (dbusTimeout) {
@@ -302,8 +330,9 @@ void DBusConnection::onRemoveTimeout(::DBusTimeout* libdbusTimeout, void* data)
}
void DBusConnection::onToggleTimeout(::DBusTimeout* dbustimeout, void* data) {
- assert(static_cast<std::weak_ptr<MainLoopContext>*>(data));
- (void)data;
+ if (NULL == static_cast<std::weak_ptr<MainLoopContext>*>(data)) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "MainLoopContext == NULL");
+ }
DBusTimeout* timeout = static_cast<DBusTimeout*>(dbus_timeout_get_data(dbustimeout));
if (timeout->isReadyToBeMonitored()) {
@@ -319,7 +348,11 @@ bool DBusConnection::connect(bool startDispatchThread) {
}
bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) {
- assert(!dbusError);
+ if (dbusError) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "dbusError set");
+ return false;
+ }
+
if (isConnected()) {
return true;
}
@@ -340,7 +373,11 @@ bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) {
return false;
}
- assert(connection_);
+ if (NULL == connection_) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "connection_ == NULL");
+ return false;
+ }
+
dbus_connection_set_exit_on_disconnect(connection_, false);
initLibdbusObjectPathHandlerAfterConnect();
@@ -352,7 +389,7 @@ bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) {
dbusConnectionStatusEvent_.notifyListeners(AvailabilityStatus::AVAILABLE);
- stopDispatching_ = !startDispatchThread;
+ isDisconnecting_ = false;
if (startDispatchThread) {
std::shared_ptr<MainLoopContext> itsContext = std::make_shared<MainLoopContext>();
loop_ = std::make_shared<DBusMainLoop>(itsContext);
@@ -365,6 +402,10 @@ bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) {
void DBusConnection::disconnect() {
std::lock_guard<std::mutex> dbusConnectionLock(connectionGuard_);
+
+ std::unique_lock<std::mutex> dispatchLock(dispatchMutex_);
+ isDisconnecting_ = true;
+
if (isConnected()) {
dbusConnectionStatusEvent_.notifyListeners(AvailabilityStatus::NOT_AVAILABLE);
@@ -375,7 +416,16 @@ void DBusConnection::disconnect() {
connectionNameCount_.clear();
- stopDispatching_ = true;
+ //wait until dispatching is finished
+ auto it = dispatchThreads_.find(std::this_thread::get_id());
+ if(it == dispatchThreads_.end()) { //wait only if disconnect is NOT triggered by main loop
+ while(isDispatching_) {
+ isWaitingOnFinishedDispatching_ = true;
+ dispatchCondition_.wait(dispatchLock);
+ isWaitingOnFinishedDispatching_ = false;
+ }
+ }
+ dispatchLock.unlock();
dbus_connection_close(connection_);
@@ -394,7 +444,8 @@ void DBusConnection::disconnect() {
enforcerThreadCancelled_ = true;
enforceTimeoutCondition_.notify_one();
- if (enforcerThread_->joinable()) {
+ if (enforcerThread_->joinable() &&
+ std::this_thread::get_id() != enforcerThread_->get_id()) {
enforcerThread_->join();
}
enforcerThreadCancelled_ = false;
@@ -406,6 +457,10 @@ void DBusConnection::disconnect() {
dbus_connection_unref(connection_);
connection_ = nullptr;
}
+
+ if (std::shared_ptr<CommonAPI::MainLoopContext> mainLoopContext = mainLoopContext_.lock()) {
+ Factory::get()->releaseConnection(connectionId_, mainLoopContext.get());
+ }
}
bool DBusConnection::isConnected() const {
@@ -488,60 +543,87 @@ bool DBusConnection::releaseServiceName(const std::string& serviceName) const {
}
bool DBusConnection::sendDBusMessage(const DBusMessage &_message) const {
- assert(_message);
- assert(isConnected());
+ if (!_message) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "message == NULL");
+ return false;
+ }
+ if (!isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected");
+ return false;
+ }
dbus_uint32_t dbusSerial;
- bool result = 0 != dbus_connection_send(connection_, _message.message_, &dbusSerial);
+ const bool result = (0 != dbus_connection_send(connection_, _message.message_, &dbusSerial));
return result;
}
-DBusMessage DBusConnection::convertToDBusMessage(::DBusPendingCall* _libdbusPendingCall,
- CallStatus& _callStatus) {
- assert(_libdbusPendingCall);
+DBusMessage DBusConnection::convertToDBusMessage(::DBusPendingCall* _libdbusPendingCall) {
+ if (NULL == _libdbusPendingCall) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "_libdbusPendingCall == NULL");
+ return DBusMessage();
+ }
::DBusMessage* libdbusMessage = dbus_pending_call_steal_reply(_libdbusPendingCall);
const bool increaseLibdbusMessageReferenceCount = false;
DBusMessage dbusMessage(libdbusMessage, increaseLibdbusMessageReferenceCount);
- _callStatus = CallStatus::SUCCESS;
-
- if (!dbusMessage.isMethodReturnType()) {
- _callStatus = CallStatus::REMOTE_ERROR;
- }
return dbusMessage;
}
-void DBusConnection::onLibdbusPendingCallNotifyThunk(::DBusPendingCall* _libdbusPendingCall, void *_userData) {
- assert(_userData);
- assert(_libdbusPendingCall);
+void DBusConnection::onLibdbusPendingCall(::DBusPendingCall* _libdbusPendingCall,
+ const DBusMessage& _reply,
+ DBusMessageReplyAsyncHandler* _dbusMessageReplyAsyncHandler) const {
- auto dbusMessageReplyAsyncHandler = reinterpret_cast<DBusMessageReplyAsyncHandler*>(_userData);
+ CallStatus callStatus = CallStatus::SUCCESS;
+ if (_reply.isErrorType() || !_reply.isMethodReturnType()) {
+ if(strcmp(_reply.getError(), DBUS_ERROR_UNKNOWN_METHOD) == 0) {
+ callStatus = CallStatus::NOT_AVAILABLE;
+ } else {
+ callStatus = CallStatus::REMOTE_ERROR;
+ }
+ }
- dbusMessageReplyAsyncHandler->lock();
- bool processAsyncHandler = !dbusMessageReplyAsyncHandler->getTimeoutOccurred();
- dbusMessageReplyAsyncHandler->setExecutionStarted();
- dbusMessageReplyAsyncHandler->unlock();
+ _dbusMessageReplyAsyncHandler->lock();
+ bool processAsyncHandler = !_dbusMessageReplyAsyncHandler->getTimeoutOccurred();
+ _dbusMessageReplyAsyncHandler->setExecutionStarted();
+ _dbusMessageReplyAsyncHandler->unlock();
- if (processAsyncHandler) {
- DBusMessage dbusMessage;
- CallStatus callStatus;
- dbusMessage = DBusConnection::convertToDBusMessage(_libdbusPendingCall, callStatus);
+ if (processAsyncHandler)
+ _dbusMessageReplyAsyncHandler->onDBusMessageReply(callStatus, _reply);
- dbusMessageReplyAsyncHandler->onDBusMessageReply(callStatus, dbusMessage);
- }
+ _dbusMessageReplyAsyncHandler->lock();
- dbusMessageReplyAsyncHandler->lock();
// libdbus calls the cleanup method below
- dbus_pending_call_unref(_libdbusPendingCall);
+ if(_libdbusPendingCall)
+ dbus_pending_call_unref(_libdbusPendingCall);
- dbusMessageReplyAsyncHandler->setExecutionFinished();
- if (dbusMessageReplyAsyncHandler->hasToBeDeleted()) {
- dbusMessageReplyAsyncHandler->unlock();
- delete dbusMessageReplyAsyncHandler;
+ _dbusMessageReplyAsyncHandler->setExecutionFinished();
+ if (_dbusMessageReplyAsyncHandler->hasToBeDeleted()) {
+ _dbusMessageReplyAsyncHandler->unlock();
+ delete _dbusMessageReplyAsyncHandler;
+ } else {
+ _dbusMessageReplyAsyncHandler->unlock();
+ }
+}
+
+void DBusConnection::onLibdbusPendingCallNotifyThunk(::DBusPendingCall* _libdbusPendingCall, void *_userData) {
+ if (NULL == _libdbusPendingCall) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "_libdbusPendingCall == NULL");
return;
}
- dbusMessageReplyAsyncHandler->unlock();
+ if (NULL == _userData) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "_userData == NULL");
+ return;
+ }
+
+ auto pendingCallNotificationData = reinterpret_cast<PendingCallNotificationData*>(_userData);
+ auto dbusMessageReplyAsyncHandler = pendingCallNotificationData->replyAsyncHandler_;
+ auto dbusConnection = pendingCallNotificationData->dbusConnection_;
+ delete pendingCallNotificationData;
+
+ DBusMessage dbusMessage = DBusConnection::convertToDBusMessage(_libdbusPendingCall);
+
+ dbusConnection->onLibdbusPendingCall(_libdbusPendingCall, dbusMessage, dbusMessageReplyAsyncHandler);
}
void DBusConnection::onLibdbusDataCleanup(void *_data) {
@@ -608,15 +690,19 @@ void DBusConnection::enforceAsynchronousTimeouts() const {
// => add asyncHandler to mainloopTimeouts list
DBusMessage& dbusMessageCall = std::get<2>(it->second);
- assert(mainLoopContext_.lock());
- {
- std::lock_guard<std::mutex> itsLock(mainloopTimeoutsMutex_);
- mainloopTimeouts_.push_back(std::make_tuple(asyncHandler,
- dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT),
- CallStatus::REMOTE_ERROR,
- nullptr));
+ auto lockedContext = mainLoopContext_.lock();
+ if (!lockedContext) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "lockedContext == nullptr");
+ } else {
+ {
+ std::lock_guard<std::mutex> itsLock(mainloopTimeoutsMutex_);
+ mainloopTimeouts_.push_back(std::make_tuple(asyncHandler,
+ dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT),
+ CallStatus::REMOTE_ERROR,
+ nullptr));
+ }
+ lockedContext->wakeup();
}
- mainLoopContext_.lock()->wakeup();
it = timeoutMap_.erase(it);
//This unref MIGHT cause the destruction of the last callback object that references the DBusConnection.
@@ -687,21 +773,34 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync(
std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler,
const CommonAPI::CallInfo *_info) const {
- assert(dbusMessage);
- assert(isConnected());
+ if (!dbusMessage) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "message == NULL");
+ return std::future<CallStatus>();
+ }
+ if (!isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected");
+ return std::future<CallStatus>();
+ }
DBusPendingCall* libdbusPendingCall;
dbus_bool_t libdbusSuccess;
DBusMessageReplyAsyncHandler* replyAsyncHandler = dbusMessageReplyAsyncHandler.release();
- std::future<CallStatus> callStatusFuture = replyAsyncHandler->getFuture();
+ std::future<CallStatus> callStatusFuture;
+ try {
+ callStatusFuture = replyAsyncHandler->getFuture();
+ } catch (std::exception& e) {
+ (void)e;
+ }
+
+ PendingCallNotificationData* userData = new PendingCallNotificationData(this, replyAsyncHandler);
libdbusSuccess = dbus_connection_send_with_reply_set_notify(connection_,
dbusMessage.message_,
&libdbusPendingCall,
onLibdbusPendingCallNotifyThunk,
- replyAsyncHandler,
+ userData,
onLibdbusDataCleanup,
_info->timeout_);
@@ -743,7 +842,13 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync(
};
enforceTimeoutMutex_.lock();
- timeoutMap_.insert( { libdbusPendingCall, toInsert } );
+ auto ret = timeoutMap_.insert( { libdbusPendingCall, toInsert } );
+ if (ret.second == false) {
+ // key has been reused
+ // update the map value with the new info
+ timeoutMap_.erase(ret.first);
+ timeoutMap_.insert( { libdbusPendingCall, toInsert } );
+ }
enforceTimeoutMutex_.unlock();
enforcerThreadMutex_.lock();
@@ -761,9 +866,14 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync(
DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage,
DBusError& dbusError,
const CommonAPI::CallInfo *_info) const {
- assert(dbusMessage);
- assert(!dbusError);
- assert(isConnected());
+ if (!dbusMessage) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "message == NULL");
+ return DBusMessage();
+ }
+ if (!isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected");
+ return DBusMessage();
+ }
::DBusMessage* libdbusMessageReply = dbus_connection_send_with_reply_and_block(connection_,
dbusMessage.message_,
@@ -775,6 +885,7 @@ DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage&
}
if (dbusError) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "dbusError set");
return DBusMessage();
}
@@ -782,6 +893,13 @@ DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage&
return DBusMessage(libdbusMessageReply, increaseLibdbusMessageReferenceCount);
}
+void DBusConnection::dispatchDBusMessageReply(const DBusMessage& _reply,
+ DBusMessageReplyAsyncHandler* _dbusMessageReplyAsyncHandler) {
+ if(setDispatching(true)) {
+ onLibdbusPendingCall(NULL, _reply, _dbusMessageReplyAsyncHandler);
+ setDispatching(false);
+ }
+}
bool DBusConnection::singleDispatch() {
{
@@ -795,14 +913,25 @@ bool DBusConnection::singleDispatch() {
}
mainloopTimeouts_.clear();
}
-
- return (dbus_connection_dispatch(connection_) == DBUS_DISPATCH_DATA_REMAINS);
+ if(setDispatching(true)) {
+ bool dispatchStatus(connection_ && dbus_connection_dispatch(connection_) == DBUS_DISPATCH_DATA_REMAINS);
+ setDispatching(false);
+ return dispatchStatus;
+ } else {
+ return false;
+ }
}
bool DBusConnection::isDispatchReady() {
std::lock_guard<std::mutex> itsLock(mainloopTimeoutsMutex_);
- return (dbus_connection_get_dispatch_status(connection_) == DBUS_DISPATCH_DATA_REMAINS ||
+
+ if(setDispatching(true)) {
+ bool dispatchStatus((connection_ && dbus_connection_get_dispatch_status(connection_) == DBUS_DISPATCH_DATA_REMAINS) ||
!mainloopTimeouts_.empty());
+ setDispatching(false);
+ return dispatchStatus;
+ }
+ return false;
}
bool DBusConnection::hasDispatchThread() {
@@ -813,48 +942,95 @@ const ConnectionId_t& DBusConnection::getConnectionId() const {
return connectionId_;
}
-bool DBusConnection::sendPendingSelectiveSubscription(DBusProxy* proxy, std::string methodName) {
- bool subscriptionAccepted;
- CommonAPI::CallStatus callStatus;
- DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<>,
- CommonAPI::DBus::DBusSerializableArguments<bool>>::callMethodWithReply(
- *proxy, methodName.c_str(), "", &CommonAPI::DBus::defaultCallInfo, callStatus, subscriptionAccepted);
+void DBusConnection::incrementConnection() {
+ std::lock_guard < std::mutex > lock(activeConnectionsMutex_);
+ activeConnections_++;
+}
+
+void DBusConnection::decrementConnection() {
+ std::lock_guard < std::mutex > lock(activeConnectionsMutex_);
+ activeConnections_--;
+
+ if (activeConnections_ <= 0) {
+ disconnect();
+ }
+}
+
+bool DBusConnection::setDispatching(bool _isDispatching) {
+ std::lock_guard<std::mutex> dispatchLock(dispatchMutex_);
+
+ if(isDispatching_ == _isDispatching)
+ return true;
- return subscriptionAccepted;
+ dispatchThreads_.insert(std::this_thread::get_id());
+ if(isDisconnecting_) { // we want to disconnect and only accept unsetting the dispatch flag
+ if(!_isDispatching) {
+ isDispatching_ = _isDispatching;
+ if(isWaitingOnFinishedDispatching_)
+ dispatchCondition_.notify_one();
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ isDispatching_ = _isDispatching;
+ return true;
+ }
+}
+
+void DBusConnection::sendPendingSelectiveSubscription(DBusProxy* callingProxy, std::string methodName,
+ DBusSignalHandler* dbusSignalHandler, uint32_t tag) {
+ bool outarg;
+ DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<>,
+ CommonAPI::DBus::DBusSerializableArguments<bool>>::callMethodAsync(
+ *callingProxy, methodName.c_str(), "",
+ &CommonAPI::DBus::defaultCallInfo,
+ [this, dbusSignalHandler, callingProxy, tag]
+ (const CommonAPI::CallStatus& callStatus, const bool& accepted) {
+
+ if (callStatus == CommonAPI::CallStatus::SUCCESS && accepted) {
+ dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUCCESS, tag);
+ } else {
+ dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED, tag);
+ }
+ }, std::make_tuple(outarg));
}
-DBusProxyConnection::DBusSignalHandlerToken DBusConnection::subscribeForSelectiveBroadcast(
- bool& subscriptionAccepted,
+void DBusConnection::subscribeForSelectiveBroadcast(
const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
DBusSignalHandler* dbusSignalHandler,
- DBusProxy* callingProxy) {
+ DBusProxy* callingProxy,
+ uint32_t tag) {
std::string methodName = "subscribeFor" + interfaceMemberName + "Selective";
- subscriptionAccepted = false;
-
- CommonAPI::CallStatus callStatus;
+ bool outarg;
DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<>,
- CommonAPI::DBus::DBusSerializableArguments<bool>>::callMethodWithReply(
- *callingProxy, methodName.c_str(), "", &CommonAPI::DBus::defaultCallInfo, callStatus, subscriptionAccepted);
-
- DBusProxyConnection::DBusSignalHandlerToken subscriptionToken;
- if ((callStatus == CommonAPI::CallStatus::SUCCESS && subscriptionAccepted) || !callingProxy->isAvailable()) {
- subscriptionToken = addSignalMemberHandler(
- objectPath,
- interfaceName,
- interfaceMemberName,
- interfaceMemberSignature,
- dbusSignalHandler,
- true
- );
- subscriptionAccepted = true;
- }
-
- return (subscriptionToken);
+ CommonAPI::DBus::DBusSerializableArguments<bool>>::callMethodAsync(
+ *callingProxy, methodName.c_str(), "",
+ &CommonAPI::DBus::defaultCallInfo,
+ [this, objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature, dbusSignalHandler, callingProxy, tag]
+ (const CommonAPI::CallStatus& callStatus, const bool& accepted) {
+ if ((callStatus == CommonAPI::CallStatus::SUCCESS && accepted) || !callingProxy->isAvailable()) {
+ DBusProxyConnection::DBusSignalHandlerToken token = addSignalMemberHandler(
+ objectPath,
+ interfaceName,
+ interfaceMemberName,
+ interfaceMemberSignature,
+ dbusSignalHandler,
+ true
+ );
+ dbusSignalHandler->setSubscriptionToken(token, tag);
+ }
+ if (accepted) {
+ dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUCCESS, tag);
+ } else {
+ dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED, tag);
+ }
+ }, std::make_tuple(outarg));
}
void DBusConnection::unsubscribeFromSelectiveBroadcast(const std::string& eventName,
@@ -955,8 +1131,9 @@ bool DBusConnection::addObjectManagerSignalMemberHandler(const std::string& dbus
if (!isInsertSuccessful) {
if (isConnected()) {
const bool isRemoveSignalMatchRuleSuccessful = removeObjectManagerSignalMatchRule(dbusBusName);
- assert(isRemoveSignalMatchRuleSuccessful);
- (void)isRemoveSignalMatchRuleSuccessful;
+ if (!isRemoveSignalMatchRuleSuccessful) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " removeObjectManagerSignalMatchRule", dbusBusName, " failed");
+ }
}
return false;
}
@@ -973,7 +1150,10 @@ bool DBusConnection::addObjectManagerSignalMemberHandler(const std::string& dbus
bool DBusConnection::removeObjectManagerSignalMemberHandler(const std::string& dbusBusName,
DBusSignalHandler* dbusSignalHandler) {
- assert(!dbusBusName.empty());
+ if (dbusBusName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty dbusBusName");
+ return false;
+ }
std::lock_guard<std::mutex> dbusSignalLock(dbusObjectManagerSignalGuard_);
@@ -996,8 +1176,11 @@ bool DBusConnection::removeObjectManagerSignalMemberHandler(const std::string& d
size_t& dbusSignalMatchRuleReferenceCount = dbusSignalMatchRuleIterator->second;
- assert(dbusSignalMatchRuleReferenceCount > 0);
- dbusSignalMatchRuleReferenceCount--;
+ if (0 == dbusSignalMatchRuleReferenceCount) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "ref count == 0");
+ } else {
+ dbusSignalMatchRuleReferenceCount--;
+ }
const bool isLastDBusSignalMatchRuleReference = (dbusSignalMatchRuleReferenceCount == 0);
if (isLastDBusSignalMatchRuleReference) {
@@ -1083,8 +1266,14 @@ bool DBusConnection::removeLibdbusSignalMatchRule(const std::string& dbusMatchRu
}
void DBusConnection::registerObjectPath(const std::string& objectPath) {
- assert(!objectPath.empty());
- assert(objectPath[0] == '/');
+ if (objectPath.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty objectPath");
+ return;
+ }
+ if ('/' != objectPath[0]) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid objectPath ", objectPath);
+ return;
+ }
auto handlerIterator = libdbusRegisteredObjectPaths_.find(objectPath);
const bool foundRegisteredObjectPathHandler = handlerIterator != libdbusRegisteredObjectPaths_.end();
@@ -1104,22 +1293,33 @@ void DBusConnection::registerObjectPath(const std::string& objectPath) {
getDBusObjectPathVTable(),
this,
&dbusError.libdbusError_);
- assert(libdbusSuccess);
- assert(!dbusError);
- (void)libdbusSuccess;
- (void)dbusError;
+
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_connection_try_register_object_path failed for ", objectPath);
+ }
+ if (dbusError) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " name: ", dbusError.getName(), " message: ", dbusError.getMessage());
+ }
}
}
void DBusConnection::unregisterObjectPath(const std::string& objectPath) {
- assert(!objectPath.empty());
- assert(objectPath[0] == '/');
+ if (objectPath.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty objectPath");
+ return;
+ }
+ if ('/' != objectPath[0]) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid objectPath ", objectPath);
+ return;
+ }
auto handlerIterator = libdbusRegisteredObjectPaths_.find(objectPath);
const bool foundRegisteredObjectPathHandler = handlerIterator != libdbusRegisteredObjectPaths_.end();
- assert(foundRegisteredObjectPathHandler);
- (void)foundRegisteredObjectPathHandler;
+ if (!foundRegisteredObjectPathHandler) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no handler found for ", objectPath);
+ return;
+ }
uint32_t& referenceCount = handlerIterator->second;
if (referenceCount > 1) {
@@ -1130,10 +1330,11 @@ void DBusConnection::unregisterObjectPath(const std::string& objectPath) {
libdbusRegisteredObjectPaths_.erase(handlerIterator);
if (isConnected()) {
- dbus_bool_t libdbusSuccess
+ const dbus_bool_t libdbusSuccess
= dbus_connection_unregister_object_path(connection_, objectPath.c_str());
- assert(libdbusSuccess);
- (void)libdbusSuccess;
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_connection_unregister_object_path failed for ", objectPath);
+ }
}
}
@@ -1166,8 +1367,10 @@ void DBusConnection::addLibdbusSignalMatchRule(const std::string& objectPath,
auto success = dbusSignalMatchRulesMap_.insert(
DBusSignalMatchRulesMap::value_type(dbusSignalMatchRuleTuple,
DBusSignalMatchRuleMapping(1, matchRuleString)));
- assert(success.second);
- (void)success;
+ if (!success.second) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "dbusSignalMatchRulesMap_.insert failed ", matchRuleString);
+ return;
+ }
if (isConnected()) {
bool libdbusSuccess = true;
@@ -1180,7 +1383,9 @@ void DBusConnection::addLibdbusSignalMatchRule(const std::string& objectPath,
&onLibdbusSignalFilterThunk,
this,
NULL);
- assert(libdbusSuccess);
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_connection_add_filter() failed");
+ }
}
if (!justAddFilter)
@@ -1188,8 +1393,10 @@ void DBusConnection::addLibdbusSignalMatchRule(const std::string& objectPath,
// finally add the match rule
DBusError dbusError;
dbus_bus_add_match(connection_, matchRuleString.c_str(), &dbusError.libdbusError_);
- assert(!dbusError);
- (void)dbusError;
+
+ if (dbusError) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " name: ", dbusError.getName(), " message: ", dbusError.getMessage());
+ }
}
if (libdbusSuccess) {
@@ -1206,8 +1413,10 @@ void DBusConnection::removeLibdbusSignalMatchRule(const std::string& objectPath,
auto matchRuleIterator = dbusSignalMatchRulesMap_.find(dbusSignalMatchRuleTuple);
const bool matchRuleFound = matchRuleIterator != dbusSignalMatchRulesMap_.end();
- assert(matchRuleFound);
- (void)matchRuleFound;
+ if (!matchRuleFound) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no match rule found for path: ", objectPath,
+ "interface: ", interfaceName, " member: ", interfaceMemberName);
+ }
uint32_t& matchRuleReferenceCount = matchRuleIterator->second.first;
if (matchRuleReferenceCount > 1) {
@@ -1218,15 +1427,19 @@ void DBusConnection::removeLibdbusSignalMatchRule(const std::string& objectPath,
if (isConnected()) {
const std::string& matchRuleString = matchRuleIterator->second.second;
const bool libdbusSuccess = removeLibdbusSignalMatchRule(matchRuleString);
- assert(libdbusSuccess);
- (void)libdbusSuccess;
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " removeLibdbusSignalMatchRule failed ", matchRuleString);
+ }
}
dbusSignalMatchRulesMap_.erase(matchRuleIterator);
}
void DBusConnection::initLibdbusObjectPathHandlerAfterConnect() {
- assert(isConnected());
+ if (!isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected");
+ return;
+ }
// nothing to do if there aren't any registered object path handlers
if (libdbusRegisteredObjectPaths_.empty()) {
@@ -1248,37 +1461,46 @@ void DBusConnection::initLibdbusObjectPathHandlerAfterConnect() {
getDBusObjectPathVTable(),
this,
&dbusError.libdbusError_);
- assert(libdbusSuccess);
- (void)libdbusSuccess;
-
- assert(!dbusError);
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_connection_try_register_object_path(", objectPath , ") failed ");
+ }
+ if (dbusError) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " name: ", dbusError.getName(), " message: ", dbusError.getMessage());
+ }
}
}
void DBusConnection::initLibdbusSignalFilterAfterConnect() {
- assert(isConnected());
+ if (!isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected");
+ return;
+ }
// proxy/stub match rules
for (const auto& dbusSignalMatchRuleIterator : dbusSignalMatchRulesMap_) {
const auto& dbusSignalMatchRuleMapping = dbusSignalMatchRuleIterator.second;
const std::string& dbusMatchRuleString = dbusSignalMatchRuleMapping.second;
const bool libdbusSuccess = addLibdbusSignalMatchRule(dbusMatchRuleString);
- assert(libdbusSuccess);
- (void)libdbusSuccess;
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " addLibdbusSignalMatchRule(", dbusMatchRuleString , ") failed ");
+ }
}
// object manager match rules (see DBusServiceRegistry)
for (const auto& dbusObjectManagerSignalMatchRuleIterator : dbusObjectManagerSignalMatchRulesMap_) {
const std::string& dbusBusName = dbusObjectManagerSignalMatchRuleIterator.first;
const bool libdbusSuccess = addObjectManagerSignalMatchRule(dbusBusName);
- assert(libdbusSuccess);
- (void)libdbusSuccess;
+ if (!libdbusSuccess) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " addObjectManagerSignalMatchRule(", dbusBusName , ") failed ");
+ }
}
}
::DBusHandlerResult DBusConnection::onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage) {
- assert(libdbusMessage);
- (void)libdbusMessage;
+ if (NULL == libdbusMessage) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " libdbusMessage == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
// handle only method call messages
if (dbus_message_get_type(libdbusMessage) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
@@ -1299,7 +1521,6 @@ void notifyDBusSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable,
return;
}
- signalEntry->second.first->lock();
auto handlerEntry = signalEntry->second.second.begin();
while (handlerEntry != signalEntry->second.second.end()) {
DBusProxyConnection::DBusSignalHandler* dbusSignalHandler = *handlerEntry;
@@ -1307,7 +1528,6 @@ void notifyDBusSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable,
handlerEntry++;
}
dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED;
- signalEntry->second.first->unlock();
}
template<typename DBusSignalHandlersTable>
@@ -1329,7 +1549,10 @@ void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable
}
::DBusHandlerResult DBusConnection::onLibdbusSignalFilter(::DBusMessage* libdbusMessage) {
- assert(libdbusMessage);
+ if (NULL == libdbusMessage) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " libdbusMessage == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
auto selfReference = this->shared_from_this();
@@ -1343,10 +1566,10 @@ void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable
const char* interfaceMemberName = dbus_message_get_member(libdbusMessage);
const char* interfaceMemberSignature = dbus_message_get_signature(libdbusMessage);
- assert(objectPath);
- assert(interfaceName);
- assert(interfaceMemberName);
- assert(interfaceMemberSignature);
+ if (NULL == objectPath || NULL == interfaceName || NULL == interfaceMemberName || NULL == interfaceMemberSignature ) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid message");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
DBusMessage dbusMessage(libdbusMessage);
::DBusHandlerResult dbusHandlerResult = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1357,14 +1580,23 @@ void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable
interfaceName,
interfaceMemberName,
interfaceMemberSignature));
+
+ if(signalEntry != dbusSignalHandlerTable_.end())
+ signalEntry->second.first->lock();
signalGuard_.unlock();
notifyDBusSignalHandlers(dbusSignalHandlerTable_,
signalEntry, dbusMessage, dbusHandlerResult);
+ if(signalEntry != dbusSignalHandlerTable_.end())
+ signalEntry->second.first->unlock();
+
if (dbusMessage.hasInterfaceName("org.freedesktop.DBus.ObjectManager")) {
const char* dbusSenderName = dbusMessage.getSender();
- assert(dbusSenderName);
+ if (NULL == dbusSenderName) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusSenderName == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
dbusObjectManagerSignalGuard_.lock();
auto dbusObjectManagerSignalHandlerIteratorPair = dbusObjectManagerSignalHandlerTable_.equal_range(dbusSenderName);
@@ -1381,26 +1613,50 @@ void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable
::DBusHandlerResult DBusConnection::onLibdbusSignalFilterThunk(::DBusConnection *_dbusConnection,
::DBusMessage* libdbusMessage,
void* userData) {
- assert(_dbusConnection);
- assert(libdbusMessage);
- assert(userData);
- (void)_dbusConnection;
+ if (NULL == _dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " _dbusConnection == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ if (NULL == libdbusMessage) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " libdbusMessage == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ if (NULL == userData) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " userData == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
DBusConnection* dbusConnection = reinterpret_cast<DBusConnection*>(userData);
- assert(dbusConnection->connection_ == _dbusConnection);
+ if (dbusConnection->connection_ != _dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " wrong connection!?");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
return dbusConnection->onLibdbusSignalFilter(libdbusMessage);
}
::DBusHandlerResult DBusConnection::onLibdbusObjectPathMessageThunk(::DBusConnection *_dbusConnection,
::DBusMessage* libdbusMessage,
void* userData) {
- assert(_dbusConnection);
- assert(libdbusMessage);
- assert(userData);
- (void)_dbusConnection;
+ if (NULL == _dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " _dbusConnection == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ if (NULL == libdbusMessage) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " libdbusMessage == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ if (NULL == userData) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " userData == NULL");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
DBusConnection* dbusConnection = reinterpret_cast<DBusConnection*>(userData);
- assert(dbusConnection->connection_ == _dbusConnection);
+ if (dbusConnection->connection_ != _dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " wrong connection!?");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
return dbusConnection->onLibdbusObjectPathMessage(libdbusMessage);
}
@@ -1412,5 +1668,15 @@ std::shared_ptr<DBusConnection> DBusConnection::wrap(::DBusConnection *_connecti
return std::make_shared<DBusConnection>(_connection, _connectionId);
}
+void DBusConnection::pushDBusMessageReply(const DBusMessage& _reply,
+ std::unique_ptr<DBusMessageReplyAsyncHandler> _dbusMessageReplyAsyncHandler) {
+ // push message to the message queue
+ DBusMessageReplyAsyncHandler* replyAsyncHandler = _dbusMessageReplyAsyncHandler.release();
+ replyAsyncHandler->setHasToBeDeleted();
+ std::shared_ptr<DBusMessageWatch::MsgReplyQueueEntry> msgReplyQueueEntry = std::make_shared<DBusMessageWatch::MsgReplyQueueEntry>(
+ replyAsyncHandler, _reply);
+ msgWatch_->pushMsgQueue(msgReplyQueueEntry);
+}
+
} // namespace DBus
} // namespace CommonAPI
diff --git a/src/CommonAPI/DBus/DBusDaemonProxy.cpp b/src/CommonAPI/DBus/DBusDaemonProxy.cpp
index ee434b1..58ee08f 100644
--- a/src/CommonAPI/DBus/DBusDaemonProxy.cpp
+++ b/src/CommonAPI/DBus/DBusDaemonProxy.cpp
@@ -39,7 +39,6 @@ static const char *DAEMON_DBUS_INTERFACE = DBusDaemonProxy::getInterfaceId();
static const char *DAEMON_DBUS_OBJECT_PATH = "/org/freedesktop/DBus";
static const char *DAEMON_DBUS_BUS = "org.freedesktop.DBus";
static DBusAddress dbusProxyAddress(DAEMON_DBUS_INTERFACE, DAEMON_DBUS_OBJECT_PATH, DAEMON_DBUS_BUS);
-static CommonAPI::CallInfo daemonProxyInfo(30000);
DBusDaemonProxy::DBusDaemonProxy(const std::shared_ptr<DBusProxyConnection>& dbusConnection):
DBusProxyBase(dbusProxyAddress, dbusConnection),
@@ -60,6 +59,12 @@ bool DBusDaemonProxy::isAvailableBlocking() const {
return isAvailable();
}
+std::future<AvailabilityStatus> DBusDaemonProxy::isAvailableAsync(
+ isAvailableAsyncCallback _callback,
+ const CallInfo *_info) const {
+ return isAvailableAsync(_callback, _info);
+}
+
ProxyStatusEvent& DBusDaemonProxy::getProxyStatusEvent() {
return getDBusConnection()->getConnectionStatusEvent();
}
@@ -94,14 +99,6 @@ void DBusDaemonProxy::listNames(CommonAPI::CallStatus& callStatus, std::vector<s
callStatus = CallStatus::SUCCESS;
}
-std::future<CallStatus> DBusDaemonProxy::listNamesAsync(ListNamesAsyncCallback listNamesAsyncCallback) const {
- DBusMessage dbusMessage = createMethodCall("ListNames", "");
- return getDBusConnection()->sendDBusMessageWithReplyAsync(
- dbusMessage,
- DBusProxyAsyncCallbackHandler<std::vector<std::string>>::create(listNamesAsyncCallback, std::tuple<std::vector<std::string>>()),
- &daemonProxyInfo);
-}
-
void DBusDaemonProxy::nameHasOwner(const std::string& busName, CommonAPI::CallStatus& callStatus, bool& hasOwner) const {
DBusMessage dbusMethodCall = createMethodCall("NameHasOwner", "s");
@@ -132,54 +129,6 @@ void DBusDaemonProxy::nameHasOwner(const std::string& busName, CommonAPI::CallSt
callStatus = CallStatus::SUCCESS;
}
-std::future<CallStatus> DBusDaemonProxy::nameHasOwnerAsync(const std::string& busName, NameHasOwnerAsyncCallback nameHasOwnerAsyncCallback) const {
- DBusMessage dbusMessage = createMethodCall("NameHasOwner", "s");
-
- DBusOutputStream outputStream(dbusMessage);
- const bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);
- if (!success) {
- std::promise<CallStatus> promise;
- promise.set_value(CallStatus::OUT_OF_MEMORY);
- return promise.get_future();
- }
- outputStream.flush();
-
- return getDBusConnection()->sendDBusMessageWithReplyAsync(
- dbusMessage,
- DBusProxyAsyncCallbackHandler<bool>::create(nameHasOwnerAsyncCallback, std::tuple<bool>()),
- &daemonProxyInfo);
-}
-
-std::future<CallStatus> DBusDaemonProxy::getManagedObjectsAsync(const std::string& forDBusServiceName, GetManagedObjectsAsyncCallback callback) const {
- static DBusAddress address(forDBusServiceName, "/", "org.freedesktop.DBus.ObjectManager");
- auto dbusMethodCallMessage = DBusMessage::createMethodCall(address, "GetManagedObjects", "");
-
- return getDBusConnection()->sendDBusMessageWithReplyAsync(
- dbusMethodCallMessage,
- DBusProxyAsyncCallbackHandler<DBusObjectToInterfaceDict>::create(
- callback, std::tuple<DBusObjectToInterfaceDict>()
- ),
- &daemonProxyInfo);
-}
-
-std::future<CallStatus> DBusDaemonProxy::getNameOwnerAsync(const std::string& busName, GetNameOwnerAsyncCallback getNameOwnerAsyncCallback) const {
- DBusMessage dbusMessage = createMethodCall("GetNameOwner", "s");
-
- DBusOutputStream outputStream(dbusMessage);
- const bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);
- if (!success) {
- std::promise<CallStatus> promise;
- promise.set_value(CallStatus::OUT_OF_MEMORY);
- return promise.get_future();
- }
- outputStream.flush();
-
- return getDBusConnection()->sendDBusMessageWithReplyAsync(
- dbusMessage,
- DBusProxyAsyncCallbackHandler<std::string>::create(getNameOwnerAsyncCallback, std::tuple<std::string>()),
- &daemonProxyInfo);
-}
-
const char* DBusDaemonProxy::getInterfaceId() {
static const char interfaceId[] = "org.freedesktop.DBus";
return interfaceId;
diff --git a/src/CommonAPI/DBus/DBusError.cpp b/src/CommonAPI/DBus/DBusError.cpp
index b5f5d5c..884f23b 100644
--- a/src/CommonAPI/DBus/DBusError.cpp
+++ b/src/CommonAPI/DBus/DBusError.cpp
@@ -3,7 +3,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <cstring>
#include <CommonAPI/DBus/DBusError.hpp>
diff --git a/src/CommonAPI/DBus/DBusFactory.cpp b/src/CommonAPI/DBus/DBusFactory.cpp
index 40da41f..d7fa84c 100644
--- a/src/CommonAPI/DBus/DBusFactory.cpp
+++ b/src/CommonAPI/DBus/DBusFactory.cpp
@@ -27,13 +27,37 @@ Factory::get() {
return theFactory;
}
-Factory::Factory() {
+Factory::Factory() : isInitialized_(false) {
}
Factory::~Factory() {
}
void
+Factory::init() {
+#ifndef WIN32
+ std::lock_guard<std::mutex> itsLock(initializerMutex_);
+#endif
+ if (!isInitialized_) {
+ for (auto i : initializers_) i();
+ initializers_.clear(); // Not needed anymore
+ isInitialized_ = true;
+ }
+}
+
+void
+Factory::registerInterface(InterfaceInitFunction _function) {
+ std::lock_guard<std::mutex> itsLock(initializerMutex_);
+ if (isInitialized_) {
+ // We are already running --> initialize the interface library!
+ _function();
+ } else {
+ // We are not initialized --> save the initializer
+ initializers_.push_back(_function);
+ }
+}
+
+void
Factory::registerProxyCreateMethod(
const std::string &_interface, ProxyCreateFunction _function) {
proxyCreateFunctions_[_interface] = _function;
@@ -222,13 +246,14 @@ Factory::unregisterStubAdapter(std::shared_ptr<DBusStubAdapter> _adapter) {
std::shared_ptr<DBusConnection>
Factory::getConnection(const ConnectionId_t &_connectionId) {
+ std::lock_guard<std::mutex> itsGuard(connectionsMutex_);
auto itsConnectionIterator = connections_.find(_connectionId);
if (itsConnectionIterator != connections_.end()) {
return itsConnectionIterator->second;
}
// No connection found, lets create and initialize one
- DBusType_t dbusType = DBusAddressTranslator::get()->getDBusBusType(_connectionId);
+ const DBusType_t dbusType = DBusAddressTranslator::get()->getDBusBusType(_connectionId);
std::shared_ptr<DBusConnection> itsConnection
= std::make_shared<DBusConnection>(dbusType, _connectionId);
connections_.insert({ _connectionId, itsConnection });
@@ -242,14 +267,16 @@ Factory::getConnection(std::shared_ptr<MainLoopContext> _context) {
if (!_context)
return getConnection(DEFAULT_CONNECTION_ID);
+ std::lock_guard<std::mutex> itsGuard(contextConnectionsMutex_);
auto itsConnectionIterator = contextConnections_.find(_context.get());
if (itsConnectionIterator != contextConnections_.end()) {
return itsConnectionIterator->second;
}
// No connection found, lets create and initialize one
+ const DBusType_t dbusType = DBusAddressTranslator::get()->getDBusBusType(_context->getName());
std::shared_ptr<DBusConnection> itsConnection
- = std::make_shared<DBusConnection>(DBusType_t::SESSION, _context->getName());
+ = std::make_shared<DBusConnection>(dbusType, _context->getName());
contextConnections_.insert({ _context.get(), itsConnection } );
itsConnection->connect(false);
@@ -310,9 +337,9 @@ Factory::registerManagedService(const std::shared_ptr<DBusStubAdapter> &_stubAda
const bool isAcquired = connection->requestServiceNameAndBlock(serviceName);
if (!isAcquired) {
const bool isDeregistered = objectManager->unregisterDBusStubAdapter(_stubAdapter);
- assert(isDeregistered);
- (void)isDeregistered;
-
+ if (!isDeregistered) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " couldn't deregister ", serviceName);
+ }
services_.erase(insertResult.first);
}
@@ -348,5 +375,87 @@ Factory::unregisterManagedService(const ServicesMap::iterator &iterator) {
return isUnregistered;
}
+void Factory::incrementConnection(std::shared_ptr<DBusProxyConnection> _connection) {
+ std::shared_ptr<DBusConnection> connection;
+ {
+ std::lock_guard<std::mutex> itsConnectionGuard(connectionsMutex_);
+ for (auto itsConnectionIterator = connections_.begin(); itsConnectionIterator != connections_.end(); itsConnectionIterator++) {
+ if (itsConnectionIterator->second == _connection) {
+ connection = itsConnectionIterator->second;
+ break;
+ }
+ }
+ }
+
+ if(connection)
+ connection->incrementConnection();
+
+ std::shared_ptr<DBusConnection> contextConnection;
+ {
+ std::lock_guard<std::mutex> itsContextConnectionGuard(contextConnectionsMutex_);
+ for (auto itsConnectionIterator = contextConnections_.begin(); itsConnectionIterator != contextConnections_.end(); itsConnectionIterator++) {
+ if (itsConnectionIterator->second == _connection) {
+ contextConnection = itsConnectionIterator->second;
+ break;
+ }
+ }
+ }
+
+ if(contextConnection)
+ contextConnection->incrementConnection();
+}
+
+void Factory::decrementConnection(std::shared_ptr<DBusProxyConnection> _connection) {
+ std::shared_ptr<DBusConnection> connection;
+ {
+ std::lock_guard<std::mutex> itsConnectionGuard(connectionsMutex_);
+ for (auto itsConnectionIterator = connections_.begin(); itsConnectionIterator != connections_.end(); itsConnectionIterator++) {
+ if (itsConnectionIterator->second == _connection) {
+ connection = itsConnectionIterator->second;
+ break;
+ }
+ }
+ }
+
+ if(connection)
+ connection->decrementConnection();
+
+ std::shared_ptr<DBusConnection> contextConnection;
+ {
+ std::lock_guard<std::mutex> itsContextConnectionGuard(contextConnectionsMutex_);
+ for (auto itsConnectionIterator = contextConnections_.begin(); itsConnectionIterator != contextConnections_.end(); itsConnectionIterator++) {
+ if (itsConnectionIterator->second == _connection) {
+ contextConnection = itsConnectionIterator->second;
+ break;
+ }
+ }
+ }
+
+ if(contextConnection)
+ contextConnection->decrementConnection();
+}
+
+void Factory::releaseConnection(const ConnectionId_t& _connectionId, MainLoopContext* _mainloopContext) {
+ {
+ std::lock_guard<std::mutex> itsConnectionGuard(connectionsMutex_);
+ auto connection = connections_.find(_connectionId);
+
+ if (connection != connections_.end()) {
+ DBusServiceRegistry::remove(connection->second);
+ connections_.erase(_connectionId);
+ }
+ }
+
+ {
+ std::lock_guard<std::mutex> itsContextConnectionGuard(contextConnectionsMutex_);
+ auto connectionContext = contextConnections_.find(_mainloopContext);
+
+ if (connectionContext != contextConnections_.end()) {
+ DBusServiceRegistry::remove(connectionContext->second);
+ contextConnections_.erase(_mainloopContext);
+ }
+ }
+}
+
} // namespace DBus
} // namespace CommonAPI
diff --git a/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp
index 75fc0b5..f41b77e 100644
--- a/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp
+++ b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp
@@ -3,8 +3,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <vector>
+#include <algorithm>
#include <CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp>
#include <CommonAPI/DBus/DBusStubAdapter.hpp>
@@ -21,14 +21,30 @@ DBusFreedesktopPropertiesStub::DBusFreedesktopPropertiesStub(
: path_(_path),
connection_(_connection),
adapter_(_adapter) {
- assert(!path_.empty());
- assert(path_[0] == '/');
- assert(_connection);
+ if (path_.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty _path");
+ }
+ if ('/' != path_[0]) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid _path ", _path);
+ }
+ if (!_connection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid _connection");
+ }
dbusInterfacesLock_.lock();
- if(managedInterfaces_.find(_interface) == managedInterfaces_.end()) {
- managedInterfaces_.insert({ _interface, _adapter });
+
+ const auto& it = managedInterfaces_.find(_interface);
+ if (it != managedInterfaces_.end()) {
+ auto& adapters = it->second;
+ if (find(adapters.begin(), adapters.end(), _adapter) == adapters.end()) {
+ adapters.push_back(_adapter);
+ it->second = adapters;
+ }
}
+ else {
+ managedInterfaces_.insert({ _interface, std::vector<std::shared_ptr<DBusStubAdapter>> ({_adapter}) });
+ }
+
dbusInterfacesLock_.unlock();
}
@@ -86,7 +102,12 @@ DBusFreedesktopPropertiesStub::onInterfaceDBusMessage(const DBusMessage &_messag
return false;
}
- return it->second->onInterfaceDBusFreedesktopPropertiesMessage(_message);
+ for (auto& adapter : it->second) {
+ adapter->onInterfaceDBusFreedesktopPropertiesMessage(_message);
+ }
+
+ // errors are ignored.
+ return true;
}
bool DBusFreedesktopPropertiesStub::hasFreedesktopProperties() {
diff --git a/src/CommonAPI/DBus/DBusFunctionalHash.cpp b/src/CommonAPI/DBus/DBusFunctionalHash.cpp
index 00b5da6..e82d578 100644
--- a/src/CommonAPI/DBus/DBusFunctionalHash.cpp
+++ b/src/CommonAPI/DBus/DBusFunctionalHash.cpp
@@ -3,11 +3,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <cstring>
#include <murmurhash/MurmurHash3.h>
+#include <CommonAPI/Logger.hpp>
#include <CommonAPI/DBus/DBusFunctionalHash.hpp>
/*
@@ -15,18 +15,29 @@
*/
#define SMHASHER_SEED_VALUE 0xc70f6907UL
+using namespace CommonAPI;
+
namespace std {
size_t hash<pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& t) const {
const char* a = t.first;
const char* b = t.second;
- assert(a);
- assert(b);
+ if (NULL == a) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " t.first is NULL");
+ }
+ if (NULL == b) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " t.second is NULL");
+ }
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(a, static_cast<int>(strlen(a)), seed, &seed);
- MurmurHash3_x86_32(b, static_cast<int>(strlen(b)), seed, &seed);
+
+ if (NULL != a) {
+ MurmurHash3_x86_32(a, static_cast<int>(strlen(a)), seed, &seed);
+ }
+ if (NULL != b) {
+ MurmurHash3_x86_32(b, static_cast<int>(strlen(b)), seed, &seed);
+ }
return static_cast<size_t>(seed);
}
diff --git a/src/CommonAPI/DBus/DBusInputStream.cpp b/src/CommonAPI/DBus/DBusInputStream.cpp
index ae2201a..0c838a0 100644
--- a/src/CommonAPI/DBus/DBusInputStream.cpp
+++ b/src/CommonAPI/DBus/DBusInputStream.cpp
@@ -13,7 +13,7 @@ namespace DBus {
DBusInputStream::DBusInputStream(const CommonAPI::DBus::DBusMessage &_message)
: begin_(_message.getBodyData()),
current_(0),
- size_(_message.getBodyLength()),
+ size_((size_t)(_message.getBodyLength())),
exception_(nullptr),
message_(_message) {
}
@@ -38,7 +38,10 @@ void DBusInputStream::align(const size_t _boundary) {
}
char *DBusInputStream::_readRaw(const size_t _size) {
- assert(current_ + _size <= size_);
+ if ((current_ + _size) > size_) {
+ setError();
+ return NULL;
+ }
char *data = (char *) (begin_ + current_);
current_ += _size;
@@ -130,14 +133,15 @@ InputStream<DBusInputStream> &DBusInputStream::readValue(double &_value, const E
InputStream<DBusInputStream> &DBusInputStream::readValue(std::string &_value, const EmptyDeployment *_depl) {
(void)_depl;
- uint32_t length;
+ uint32_t length(0);
_readValue(length);
// length field does not include terminating 0-byte, therefore length of data to read is +1
char *data = _readRaw(length + 1);
-
- // The string contained in a DBus-message is required to be 0-terminated, therefore the following line works
- _value = data;
+ if (!hasError()) {
+ // The string contained in a DBus-message is required to be 0-terminated, therefore the following line works
+ _value = data;
+ }
return (*this);
}
diff --git a/src/CommonAPI/DBus/DBusMainLoop.cpp b/src/CommonAPI/DBus/DBusMainLoop.cpp
index a46072f..b9daea3 100755
--- a/src/CommonAPI/DBus/DBusMainLoop.cpp
+++ b/src/CommonAPI/DBus/DBusMainLoop.cpp
@@ -203,6 +203,8 @@ DBusMainLoop::~DBusMainLoop() {
#else
close(wakeFd_.fd);
#endif
+
+ cleanup();
}
void DBusMainLoop::run(const int64_t& timeoutInterval) {
@@ -228,9 +230,9 @@ void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
if (!(dispatchSourceIterator->second)->isExecuted_) {
(dispatchSourceIterator->second)->mutex_->unlock();
bool contained = false;
- for (std::set<DispatchSourceToDispatchStruct*>::iterator dispatchSourceIteratorInner = sourcesToDispatch_.begin();
+ for (std::set<std::pair<DispatchPriority, DispatchSourceToDispatchStruct*>>::iterator dispatchSourceIteratorInner = sourcesToDispatch_.begin();
dispatchSourceIteratorInner != sourcesToDispatch_.end(); dispatchSourceIteratorInner++) {
- if ((*dispatchSourceIteratorInner)->dispatchSource_ == (dispatchSourceIterator->second)->dispatchSource_) {
+ if (std::get<1>(*dispatchSourceIteratorInner)->dispatchSource_ == (dispatchSourceIterator->second)->dispatchSource_) {
contained = true;
break;
}
@@ -268,9 +270,9 @@ void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
if (!(timeoutIterator->second)->isExecuted_) {
(timeoutIterator->second)->mutex_->unlock();
bool contained = false;
- for (std::set<TimeoutToDispatchStruct*>::iterator timeoutIteratorInner = timeoutsToDispatch_.begin();
+ for (std::set<std::pair<DispatchPriority, TimeoutToDispatchStruct*>>::iterator timeoutIteratorInner = timeoutsToDispatch_.begin();
timeoutIteratorInner != timeoutsToDispatch_.end(); timeoutIteratorInner++) {
- if ((*timeoutIteratorInner)->timeout_ == (timeoutIterator->second)->timeout_) {
+ if (std::get<1>(*timeoutIteratorInner)->timeout_ == (timeoutIterator->second)->timeout_) {
contained = true;
break;
}
@@ -310,7 +312,7 @@ void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
bool contained = false;
for (auto watchesIteratorInner = watchesToDispatch_.begin();
watchesIteratorInner != watchesToDispatch_.end(); watchesIteratorInner++) {
- if ((*watchesIteratorInner)->watch_ == (watchesIterator->second)->watch_) {
+ if (std::get<1>(*watchesIteratorInner)->watch_ == (watchesIterator->second)->watch_) {
contained = true;
break;
}
@@ -350,20 +352,22 @@ void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
bool DBusMainLoop::prepare(const int64_t& timeout) {
currentMinimalTimeoutInterval_ = timeout;
- {
- std::lock_guard<std::mutex> itsLock(dispatchSourcesMutex_);
- for (auto dispatchSourceIterator = registeredDispatchSources_.begin();
- dispatchSourceIterator != registeredDispatchSources_.end();
- dispatchSourceIterator++) {
+ dispatchSourcesMutex_.lock();
+ for (auto dispatchSourceIterator = registeredDispatchSources_.begin();
+ dispatchSourceIterator != registeredDispatchSources_.end();
+ dispatchSourceIterator++) {
- int64_t dispatchTimeout = TIMEOUT_INFINITE;
- if ((dispatchSourceIterator->second)->dispatchSource_->prepare(dispatchTimeout)) {
- sourcesToDispatch_.insert(dispatchSourceIterator->second);
- } else if (dispatchTimeout < currentMinimalTimeoutInterval_) {
- currentMinimalTimeoutInterval_ = dispatchTimeout;
- }
+ int64_t dispatchTimeout = TIMEOUT_INFINITE;
+ dispatchSourcesMutex_.unlock();
+ if (!(dispatchSourceIterator->second->deleteObject_) &&
+ (dispatchSourceIterator->second)->dispatchSource_->prepare(dispatchTimeout)) {
+ sourcesToDispatch_.insert(*dispatchSourceIterator);
+ } else if (dispatchTimeout > 0 && dispatchTimeout < currentMinimalTimeoutInterval_) {
+ currentMinimalTimeoutInterval_ = dispatchTimeout;
}
+ dispatchSourcesMutex_.lock();
}
+ dispatchSourcesMutex_.unlock();
int64_t currentContextTime = getCurrentTimeInMs();
@@ -386,7 +390,7 @@ bool DBusMainLoop::prepare(const int64_t& timeout) {
// set information that timeout is elapsed
(timeoutPriorityRange->second)->timeoutElapsed_ = true;
- timeoutsToDispatch_.insert(timeoutPriorityRange->second);
+ timeoutsToDispatch_.insert(*timeoutPriorityRange);
currentMinimalTimeoutInterval_ = TIMEOUT_NONE;
} else if (intervalToReady < currentMinimalTimeoutInterval_) {
currentMinimalTimeoutInterval_ = intervalToReady;
@@ -401,16 +405,18 @@ bool DBusMainLoop::prepare(const int64_t& timeout) {
void DBusMainLoop::poll() {
int managedFileDescriptorOffset = 0;
-
- for (auto fileDescriptor = managedFileDescriptors_.begin() + managedFileDescriptorOffset; fileDescriptor != managedFileDescriptors_.end(); ++fileDescriptor) {
- (*fileDescriptor).revents = 0;
+ {
+ std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_);
+ for (auto fileDescriptor = managedFileDescriptors_.begin() + managedFileDescriptorOffset; fileDescriptor != managedFileDescriptors_.end(); ++fileDescriptor) {
+ (*fileDescriptor).revents = 0;
+ }
}
-#ifdef WIN32
- size_t numReadyFileDescriptors = WSAPoll(&managedFileDescriptors_[0], managedFileDescriptors_.size(), -1);
+#ifdef WIN32
+ int numReadyFileDescriptors = WSAPoll(&managedFileDescriptors_[0], managedFileDescriptors_.size(), int(currentMinimalTimeoutInterval_));
#else
- size_t numReadyFileDescriptors = ::poll(&(managedFileDescriptors_[0]),
- managedFileDescriptors_.size(), -1);
+ int numReadyFileDescriptors = ::poll(&(managedFileDescriptors_[0]),
+ managedFileDescriptors_.size(), int(currentMinimalTimeoutInterval_));
#endif
if (!numReadyFileDescriptors) {
int64_t currentContextTime = getCurrentTimeInMs();
@@ -435,7 +441,7 @@ void DBusMainLoop::poll() {
// set information that timeout is elapsed
(timeoutPriorityRange->second)->timeoutElapsed_ = true;
- timeoutsToDispatch_.insert(timeoutPriorityRange->second);
+ timeoutsToDispatch_.insert(*timeoutPriorityRange);
}
}
}
@@ -450,7 +456,7 @@ void DBusMainLoop::poll() {
}
bool DBusMainLoop::check() {
-//The first file descriptor always is the loop's wakeup-descriptor (but not for windows anymore). All others need to be linked to a watch.
+ //The first file descriptor always is the loop's wakeup-descriptor (but not for windows anymore). All others need to be linked to a watch.
int managedFileDescriptorOffset = 1;
{
std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_);
@@ -461,7 +467,7 @@ bool DBusMainLoop::check() {
for (auto registeredWatchIterator = registeredWatches_.begin();
registeredWatchIterator != registeredWatches_.end();
registeredWatchIterator++) {
-
+
(registeredWatchIterator->second)->mutex_->lock();
bool deleteObject = (registeredWatchIterator->second)->deleteObject_;
(registeredWatchIterator->second)->mutex_->unlock();
@@ -469,23 +475,26 @@ bool DBusMainLoop::check() {
if (!deleteObject) {
if ((registeredWatchIterator->second)->fd_ == fileDescriptor->fd
&& fileDescriptor->revents) {
- watchesToDispatch_.insert(registeredWatchIterator->second);
+ watchesToDispatch_.insert(*registeredWatchIterator);
}
}
}
}
}
}
- {
- std::lock_guard<std::mutex> itsLock(dispatchSourcesMutex_);
- for (auto dispatchSourceIterator = registeredDispatchSources_.begin();
- dispatchSourceIterator != registeredDispatchSources_.end();
- ++dispatchSourceIterator) {
- if ((dispatchSourceIterator->second)->dispatchSource_->check()) {
- sourcesToDispatch_.insert(dispatchSourceIterator->second);
- }
+
+ dispatchSourcesMutex_.lock();
+ for (auto dispatchSourceIterator = registeredDispatchSources_.begin();
+ dispatchSourceIterator != registeredDispatchSources_.end();
+ ++dispatchSourceIterator) {
+ dispatchSourcesMutex_.unlock();
+ if (!dispatchSourceIterator->second->deleteObject_&&
+ dispatchSourceIterator->second->dispatchSource_->check()) {
+ sourcesToDispatch_.insert(*dispatchSourceIterator);
}
+ dispatchSourcesMutex_.lock();
}
+ dispatchSourcesMutex_.unlock();
return (!timeoutsToDispatch_.empty() ||
!watchesToDispatch_.empty() ||
@@ -497,15 +506,16 @@ void DBusMainLoop::dispatch() {
{
for (auto timeoutIterator = timeoutsToDispatch_.begin();
timeoutIterator != timeoutsToDispatch_.end(); timeoutIterator++) {
- (*timeoutIterator)->mutex_->lock();
- if (!(*timeoutIterator)->deleteObject_) {
- (*timeoutIterator)->isExecuted_ = true;
- (*timeoutIterator)->mutex_->unlock();
- (*timeoutIterator)->timeout_->dispatch();
- (*timeoutIterator)->mutex_->lock();
- (*timeoutIterator)->isExecuted_ = false;
+ auto timeoutToDispatchStruct = std::get<1>(*timeoutIterator);
+ timeoutToDispatchStruct->mutex_->lock();
+ if (!timeoutToDispatchStruct->deleteObject_) {
+ timeoutToDispatchStruct->isExecuted_ = true;
+ timeoutToDispatchStruct->mutex_->unlock();
+ timeoutToDispatchStruct->timeout_->dispatch();
+ timeoutToDispatchStruct->mutex_->lock();
+ timeoutToDispatchStruct->isExecuted_ = false;
}
- (*timeoutIterator)->mutex_->unlock();
+ timeoutToDispatchStruct->mutex_->unlock();
}
timeoutsToDispatch_.clear();
@@ -515,17 +525,18 @@ void DBusMainLoop::dispatch() {
{
for (auto watchIterator = watchesToDispatch_.begin();
watchIterator != watchesToDispatch_.end(); watchIterator++) {
- (*watchIterator)->mutex_->lock();
- if (!(*watchIterator)->deleteObject_) {
- (*watchIterator)->isExecuted_ = true;
- (*watchIterator)->mutex_->unlock();
- Watch* watch = (*watchIterator)->watch_;
- const unsigned int flags = watch->getAssociatedFileDescriptor().events;
+ auto watchToDispatchStruct = std::get<1>(*watchIterator);
+ watchToDispatchStruct->mutex_->lock();
+ if (!watchToDispatchStruct->deleteObject_) {
+ watchToDispatchStruct->isExecuted_ = true;
+ watchToDispatchStruct->mutex_->unlock();
+ Watch* watch = watchToDispatchStruct->watch_;
+ const unsigned int flags = (unsigned int)(watch->getAssociatedFileDescriptor().events);
watch->dispatch(flags);
- (*watchIterator)->mutex_->lock();
- (*watchIterator)->isExecuted_ = false;
+ watchToDispatchStruct->mutex_->lock();
+ watchToDispatchStruct->isExecuted_ = false;
}
- (*watchIterator)->mutex_->unlock();
+ watchToDispatchStruct->mutex_->unlock();
}
watchesToDispatch_.clear();
}
@@ -536,15 +547,17 @@ void DBusMainLoop::dispatch() {
for (auto dispatchSourceIterator = sourcesToDispatch_.begin();
dispatchSourceIterator != sourcesToDispatch_.end() && !isBroken_;
dispatchSourceIterator++) {
- (*dispatchSourceIterator)->mutex_->lock();
- if (!(*dispatchSourceIterator)->deleteObject_) {
- (*dispatchSourceIterator)->isExecuted_ = true;
- (*dispatchSourceIterator)->mutex_->unlock();
- while ((*dispatchSourceIterator)->dispatchSource_->dispatch());
- (*dispatchSourceIterator)->mutex_->lock();
- (*dispatchSourceIterator)->isExecuted_ = false;
+ auto dispatchSourceToDispatchStruct = std::get<1>(*dispatchSourceIterator);
+ dispatchSourceToDispatchStruct->mutex_->lock();
+ if (!dispatchSourceToDispatchStruct->deleteObject_) {
+ dispatchSourceToDispatchStruct->isExecuted_ = true;
+ dispatchSourceToDispatchStruct->mutex_->unlock();
+ while(!dispatchSourceToDispatchStruct->deleteObject_ &&
+ dispatchSourceToDispatchStruct->dispatchSource_->dispatch());
+ dispatchSourceToDispatchStruct->mutex_->lock();
+ dispatchSourceToDispatchStruct->isExecuted_ = false;
}
- (*dispatchSourceIterator)->mutex_->unlock();
+ dispatchSourceToDispatchStruct->mutex_->unlock();
}
{
sourcesToDispatch_.clear();
@@ -597,6 +610,50 @@ void DBusMainLoop::wakeupAck() {
#endif
}
+void DBusMainLoop::cleanup() {
+ {
+ std::lock_guard<std::mutex> itsLock(dispatchSourcesMutex_);
+ for (auto dispatchSourceIterator = registeredDispatchSources_.begin();
+ dispatchSourceIterator != registeredDispatchSources_.end();) {
+
+ delete (dispatchSourceIterator->second)->dispatchSource_;
+ (dispatchSourceIterator->second)->dispatchSource_ = NULL;
+ delete (dispatchSourceIterator->second)->mutex_;
+ (dispatchSourceIterator->second)->mutex_ = NULL;
+ delete dispatchSourceIterator->second;
+ dispatchSourceIterator = registeredDispatchSources_.erase(dispatchSourceIterator);
+ }
+ }
+
+ {
+ std::lock_guard<std::mutex> itsLock(timeoutsMutex_);
+ for (auto timeoutIterator = registeredTimeouts_.begin();
+ timeoutIterator != registeredTimeouts_.end();) {
+
+ delete (timeoutIterator->second)->timeout_;
+ (timeoutIterator->second)->timeout_ = NULL;
+ delete (timeoutIterator->second)->mutex_;
+ (timeoutIterator->second)->mutex_ = NULL;
+ delete timeoutIterator->second;
+ timeoutIterator = registeredTimeouts_.erase(timeoutIterator);
+ }
+ }
+
+ {
+ std::lock_guard<std::mutex> itsLock(watchesMutex_);
+ for (auto watchesIterator = registeredWatches_.begin();
+ watchesIterator != registeredWatches_.end();) {
+
+ delete (watchesIterator->second)->watch_;
+ (watchesIterator->second)->watch_ = NULL;
+ delete (watchesIterator->second)->mutex_;
+ (watchesIterator->second)->mutex_ = NULL;
+ delete watchesIterator->second;
+ watchesIterator = registeredWatches_.erase(watchesIterator);
+ }
+ }
+}
+
void DBusMainLoop::registerFileDescriptor(
const DBusMainLoopPollFd& fileDescriptor) {
std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_);
diff --git a/src/CommonAPI/DBus/DBusMainLoopContext.cpp b/src/CommonAPI/DBus/DBusMainLoopContext.cpp
index 1c795ad..5c8afa5 100644
--- a/src/CommonAPI/DBus/DBusMainLoopContext.cpp
+++ b/src/CommonAPI/DBus/DBusMainLoopContext.cpp
@@ -7,8 +7,12 @@
#include <WinSock2.h>
#else
#include <poll.h>
+#include <unistd.h>
#endif
+#include <fcntl.h>
+#include <cstdio>
+
#include <chrono>
#include <CommonAPI/DBus/DBusMainLoopContext.hpp>
@@ -25,7 +29,7 @@ DBusDispatchSource::~DBusDispatchSource() {
}
bool DBusDispatchSource::prepare(int64_t &_timeout) {
- (void)_timeout;
+ _timeout = -1;
return dbusConnection_->isDispatchReady();
}
@@ -37,11 +41,46 @@ bool DBusDispatchSource::dispatch() {
return dbusConnection_->singleDispatch();
}
+DBusMessageDispatchSource::DBusMessageDispatchSource(DBusMessageWatch* watch) :
+ watch_(watch) {
+ watch_->addDependentDispatchSource(this);
+}
+
+DBusMessageDispatchSource::~DBusMessageDispatchSource() {
+ std::unique_lock<std::mutex> itsLock(watchMutex_);
+ watch_->removeDependentDispatchSource(this);
+}
+
+bool DBusMessageDispatchSource::prepare(int64_t& timeout) {
+ std::unique_lock<std::mutex> itsLock(watchMutex_);
+ timeout = -1;
+ return !watch_->emptyMsgQueue();
+}
+
+bool DBusMessageDispatchSource::check() {
+ std::unique_lock<std::mutex> itsLock(watchMutex_);
+ return !watch_->emptyMsgQueue();
+}
+
+bool DBusMessageDispatchSource::dispatch() {
+ std::unique_lock<std::mutex> itsLock(watchMutex_);
+ if (!watch_->emptyMsgQueue()) {
+ auto queueEntry = watch_->frontMsgQueue();
+ watch_->popMsgQueue();
+ watch_->processMsgQueueEntry(queueEntry);
+ }
-DBusWatch::DBusWatch(::DBusWatch* libdbusWatch, std::weak_ptr<MainLoopContext>& mainLoopContext):
+ return !watch_->emptyMsgQueue();
+}
+
+DBusWatch::DBusWatch(::DBusWatch* libdbusWatch, std::weak_ptr<MainLoopContext>& mainLoopContext,
+ std::weak_ptr<DBusConnection>& dbusConnection):
libdbusWatch_(libdbusWatch),
- mainLoopContext_(mainLoopContext) {
- assert(libdbusWatch_);
+ mainLoopContext_(mainLoopContext),
+ dbusConnection_(dbusConnection) {
+ if (NULL == libdbusWatch_) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " libdbusWatch_ == NULL");
+ }
}
bool DBusWatch::isReadyToBeWatched() {
@@ -52,11 +91,8 @@ void DBusWatch::startWatching() {
if(!dbus_watch_get_enabled(libdbusWatch_)) stopWatching();
unsigned int channelFlags_ = dbus_watch_get_flags(libdbusWatch_);
-#ifdef WIN32
short int pollFlags = 0;
-#else
- short int pollFlags = POLLERR | POLLHUP;
-#endif
+
if(channelFlags_ & DBUS_WATCH_READABLE) {
pollFlags |= POLLIN;
}
@@ -76,8 +112,11 @@ void DBusWatch::startWatching() {
pollFileDescriptor_.revents = 0;
auto lockedContext = mainLoopContext_.lock();
- assert(lockedContext);
- lockedContext->registerWatch(this);
+ if (NULL == lockedContext) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " lockedContext == NULL");
+ } else {
+ lockedContext->registerWatch(this);
+ }
}
void DBusWatch::stopWatching() {
@@ -120,10 +159,15 @@ void DBusWatch::dispatch(unsigned int eventFlags) {
((eventFlags & POLLERR) >> 1) |
((eventFlags & POLLHUP) >> 1);
#endif
- dbus_bool_t response = dbus_watch_handle(libdbusWatch_, dbusWatchFlags);
-
- if (!response) {
- printf("dbus_watch_handle returned FALSE!");
+ std::shared_ptr<DBusConnection> itsConnection = dbusConnection_.lock();
+ if(itsConnection) {
+ if(itsConnection->setDispatching(true)) {
+ dbus_bool_t response = dbus_watch_handle(libdbusWatch_, dbusWatchFlags);
+ if (!response) {
+ printf("dbus_watch_handle returned FALSE!");
+ }
+ itsConnection->setDispatching(false);
+ }
}
}
@@ -135,6 +179,244 @@ void DBusWatch::addDependentDispatchSource(DispatchSource* dispatchSource) {
dependentDispatchSources_.push_back(dispatchSource);
}
+void DBusMessageWatch::MsgReplyQueueEntry::process(std::shared_ptr<DBusConnection> _connection) {
+ _connection->dispatchDBusMessageReply(message_, replyAsyncHandler_);
+}
+
+void DBusMessageWatch::MsgReplyQueueEntry::clear() {
+ delete replyAsyncHandler_;
+}
+
+void DBusMessageWatch::MsgQueueEntry::clear() {
+
+}
+
+DBusMessageWatch::DBusMessageWatch(std::shared_ptr<DBusConnection> _connection) : pipeValue_(4) {
+#ifdef WIN32
+ std::string pipeName = "\\\\.\\pipe\\CommonAPI-DBus-";
+
+ UUID uuid;
+ CHAR* uuidString = NULL;
+ UuidCreate(&uuid);
+ UuidToString(&uuid, (RPC_CSTR*)&uuidString);
+ pipeName += uuidString;
+ RpcStringFree((RPC_CSTR*)&uuidString);
+
+ HANDLE hPipe = ::CreateNamedPipe(
+ pipeName.c_str(),
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+ 1,
+ 4096,
+ 4096,
+ 100,
+ nullptr);
+
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ if (GetLastError() != ERROR_PIPE_BUSY)
+ {
+ printf("Could not open pipe %d\n", GetLastError());
+ }
+
+ // All pipe instances are busy, so wait for sometime.
+ else if (!WaitNamedPipe(pipeName.c_str(), NMPWAIT_USE_DEFAULT_WAIT))
+ {
+ printf("Could not open pipe: wait timed out.\n");
+ }
+ }
+
+ HANDLE hPipe2 = CreateFile(
+ pipeName.c_str(), // pipe name
+ GENERIC_READ | // read and write access
+ GENERIC_WRITE,
+ 0, // no sharing
+ NULL, // default security attributes
+ OPEN_EXISTING, // opens existing pipe
+ 0, // default attributes
+ NULL); // no template file
+
+ if (hPipe2 == INVALID_HANDLE_VALUE) {
+ if (GetLastError() != ERROR_PIPE_BUSY)
+ {
+ printf("Could not open pipe2 %d\n", GetLastError());
+ }
+
+ // All pipe instances are busy, so wait for sometime.
+ else if (!WaitNamedPipe(pipeName.c_str(), NMPWAIT_USE_DEFAULT_WAIT))
+ {
+ printf("Could not open pipe2: wait timed out.\n");
+ }
+ }
+
+ pipeFileDescriptors_[0] = (int)hPipe;
+ pipeFileDescriptors_[1] = (int)hPipe2;
+
+ wsaEvent_ = ::CreateEventW(nullptr, TRUE, FALSE, nullptr);
+
+ if (wsaEvent_ == WSA_INVALID_EVENT) {
+ printf("Invalid Event Created!\n");
+ }
+
+ ov = { 0 };
+ ov.hEvent = wsaEvent_;
+
+ BOOL retVal = ::ConnectNamedPipe(hPipe, &ov);
+
+ if (retVal == 0) {
+ int error = GetLastError();
+
+ if (error != 535) {
+ printf("ERROR: ConnectNamedPipe failed with (%d)\n", error);
+ }
+ }
+#else
+ if(pipe2(pipeFileDescriptors_, O_NONBLOCK) == -1) {
+ std::perror(__func__);
+ }
+#endif
+ pollFileDescriptor_.fd = pipeFileDescriptors_[0];
+ pollFileDescriptor_.events = POLLIN;
+
+ connection_ = _connection;
+}
+
+DBusMessageWatch::~DBusMessageWatch() {
+#ifdef WIN32
+ BOOL retVal = DisconnectNamedPipe((HANDLE)pipeFileDescriptors_[0]);
+
+ if (!retVal) {
+ printf(TEXT("DisconnectNamedPipe failed. GLE=%d\n"), GetLastError());
+ }
+
+ retVal = CloseHandle((HANDLE)pipeFileDescriptors_[0]);
+
+ if (!retVal) {
+ printf(TEXT("CloseHandle failed. GLE=%d\n"), GetLastError());
+ }
+
+ retVal = CloseHandle((HANDLE)pipeFileDescriptors_[1]);
+
+ if (!retVal) {
+ printf(TEXT("CloseHandle2 failed. GLE=%d\n"), GetLastError());
+ }
+#else
+ close(pipeFileDescriptors_[0]);
+ close(pipeFileDescriptors_[1]);
+#endif
+
+ std::unique_lock<std::mutex> itsLock(msgQueueMutex_);
+ while(!msgQueue_.empty()) {
+ auto queueEntry = msgQueue_.front();
+ msgQueue_.pop();
+ queueEntry->clear();
+ }
+}
+
+void DBusMessageWatch::dispatch(unsigned int) {
+}
+
+const pollfd& DBusMessageWatch::getAssociatedFileDescriptor() {
+ return pollFileDescriptor_;
+}
+
+#ifdef WIN32
+const HANDLE& DBusMessageWatch::getAssociatedEvent() {
+ return wsaEvent_;
+}
+#endif
+
+const std::vector<DispatchSource*>& DBusMessageWatch::getDependentDispatchSources() {
+ return dependentDispatchSources_;
+}
+
+void DBusMessageWatch::addDependentDispatchSource(CommonAPI::DispatchSource* _dispatchSource) {
+ dependentDispatchSources_.push_back(_dispatchSource);
+}
+
+void DBusMessageWatch::removeDependentDispatchSource(CommonAPI::DispatchSource* _dispatchSource) {
+ std::vector<CommonAPI::DispatchSource*>::iterator it;
+
+ for (it = dependentDispatchSources_.begin(); it != dependentDispatchSources_.end(); it++) {
+ if ( (*it) == _dispatchSource ) {
+ dependentDispatchSources_.erase(it);
+ break;
+ }
+ }
+}
+
+void DBusMessageWatch::pushMsgQueue(std::shared_ptr<MsgQueueEntry> _queueEntry) {
+ std::unique_lock<std::mutex> itsLock(msgQueueMutex_);
+ msgQueue_.push(_queueEntry);
+
+#ifdef WIN32
+ char writeValue[sizeof(pipeValue_)];
+ *reinterpret_cast<int*>(writeValue) = pipeValue_;
+ DWORD cbWritten;
+
+ int fSuccess = WriteFile(
+ (HANDLE)pipeFileDescriptors_[1], // pipe handle
+ writeValue, // message
+ sizeof(pipeValue_), // message length
+ &cbWritten, // bytes written
+ &ov); // overlapped
+
+ if (!fSuccess)
+ {
+ printf(TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError());
+ }
+#else
+ if(write(pipeFileDescriptors_[1], &pipeValue_, sizeof(pipeValue_)) == -1) {
+ std::perror(__func__);
+ }
+#endif
+}
+
+void DBusMessageWatch::popMsgQueue() {
+ std::unique_lock<std::mutex> itsLock(msgQueueMutex_);
+
+#ifdef WIN32
+ char readValue[sizeof(pipeValue_)];
+ DWORD cbRead;
+
+ int fSuccess = ReadFile(
+ (HANDLE)pipeFileDescriptors_[0], // pipe handle
+ readValue, // buffer to receive reply
+ sizeof(pipeValue_), // size of buffer
+ &cbRead, // number of bytes read
+ &ov); // overlapped
+
+ if (!fSuccess)
+ {
+ printf(TEXT("ReadFile to pipe failed. GLE=%d\n"), GetLastError());
+ }
+#else
+ int readValue = 0;
+ if(read(pipeFileDescriptors_[0], &readValue, sizeof(readValue)) == -1) {
+ std::perror(__func__);
+ }
+#endif
+
+ msgQueue_.pop();
+}
+
+std::shared_ptr<DBusMessageWatch::MsgQueueEntry> DBusMessageWatch::frontMsgQueue() {
+ std::unique_lock<std::mutex> itsLock(msgQueueMutex_);
+
+ return msgQueue_.front();
+}
+
+bool DBusMessageWatch::emptyMsgQueue() {
+ std::unique_lock<std::mutex> itsLock(msgQueueMutex_);
+
+ return msgQueue_.empty();
+}
+
+void DBusMessageWatch::processMsgQueueEntry(std::shared_ptr<DBusMessageWatch::MsgQueueEntry> _queueEntry) {
+ std::shared_ptr<DBusConnection> itsConnection = connection_.lock();
+ if(itsConnection) {
+ _queueEntry->process(itsConnection);
+ }
+}
DBusTimeout::DBusTimeout(::DBusTimeout* libdbusTimeout, std::weak_ptr<MainLoopContext>& mainLoopContext) :
dueTimeInMs_(TIMEOUT_INFINITE),
@@ -148,9 +430,12 @@ bool DBusTimeout::isReadyToBeMonitored() {
void DBusTimeout::startMonitoring() {
auto lockedContext = mainLoopContext_.lock();
- assert(lockedContext);
- recalculateDueTime();
- lockedContext->registerTimeoutSource(this);
+ if (NULL == lockedContext) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " lockedContext == NULL");
+ } else {
+ recalculateDueTime();
+ lockedContext->registerTimeoutSource(this);
+ }
}
void DBusTimeout::stopMonitoring() {
@@ -177,7 +462,7 @@ int64_t DBusTimeout::getReadyTime() const {
void DBusTimeout::recalculateDueTime() {
if(dbus_timeout_get_enabled(libdbusTimeout_)) {
- unsigned int intervalInMs = dbus_timeout_get_interval(libdbusTimeout_);
+ int intervalInMs = dbus_timeout_get_interval(libdbusTimeout_);
dueTimeInMs_ = getCurrentTimeInMs() + intervalInMs;
} else {
dueTimeInMs_ = TIMEOUT_INFINITE;
diff --git a/src/CommonAPI/DBus/DBusMessage.cpp b/src/CommonAPI/DBus/DBusMessage.cpp
index 5a6a549..09199dc 100644
--- a/src/CommonAPI/DBus/DBusMessage.cpp
+++ b/src/CommonAPI/DBus/DBusMessage.cpp
@@ -3,9 +3,9 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <cstring>
+#include <CommonAPI/Logger.hpp>
#include <CommonAPI/DBus/DBusAddress.hpp>
#include <CommonAPI/DBus/DBusMessage.hpp>
@@ -21,8 +21,10 @@ DBusMessage::DBusMessage(::DBusMessage *_message) {
}
DBusMessage::DBusMessage(::DBusMessage *_message, bool reference) {
- assert(_message);
- message_ = (reference ? dbus_message_ref(message_) : _message);
+ if (NULL == _message) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " NULL _message");
+ }
+ message_ = (_message != nullptr ? (reference ? dbus_message_ref(message_) : _message) : nullptr);
}
DBusMessage::DBusMessage(const DBusMessage &_source) {
@@ -88,7 +90,9 @@ DBusMessage::createMethodCall(
::DBusMessage *methodCall = dbus_message_new_method_call(
service.c_str(), path.c_str(),
interface.c_str(), _method.c_str());
- assert(methodCall);
+ if (NULL == methodCall) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_message_new_method_call() returned NULL");
+ }
if ("" != _signature)
dbus_message_set_signature(methodCall, _signature.c_str());
@@ -99,7 +103,9 @@ DBusMessage::createMethodCall(
DBusMessage
DBusMessage::createMethodReturn(const std::string &_signature) const {
::DBusMessage *methodReturn = dbus_message_new_method_return(message_);
- assert(methodReturn);
+ if (NULL == methodReturn) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_message_new_method_return() returned NULL");
+ }
if ("" != _signature)
dbus_message_set_signature(methodReturn, _signature.c_str());
@@ -113,7 +119,9 @@ DBusMessage::createMethodError(
::DBusMessage *methodError
= dbus_message_new_error(message_, _code.c_str(), _info.c_str());
- assert(methodError);
+ if (NULL == methodError) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_message_new_error() returned NULL");
+ }
return DBusMessage(methodError, false);
}
@@ -125,7 +133,9 @@ DBusMessage::createSignal(
::DBusMessage *messageSignal
= dbus_message_new_signal(_path.c_str(), _interface.c_str(), _signal.c_str());
- assert(messageSignal);
+ if (NULL == messageSignal) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_message_new_signal() returned NULL");
+ }
if ("" != _signature)
dbus_message_set_signature(messageSignal, _signature.c_str());
@@ -160,7 +170,9 @@ DBusMessage::getSignature() const {
const char *
DBusMessage::getError() const {
- assert(isErrorType());
+ if (!isErrorType()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " !isErrorType");
+ }
return dbus_message_get_error_name(message_);
}
@@ -176,38 +188,53 @@ uint32_t DBusMessage::getSerial() const {
bool
DBusMessage::hasObjectPath(const char *_path) const {
const char *path = getObjectPath();
+ if (NULL == _path) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " _path == NULL");
+ }
+ if (NULL == path) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " path == NULL");
+ }
- assert(_path);
- assert(path);
-
- return (!strcmp(path, _path));
+ return (((NULL != path) && (NULL != _path))? !strcmp(path, _path) : false);
}
bool DBusMessage::hasInterfaceName(const char *_interface) const {
const char *interface = getInterface();
- assert(_interface);
- assert(interface);
+ if (NULL == _interface) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " _interface == NULL");
+ }
+ if (NULL == interface) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " interface == NULL");
+ }
- return (!strcmp(interface, _interface));
+ return (((NULL != interface) && (NULL != _interface))? !strcmp(interface, _interface) : false);
}
bool DBusMessage::hasMemberName(const char *_member) const {
const char *member = getMember();
- assert(_member);
- assert(member);
+ if (NULL == _member) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " _member == NULL");
+ }
+ if (NULL == member) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " member == NULL");
+ }
- return (!strcmp(member, _member));
+ return (((NULL != member) && (NULL != _member))? !strcmp(member, _member) : false);
}
bool DBusMessage::hasSignature(const char *_signature) const {
const char *signature = getSignature();
- assert(_signature);
- assert(signature);
+ if (NULL == _signature) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " _signature == NULL");
+ }
+ if (NULL == signature) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " signature == NULL");
+ }
- return (!strcmp(signature, _signature));
+ return (((NULL != signature) && (NULL != _signature))? !strcmp(signature, _signature) : false);
}
DBusMessage::Type DBusMessage::getType() const {
@@ -235,6 +262,10 @@ bool DBusMessage::setDestination(const char *_destination)
return 0 != dbus_message_set_destination(message_, _destination);
}
+void DBusMessage::setSerial(const unsigned int _serial) const {
+ dbus_message_set_serial(message_, _serial);
+}
+
bool DBusMessage::hasObjectPath(const std::string &_path) const {
return hasObjectPath(_path.c_str());
}
diff --git a/src/CommonAPI/DBus/DBusObjectManager.cpp b/src/CommonAPI/DBus/DBusObjectManager.cpp
index 3d10c6d..c9484fd 100644
--- a/src/CommonAPI/DBus/DBusObjectManager.cpp
+++ b/src/CommonAPI/DBus/DBusObjectManager.cpp
@@ -3,9 +3,9 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <sstream>
#include <unordered_set>
+#include <algorithm>
#include <dbus/dbus-protocol.h>
@@ -24,16 +24,15 @@ namespace DBus {
DBusObjectManager::DBusObjectManager(const std::shared_ptr<DBusProxyConnection>& dbusConnection):
rootDBusObjectManagerStub_(new DBusObjectManagerStub("/", dbusConnection)),
dbusConnection_(dbusConnection){
-
if (!dbusConnection->isObjectPathMessageHandlerSet()) {
dbusConnection->setObjectPathMessageHandler(
std::bind(&DBusObjectManager::handleMessage, this, std::placeholders::_1));
}
dbusConnection->registerObjectPath("/");
- dbusRegisteredObjectsTable_.insert({
+ addToRegisteredObjectsTable(
DBusInterfaceHandlerPath("/", DBusObjectManagerStub::getInterfaceName()),
- rootDBusObjectManagerStub_ });
+ rootDBusObjectManagerStub_ );
}
DBusObjectManager::~DBusObjectManager() {
@@ -76,7 +75,9 @@ bool DBusObjectManager::registerDBusStubAdapter(std::shared_ptr<DBusStubAdapter>
dbusStubAdapter->getDBusConnection()
);
auto insertResult = managerStubs_.insert( {dbusStubAdapterObjectPath, {newManagerStub, 1} });
- assert(insertResult.second);
+ if (!insertResult.second) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " insertResult.second == nullptr");
+ }
managerStubIterator = insertResult.first;
} else {
uint32_t& countReferencesToManagerStub = std::get<1>(managerStubIterator->second);
@@ -84,15 +85,21 @@ bool DBusObjectManager::registerDBusStubAdapter(std::shared_ptr<DBusStubAdapter>
}
std::shared_ptr<DBusObjectManagerStub> dbusObjectManagerStub = std::get<0>(managerStubIterator->second);
- assert(dbusObjectManagerStub);
- isRegistrationSuccessful = addDBusInterfaceHandler(
- { dbusStubAdapterObjectPath, dbusObjectManagerStub->getInterfaceName() }, dbusObjectManagerStub);
+ if (!dbusObjectManagerStub) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusObjectManagerStub == nullptr");
+ isRegistrationSuccessful = false;
+ } else {
+ isRegistrationSuccessful = addDBusInterfaceHandler(
+ { dbusStubAdapterObjectPath, dbusObjectManagerStub->getInterfaceName() }, dbusObjectManagerStub);
+ }
if (!isRegistrationSuccessful) {
const bool isDBusStubAdapterRemoved = removeDBusInterfaceHandler(dbusStubAdapterHandlerPath, dbusStubAdapter);
- assert(isDBusStubAdapterRemoved);
- (void)isDBusStubAdapterRemoved;
+ if (!isDBusStubAdapterRemoved) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " removeDBusInterfaceHandler failed path: ",
+ dbusStubAdapterObjectPath, " interface: ", dbusStubAdapterInterfaceName);
+ }
}
}
@@ -119,20 +126,32 @@ bool DBusObjectManager::unregisterDBusStubAdapter(std::shared_ptr<DBusStubAdapte
if (isDeregistrationSuccessful && dbusStubAdapter->isManaging()) {
auto managerStubIterator = managerStubs_.find(dbusStubAdapterObjectPath);
- assert(managerStubIterator != managerStubs_.end());
-
- std::shared_ptr<DBusObjectManagerStub> dbusObjectManagerStub = std::get<0>(managerStubIterator->second);
- assert(dbusObjectManagerStub);
-
- uint32_t& countReferencesToManagerStub = std::get<1>(managerStubIterator->second);
- assert(countReferencesToManagerStub > 0);
- --countReferencesToManagerStub;
+ if (managerStubs_.end() == managerStubIterator) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unknown DBusStubAdapter ", dbusStubAdapterObjectPath);
+ isDeregistrationSuccessful = false;
+ } else {
+ std::shared_ptr<DBusObjectManagerStub> dbusObjectManagerStub = std::get<0>(managerStubIterator->second);
+ if (!dbusObjectManagerStub) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusObjectManagerStub == nullptr ", dbusStubAdapterObjectPath);
+ isDeregistrationSuccessful = false;
+ } else {
+ uint32_t& countReferencesToManagerStub = std::get<1>(managerStubIterator->second);
+ if (0 == countReferencesToManagerStub) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " reference count == 0");
+ isDeregistrationSuccessful = false;
+ } else {
+ --countReferencesToManagerStub;
+ }
- if (countReferencesToManagerStub == 0) {
- isDeregistrationSuccessful = removeDBusInterfaceHandler(
- { dbusStubAdapterObjectPath, dbusObjectManagerStub->getInterfaceName() }, dbusObjectManagerStub);
- managerStubs_.erase(managerStubIterator);
- assert(isDeregistrationSuccessful);
+ if (countReferencesToManagerStub == 0) {
+ isDeregistrationSuccessful = removeDBusInterfaceHandler(
+ { dbusStubAdapterObjectPath, dbusObjectManagerStub->getInterfaceName() }, dbusObjectManagerStub);
+ managerStubs_.erase(managerStubIterator);
+ if (!isDeregistrationSuccessful) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unregister failed ", dbusStubAdapterObjectPath, " interface: ", dbusObjectManagerStub->getInterfaceName());
+ }
+ }
+ }
}
}
@@ -152,9 +171,9 @@ bool DBusObjectManager::unregisterDBusStubAdapter(std::shared_ptr<DBusStubAdapte
bool DBusObjectManager::exportManagedDBusStubAdapter(const std::string& parentObjectPath, std::shared_ptr<DBusStubAdapter> dbusStubAdapter) {
auto foundManagerStubIterator = managerStubs_.find(parentObjectPath);
- assert(foundManagerStubIterator != managerStubs_.end());
-
- if (std::get<0>(foundManagerStubIterator->second)->exportManagedDBusStubAdapter(dbusStubAdapter)) {
+ if (managerStubs_.end() == foundManagerStubIterator) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no manager stub found for ", parentObjectPath);
+ } else if (std::get<0>(foundManagerStubIterator->second)->exportManagedDBusStubAdapter(dbusStubAdapter)) {
// TODO Check if other handling is necessary?
return true;
}
@@ -180,8 +199,12 @@ bool DBusObjectManager::handleMessage(const DBusMessage& dbusMessage) {
const char* objectPath = dbusMessage.getObjectPath();
const char* interfaceName = dbusMessage.getInterface();
- assert(objectPath);
- assert(interfaceName);
+ if (NULL == objectPath) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " objectPath == NULL");
+ }
+ if (NULL == interfaceName) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " interfaceName == NULL");
+ }
DBusInterfaceHandlerPath handlerPath(objectPath, interfaceName);
@@ -191,8 +214,10 @@ bool DBusObjectManager::handleMessage(const DBusMessage& dbusMessage) {
bool dbusMessageHandled = false;
if (foundDBusInterfaceHandler) {
- std::shared_ptr<DBusInterfaceHandler> dbusStubAdapterBase = handlerIterator->second;
+ std::shared_ptr<DBusInterfaceHandler> dbusStubAdapterBase = handlerIterator->second.front();
+ objectPathLock_.unlock();
dbusMessageHandled = dbusStubAdapterBase->onInterfaceDBusMessage(dbusMessage);
+ return dbusMessageHandled;
} else if (dbusMessage.hasInterfaceName("org.freedesktop.DBus.Introspectable")) {
dbusMessageHandled = onIntrospectableInterfaceDBusMessage(dbusMessage);
}
@@ -207,18 +232,20 @@ bool DBusObjectManager::addDBusInterfaceHandler(const DBusInterfaceHandlerPath&
const bool isDBusInterfaceHandlerAlreadyAdded = (dbusRegisteredObjectsTableIter != dbusRegisteredObjectsTable_.end());
if (isDBusInterfaceHandlerAlreadyAdded) {
- //If another ObjectManager or a freedesktop properties stub is to be registered,
- //you can go on and just use the first one.
- if (dbusInterfaceHandlerPath.second == "org.freedesktop.DBus.ObjectManager" ||
- dbusInterfaceHandlerPath.second == "org.freedesktop.DBus.Properties") {
- return true;
+
+ auto handler = find(dbusRegisteredObjectsTableIter->second.begin(), dbusRegisteredObjectsTableIter->second.end(), dbusInterfaceHandler);
+ if (handler != dbusRegisteredObjectsTableIter->second.end()) {
+ //If another ObjectManager or a freedesktop properties stub is to be registered,
+ //you can go on and just use the first one.
+ if (dbusInterfaceHandlerPath.second == "org.freedesktop.DBus.ObjectManager" ||
+ dbusInterfaceHandlerPath.second == "org.freedesktop.DBus.Properties") {
+ return true;
+ }
+ return false;
}
- return false;
}
- auto insertResult = dbusRegisteredObjectsTable_.insert({ dbusInterfaceHandlerPath, dbusInterfaceHandler });
- const bool insertSuccess = insertResult.second;
-
+ auto insertSuccess = addToRegisteredObjectsTable(dbusInterfaceHandlerPath, dbusInterfaceHandler);
return insertSuccess;
}
@@ -228,10 +255,15 @@ bool DBusObjectManager::removeDBusInterfaceHandler(const DBusInterfaceHandlerPat
const bool isDBusInterfaceHandlerAdded = (dbusRegisteredObjectsTableIter != dbusRegisteredObjectsTable_.end());
if (isDBusInterfaceHandlerAdded) {
- auto registeredDBusStubAdapter = dbusRegisteredObjectsTableIter->second;
- assert(registeredDBusStubAdapter == dbusInterfaceHandler);
- (void)dbusInterfaceHandler;
- dbusRegisteredObjectsTable_.erase(dbusRegisteredObjectsTableIter);
+ auto registeredDBusStubAdapter = find(dbusRegisteredObjectsTableIter->second.begin(), dbusRegisteredObjectsTableIter->second.end(), dbusInterfaceHandler);
+ if (dbusRegisteredObjectsTableIter->second.end() == registeredDBusStubAdapter) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no stub adapter registered for ", dbusInterfaceHandlerPath.first, " ", dbusInterfaceHandlerPath.second);
+ } else {
+ dbusRegisteredObjectsTableIter->second.erase(registeredDBusStubAdapter);
+ if (dbusRegisteredObjectsTableIter->second.empty()) {
+ dbusRegisteredObjectsTable_.erase(dbusRegisteredObjectsTableIter);
+ }
+ }
}
return isDBusInterfaceHandlerAdded;
@@ -261,7 +293,7 @@ bool DBusObjectManager::onIntrospectableInterfaceDBusMessage(const DBusMessage&
const DBusInterfaceHandlerPath& handlerPath = registeredObjectsIterator.first;
const std::string& dbusObjectPath = handlerPath.first;
const std::string& dbusInterfaceName = handlerPath.second;
- std::shared_ptr<DBusInterfaceHandler> dbusStubAdapterBase = registeredObjectsIterator.second;
+ std::shared_ptr<DBusInterfaceHandler> dbusStubAdapterBase = registeredObjectsIterator.second.front();
std::vector<std::string> elems = CommonAPI::split(dbusObjectPath, '/');
if (dbusMessage.hasObjectPath(dbusObjectPath)) {
@@ -329,5 +361,30 @@ std::shared_ptr<DBusObjectManagerStub> DBusObjectManager::getRootDBusObjectManag
return rootDBusObjectManagerStub_;
}
+bool DBusObjectManager::addToRegisteredObjectsTable(DBusInterfaceHandlerPath ifpath, std::shared_ptr<DBusInterfaceHandler> handler) {
+ auto handlerRecord = dbusRegisteredObjectsTable_.find(ifpath);
+ if (handlerRecord == dbusRegisteredObjectsTable_.end()) {
+ // not found, create and add entry
+ dbusRegisteredObjectsTable_.insert({
+ ifpath,
+ std::vector<std::shared_ptr<DBusInterfaceHandler>>({handler})
+ });
+ }
+ else {
+ // found. search through vector to find the handler
+ std::vector<std::shared_ptr<DBusInterfaceHandler>> handlerList = handlerRecord->second;
+ auto adapter = find(handlerList.begin(), handlerList.end(), handler);
+ if (adapter != handlerList.end()) {
+ // found; don't add
+ return false;
+ }
+ else {
+ handlerList.push_back(handler);
+ handlerRecord->second = handlerList;
+ }
+ }
+ return true;
+}
+
} // namespace DBus
} // namespace CommonAPI
diff --git a/src/CommonAPI/DBus/DBusObjectManagerStub.cpp b/src/CommonAPI/DBus/DBusObjectManagerStub.cpp
index 7516994..20bbf1d 100644
--- a/src/CommonAPI/DBus/DBusObjectManagerStub.cpp
+++ b/src/CommonAPI/DBus/DBusObjectManagerStub.cpp
@@ -3,9 +3,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <vector>
-
+#include <algorithm>
#include <CommonAPI/DBus/DBusObjectManagerStub.hpp>
#include <CommonAPI/DBus/DBusOutputStream.hpp>
#include <CommonAPI/DBus/DBusStubAdapter.hpp>
@@ -18,9 +17,15 @@ DBusObjectManagerStub::DBusObjectManagerStub(const std::string& dbusObjectPath,
const std::shared_ptr<DBusProxyConnection>& dbusConnection) :
dbusObjectPath_(dbusObjectPath),
dbusConnection_(dbusConnection) {
- assert(!dbusObjectPath.empty());
- assert(dbusObjectPath[0] == '/');
- assert(dbusConnection);
+ if (dbusObjectPath.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty _path");
+ }
+ if ('/' != dbusObjectPath[0]) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid _path ", dbusObjectPath);
+ }
+ if (!dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid _connection");
+ }
}
DBusObjectManagerStub::~DBusObjectManagerStub() {
@@ -29,21 +34,33 @@ DBusObjectManagerStub::~DBusObjectManagerStub() {
for (auto& dbusInterfaceIterator : registeredDBusInterfacesMap) {
auto managedDBusStubAdapter = dbusInterfaceIterator.second;
- auto managedDBusStubAdapterServiceAddress = managedDBusStubAdapter->getDBusAddress();
#ifdef COMMONAPI_TODO
- const bool isServiceUnregistered = DBusServicePublisher::getInstance()->unregisterManagedService(
- managedDBusStubAdapterServiceAddress);
- assert(isServiceUnregistered);
+ for (auto& adapterIterator : dbusInterfaceIterator.second) {
+ auto managedDBusStubAdapterServiceAddress = adapterIterator->getDBusAddress();
+
+ const bool isServiceUnregistered = DBusServicePublisher::getInstance()->unregisterManagedService(
+ managedDBusStubAdapterServiceAddress);
+ if (!isServiceUnregistered) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " service still registered ", managedDBusStubAdapterServiceAddress.getService());
+ }
#endif
}
}
}
bool DBusObjectManagerStub::exportManagedDBusStubAdapter(std::shared_ptr<DBusStubAdapter> managedDBusStubAdapter) {
- assert(managedDBusStubAdapter);
+ if (!managedDBusStubAdapter) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "managedDBusStubAdapter == nullptr");
+ return false;
+ }
- std::lock_guard<std::mutex> dbusObjectManagerStubLock(dbusObjectManagerStubLock_);
+ // if already registered, return true.
+ const bool alreadyExported = isDBusStubAdapterExported(managedDBusStubAdapter);
+ if (alreadyExported) {
+ return true;
+ }
+ std::lock_guard<std::mutex> dbusObjectManagerStubLock(dbusObjectManagerStubLock_);
const bool isRegistrationSuccessful = registerDBusStubAdapter(managedDBusStubAdapter);
if (!isRegistrationSuccessful) {
return false;
@@ -63,7 +80,10 @@ bool DBusObjectManagerStub::exportManagedDBusStubAdapter(std::shared_ptr<DBusStu
}
bool DBusObjectManagerStub::unexportManagedDBusStubAdapter(std::shared_ptr<DBusStubAdapter> managedDBusStubAdapter) {
- assert(managedDBusStubAdapter);
+ if (!managedDBusStubAdapter) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "managedDBusStubAdapter == nullptr");
+ return false;
+ }
std::lock_guard<std::mutex> dbusObjectManagerStubLock(dbusObjectManagerStubLock_);
@@ -86,7 +106,10 @@ bool DBusObjectManagerStub::unexportManagedDBusStubAdapter(std::shared_ptr<DBusS
}
bool DBusObjectManagerStub::isDBusStubAdapterExported(std::shared_ptr<DBusStubAdapter> dbusStubAdapter) {
- assert(dbusStubAdapter);
+ if (!dbusStubAdapter) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "dbusStubAdapter == nullptr");
+ return false;
+ }
const auto& dbusObjectPath = dbusStubAdapter->getDBusAddress().getObjectPath();
const auto& dbusInterfaceName = dbusStubAdapter->getDBusAddress().getInterface();
@@ -103,13 +126,15 @@ bool DBusObjectManagerStub::isDBusStubAdapterExported(std::shared_ptr<DBusStubAd
auto& registeredDBusInterfacesMap = registeredDBusObjectPathIterator->second;
const auto& registeredDBusInterfaceIterator = registeredDBusInterfacesMap.find(dbusInterfaceName);
const bool isRegisteredDBusInterfaceName = (registeredDBusInterfaceIterator != registeredDBusInterfacesMap.end());
-
- if (isRegisteredDBusInterfaceName) {
- auto registeredDBusStubAdapter = registeredDBusInterfaceIterator->second;
- assert(registeredDBusStubAdapter == dbusStubAdapter);
+ if (!isRegisteredDBusInterfaceName) {
+ return false;
}
- return isRegisteredDBusInterfaceName;
+ const auto& registeredDBusStubAdapterList = registeredDBusInterfaceIterator->second;
+ auto registeredDBusStubAdapter = find(registeredDBusStubAdapterList.begin(), registeredDBusStubAdapterList.end(), dbusStubAdapter);
+
+ return registeredDBusStubAdapter != registeredDBusStubAdapterList.end();
+
}
bool DBusObjectManagerStub::registerDBusStubAdapter(std::shared_ptr<DBusStubAdapter> dbusStubAdapter) {
@@ -125,12 +150,27 @@ bool DBusObjectManagerStub::registerDBusStubAdapter(std::shared_ptr<DBusStubAdap
const bool isDBusInterfaceAlreadyRegistered = (registeredDBusInterfaceIterator != registeredDBusInterfacesMap.end());
if (!isDBusInterfaceAlreadyRegistered) {
- const auto& insertResult = registeredDBusInterfacesMap.insert({ dbusInterfaceName, dbusStubAdapter });
+ const auto& insertResult = registeredDBusInterfacesMap.insert(
+ { dbusInterfaceName,
+ std::vector<std::shared_ptr<DBusStubAdapter>>({dbusStubAdapter})});
isRegisterationSuccessful = insertResult.second;
}
+ else {
+ // add to existing interface
+ auto adapterList = registeredDBusInterfaceIterator->second;
+ if (find(adapterList.begin(), adapterList.end(), dbusStubAdapter) == adapterList.end()) {
+ adapterList.push_back(dbusStubAdapter);
+ registeredDBusInterfaceIterator->second = adapterList;
+ isRegisterationSuccessful = true;
+ }
+ else {
+ // already registered
+ isRegisterationSuccessful = false;
+ }
+ }
} else {
const auto& insertResult = registeredDBusObjectPathsMap_.insert({
- dbusObjectPath, DBusInterfacesMap({{ dbusInterfaceName, dbusStubAdapter }})
+ dbusObjectPath, DBusInterfacesMap({{ dbusInterfaceName, std::vector<std::shared_ptr<DBusStubAdapter>>({dbusStubAdapter}) }})
});
isRegisterationSuccessful = insertResult.second;
}
@@ -156,23 +196,37 @@ bool DBusObjectManagerStub::unregisterDBusStubAdapter(std::shared_ptr<DBusStubAd
return false;
}
- auto registeredDBusStubAdapter = registeredDBusInterfaceIterator->second;
- assert(registeredDBusStubAdapter == dbusStubAdapter);
-
- registeredDBusInterfacesMap.erase(registeredDBusInterfaceIterator);
+ auto& registeredAdapterList = registeredDBusInterfaceIterator->second;
+ auto adapter = find (registeredAdapterList.begin(), registeredAdapterList.end(), dbusStubAdapter);
- if (registeredDBusInterfacesMap.empty()) {
- registeredDBusObjectPathsMap_.erase(registeredDBusObjectPathIterator);
+ if (registeredAdapterList.end() == adapter) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " stub adapter not registered ", dbusObjectPath, " interface: ", dbusInterfaceName);
+ return false;
}
+ registeredAdapterList.erase(adapter);
+
+ if (registeredAdapterList.empty()) {
+ registeredDBusInterfacesMap.erase(registeredDBusInterfaceIterator);
+
+ if (registeredDBusInterfacesMap.empty()) {
+ registeredDBusObjectPathsMap_.erase(registeredDBusObjectPathIterator);
+ }
+ }
return true;
}
bool DBusObjectManagerStub::emitInterfacesAddedSignal(std::shared_ptr<DBusStubAdapter> dbusStubAdapter,
const std::shared_ptr<DBusProxyConnection>& dbusConnection) const {
- assert(dbusConnection);
- assert(dbusConnection->isConnected());
+ if (!dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusConnection == nullptr");
+ return false;
+ }
+ if (!dbusConnection->isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " not connected");
+ return false;
+ }
const auto& dbusStubObjectPath = dbusStubAdapter->getDBusAddress().getObjectPath();
const auto& dbusStubInterfaceName = dbusStubAdapter->getDBusAddress().getInterface();
@@ -200,8 +254,14 @@ bool DBusObjectManagerStub::emitInterfacesAddedSignal(std::shared_ptr<DBusStubAd
bool DBusObjectManagerStub::emitInterfacesRemovedSignal(std::shared_ptr<DBusStubAdapter> dbusStubAdapter,
const std::shared_ptr<DBusProxyConnection>& dbusConnection) const {
- assert(dbusConnection);
- assert(dbusConnection->isConnected());
+ if (!dbusConnection) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusConnection == nullptr");
+ return false;
+ }
+ if (!dbusConnection->isConnected()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " not connected");
+ return false;
+ }
const auto& dbusStubObjectPath = dbusStubAdapter->getDBusAddress().getObjectPath();
const auto& dbusStubInterfaceName = dbusStubAdapter->getDBusAddress().getInterface();
@@ -254,23 +314,30 @@ bool DBusObjectManagerStub::onInterfaceDBusMessage(const DBusMessage& dbusMessag
const auto& registeredDBusInterfacesMap = registeredDBusObjectPathIterator.second;
DBusInterfacesAndPropertiesDict dbusInterfacesAndPropertiesDict;
- assert(registeredDBusObjectPath.length() > 0);
- assert(registeredDBusInterfacesMap.size() > 0);
-
- for (const auto& registeredDBusInterfaceIterator : registeredDBusInterfacesMap) {
- const std::string& registeredDBusInterfaceName = registeredDBusInterfaceIterator.first;
- const auto& registeredDBusStubAdapter = registeredDBusInterfaceIterator.second;
+ if (0 == registeredDBusObjectPath.length()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty object path");
+ } else {
+ if (0 == registeredDBusInterfacesMap.size()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty interfaces map for ", registeredDBusObjectPath);
+ }
- assert(registeredDBusInterfaceName.length() > 0);
+ for (const auto& registeredDBusInterfaceIterator : registeredDBusInterfacesMap) {
+ const std::string& registeredDBusInterfaceName = registeredDBusInterfaceIterator.first;
+ const auto& registeredDBusStubAdapter = registeredDBusInterfaceIterator.second.begin();
- dbusInterfacesAndPropertiesDict.insert({ registeredDBusInterfaceName, DBusPropertiesChangedDict() });
+ if (0 == registeredDBusInterfaceName.length()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty interface name for ", registeredDBusObjectPath);
+ } else {
+ dbusInterfacesAndPropertiesDict.insert({ registeredDBusInterfaceName, DBusPropertiesChangedDict() });
+ }
- if (registeredDBusStubAdapter->isManaging()) {
- dbusInterfacesAndPropertiesDict.insert({ getInterfaceName(), DBusPropertiesChangedDict() });
+ if ((*registeredDBusStubAdapter)->isManaging()) {
+ dbusInterfacesAndPropertiesDict.insert({ getInterfaceName(), DBusPropertiesChangedDict() });
+ }
}
- }
- dbusObjectPathAndInterfacesDict.insert({ registeredDBusObjectPath, std::move(dbusInterfacesAndPropertiesDict) });
+ dbusObjectPathAndInterfacesDict.insert({ registeredDBusObjectPath, std::move(dbusInterfacesAndPropertiesDict) });
+ }
}
DBusMessage dbusMessageReply = dbusMessage.createMethodReturn("a{oa{sa{sv}}}");
diff --git a/src/CommonAPI/DBus/DBusOutputStream.cpp b/src/CommonAPI/DBus/DBusOutputStream.cpp
index 728c017..6fd5d0a 100644
--- a/src/CommonAPI/DBus/DBusOutputStream.cpp
+++ b/src/CommonAPI/DBus/DBusOutputStream.cpp
@@ -63,17 +63,32 @@ void DBusOutputStream::setError() {
* @param numOfBytes The number of bytes that should be reserved for writing.
*/
void DBusOutputStream::reserveMemory(size_t numOfBytes) {
- assert(numOfBytes > 0);
+ if (0 == numOfBytes) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " reserving 0 bytes");
+ }
payload_.reserve(numOfBytes);
}
DBusOutputStream& DBusOutputStream::writeString(const char *_value, const uint32_t &_length) {
- assert(_value != NULL);
- assert(_value[_length] == '\0');
-
- _writeValue(_length);
- _writeRaw(_value, _length + 1);
+ if (NULL == _value) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " _value == NULL");
+ } else if (_value[_length] != '\0') {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " _value is not zero-terminated")
+ } else {
+ _writeValue(_length);
+ _writeRaw(_value, _length + 1);
+ }
+ return (*this);
+}
+DBusOutputStream& DBusOutputStream::writeByteBuffer(const uint8_t *_value,
+ const uint32_t &_length) {
+ if (NULL == _value) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " _value == NULL");
+ } else {
+ _writeValue(_length);
+ _writeRaw(reinterpret_cast<const char*>(_value), _length);
+ }
return (*this);
}
@@ -81,8 +96,9 @@ DBusOutputStream& DBusOutputStream::writeString(const char *_value, const uint32
static const char eightByteZeroString[] = "\0\0\0\0\0\0\0";
void DBusOutputStream::align(const size_t _boundary) {
- assert(_boundary > 0 && _boundary <= 8 &&
- (_boundary % 2 == 0 || _boundary == 1));
+ if ( _boundary == 0 || _boundary > 8 || ( 0 != _boundary % 2 && 1 != _boundary) ) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid boundary ", _boundary);
+ }
size_t mask = _boundary - 1;
size_t necessary = ((mask - (payload_.size() & mask)) + 1) & mask;
@@ -100,7 +116,9 @@ void DBusOutputStream::_writeRawAt(const char *_data, const size_t _size, size_t
void DBusOutputStream::writeSignature(const std::string& signature) {
const auto& signatureLength = signature.length();
- assert(signatureLength > 0 && signatureLength < 256);
+ if (0 == signatureLength || 255 < signatureLength) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " invalid signatureLength ", signatureLength);
+ }
const uint8_t wireLength = (uint8_t) signatureLength;
(*this) << wireLength;
diff --git a/src/CommonAPI/DBus/DBusProxy.cpp b/src/CommonAPI/DBus/DBusProxy.cpp
index e92d90c..95c3d59 100644
--- a/src/CommonAPI/DBus/DBusProxy.cpp
+++ b/src/CommonAPI/DBus/DBusProxy.cpp
@@ -3,7 +3,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <cassert>
#include <sstream>
#include <CommonAPI/Utils.hpp>
@@ -25,15 +24,153 @@ void DBusProxyStatusEvent::onListenerAdded(const Listener &_listener, const Subs
_listener(AvailabilityStatus::AVAILABLE);
}
+void DBusProxy::availabilityTimeoutThreadHandler() const {
+ std::unique_lock<std::mutex> threadLock(availabilityTimeoutThreadMutex_);
+
+ bool cancel = false;
+ bool firstIteration = true;
+
+ // the callbacks that have to be done are stored with
+ // their required data in a list of tuples.
+ typedef std::tuple<
+ isAvailableAsyncCallback,
+ std::promise<AvailabilityStatus>,
+ AvailabilityStatus,
+ std::chrono::time_point<std::chrono::high_resolution_clock>
+ > CallbackData_t;
+ std::list<CallbackData_t> callbacks;
+
+ while(!cancel) {
+
+ //get min timeout
+ timeoutsMutex_.lock();
+
+ int timeout = std::numeric_limits<int>::max();
+ std::chrono::time_point<std::chrono::high_resolution_clock> minTimeout;
+ if (timeouts_.size() > 0) {
+ auto minTimeoutElement = std::min_element(timeouts_.begin(), timeouts_.end(),
+ [] (const AvailabilityTimeout_t& lhs, const AvailabilityTimeout_t& rhs) {
+ return std::get<0>(lhs) < std::get<0>(rhs);
+ });
+ minTimeout = std::get<0>(*minTimeoutElement);
+ std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();
+ timeout = (int)std::chrono::duration_cast<std::chrono::milliseconds>(minTimeout - now).count();
+ }
+ timeoutsMutex_.unlock();
+
+ //wait for timeout or notification
+ if (!firstIteration && std::cv_status::timeout ==
+ availabilityTimeoutCondition_.wait_for(threadLock, std::chrono::milliseconds(timeout))) {
+ timeoutsMutex_.lock();
+
+ //iterate through timeouts
+ auto it = timeouts_.begin();
+ while (it != timeouts_.end()) {
+ std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();
+
+ isAvailableAsyncCallback callback = std::get<1>(*it);
+
+ if (now > std::get<0>(*it)) {
+ //timeout
+ availabilityMutex_.lock();
+ if(isAvailable())
+ callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)),
+ AvailabilityStatus::AVAILABLE,
+ std::chrono::time_point<std::chrono::high_resolution_clock>()));
+ else
+ callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)),
+ AvailabilityStatus::NOT_AVAILABLE,
+ std::chrono::time_point<std::chrono::high_resolution_clock>()));
+ it = timeouts_.erase(it);
+ availabilityMutex_.unlock();
+ } else {
+ //timeout not expired
+ availabilityMutex_.lock();
+ if(isAvailable()) {
+ callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)),
+ AvailabilityStatus::AVAILABLE,
+ minTimeout));
+ it = timeouts_.erase(it);
+ } else {
+ ++it;
+ }
+ availabilityMutex_.unlock();
+ }
+ }
+
+ timeoutsMutex_.unlock();
+ } else {
+
+ if(firstIteration) {
+ firstIteration = false;
+ continue;
+ }
+
+ //timeout not expired
+ timeoutsMutex_.lock();
+ auto it = timeouts_.begin();
+ while (it != timeouts_.end()) {
+ isAvailableAsyncCallback callback = std::get<1>(*it);
+
+ availabilityMutex_.lock();
+ if(isAvailable()) {
+ callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)),
+ AvailabilityStatus::AVAILABLE,
+ minTimeout));
+ it = timeouts_.erase(it);
+ } else {
+ ++it;
+ }
+ availabilityMutex_.unlock();
+ }
+
+ timeoutsMutex_.unlock();
+ }
+
+ //do callbacks
+ isAvailableAsyncCallback callback;
+ AvailabilityStatus avStatus;
+ int remainingTimeout;
+ std::chrono::high_resolution_clock::time_point now;
+
+ auto it = callbacks.begin();
+ while(it != callbacks.end()) {
+ callback = std::get<0>(*it);
+ avStatus = std::get<2>(*it);
+
+ // compute remaining timeout
+ now = std::chrono::high_resolution_clock::now();
+ remainingTimeout = (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::get<3>(*it) - now).count();
+ if(remainingTimeout < 0)
+ remainingTimeout = 0;
+
+ threadLock.unlock();
+
+ std::get<1>(*it).set_value(avStatus);
+ callback(avStatus, remainingTimeout);
+
+ threadLock.lock();
+
+ it = callbacks.erase(it);
+ }
+
+ //cancel thread
+ timeoutsMutex_.lock();
+ if(timeouts_.size() == 0 && callbacks.size() == 0)
+ cancel = true;
+ timeoutsMutex_.unlock();
+ }
+}
+
DBusProxy::DBusProxy(const DBusAddress &_dbusAddress,
const std::shared_ptr<DBusProxyConnection> &_connection):
DBusProxyBase(_dbusAddress, _connection),
dbusProxyStatusEvent_(this),
availabilityStatus_(AvailabilityStatus::UNKNOWN),
interfaceVersionAttribute_(*this, "uu", "getInterfaceVersion"),
- dbusServiceRegistry_(DBusServiceRegistry::get(_connection)),
- signalMemberHandlerInfo_(3000)
+ dbusServiceRegistry_(DBusServiceRegistry::get(_connection))
{
+ Factory::get()->incrementConnection(connection_);
}
void DBusProxy::init() {
@@ -43,9 +180,14 @@ void DBusProxy::init() {
}
DBusProxy::~DBusProxy() {
+ if(availabilityTimeoutThread_) {
+ if(availabilityTimeoutThread_->joinable())
+ availabilityTimeoutThread_->join();
+ }
dbusServiceRegistry_->unsubscribeAvailabilityListener(
getAddress().getAddress(),
dbusServiceRegistrySubscription_);
+ Factory::get()->decrementConnection(connection_);
}
bool DBusProxy::isAvailable() const {
@@ -66,6 +208,56 @@ bool DBusProxy::isAvailableBlocking() const {
return true;
}
+std::future<AvailabilityStatus> DBusProxy::isAvailableAsync(
+ isAvailableAsyncCallback _callback,
+ const CommonAPI::CallInfo *_info) const {
+
+ std::promise<AvailabilityStatus> promise;
+ std::future<AvailabilityStatus> future = promise.get_future();
+
+ //set timeout point
+ auto timeoutPoint = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(_info->timeout_);
+
+ timeoutsMutex_.lock();
+ if(timeouts_.size() == 0) {
+ //no timeouts
+
+ bool isAvailabilityTimeoutThread = false;
+
+ //join running availability thread
+ if(availabilityTimeoutThread_) {
+
+ //check if current thread is availability timeout thread
+ isAvailabilityTimeoutThread = (std::this_thread::get_id() ==
+ availabilityTimeoutThread_.get()->get_id());
+
+ if(availabilityTimeoutThread_->joinable() && !isAvailabilityTimeoutThread) {
+ timeoutsMutex_.unlock();
+ availabilityTimeoutThread_->join();
+ timeoutsMutex_.lock();
+ }
+ }
+ //add new timeout
+ timeouts_.push_back(std::make_tuple(timeoutPoint, _callback, std::move(promise)));
+
+ //start availability thread
+ if(!isAvailabilityTimeoutThread)
+ availabilityTimeoutThread_ = std::make_shared<std::thread>(
+ std::bind(&DBusProxy::availabilityTimeoutThreadHandler, this));
+ } else {
+ //add timeout
+ timeouts_.push_back(std::make_tuple(timeoutPoint, _callback, std::move(promise)));
+ }
+ timeoutsMutex_.unlock();
+
+ availabilityTimeoutThreadMutex_.lock();
+ //notify availability thread that new timeout was added
+ availabilityTimeoutCondition_.notify_all();
+ availabilityTimeoutThreadMutex_.unlock();
+
+ return future;
+}
+
ProxyStatusEvent& DBusProxy::getProxyStatusEvent() {
return dbusProxyStatusEvent_;
}
@@ -87,15 +279,23 @@ void DBusProxy::signalInitialValueCallback(const CallStatus _status,
const DBusMessage &_message,
DBusProxyConnection::DBusSignalHandler *_handler,
const uint32_t _tag) {
- (void)_status;
- _handler->onInitialValueSignalDBusMessage(_message, _tag);
+ if (_status != CallStatus::SUCCESS) {
+ COMMONAPI_ERROR("Error when receiving initial value of an attribute");
+ } else {
+ _handler->onInitialValueSignalDBusMessage(_message, _tag);
+ }
}
void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus) {
if (availabilityStatus != availabilityStatus_) {
- availabilityStatusMutex_.lock();
+ availabilityMutex_.lock();
availabilityStatus_ = availabilityStatus;
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
+
+ availabilityTimeoutThreadMutex_.lock();
+ //notify availability thread that proxy status has changed
+ availabilityTimeoutCondition_.notify_all();
+ availabilityTimeoutThreadMutex_.unlock();
dbusProxyStatusEvent_.notifyListeners(availabilityStatus);
@@ -118,27 +318,26 @@ void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabili
DBusMessage message = createMethodCall(std::get<4>(*signalMemberHandlerIterator), "");
- DBusProxyAsyncSignalMemberCallbackHandler::FunctionType myFunc = std::bind(
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::Delegate::FunctionType myFunc = std::bind(
&DBusProxy::signalMemberCallback,
this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3,
std::placeholders::_4);
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::Delegate delegate(shared_from_this(), myFunc);
connection_->sendDBusMessageWithReplyAsync(
message,
- DBusProxyAsyncSignalMemberCallbackHandler::create(myFunc, std::get<5>(*signalMemberHandlerIterator), 0),
- &signalMemberHandlerInfo_);
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::create(delegate, std::get<5>(*signalMemberHandlerIterator), 0),
+ &defaultCallInfo);
}
}
{
std::lock_guard < std::mutex > queueLock(selectiveBroadcastHandlersMutex_);
for (auto selectiveBroadcasts : selectiveBroadcastHandlers) {
std::string methodName = "subscribeFor" + selectiveBroadcasts.first + "Selective";
- bool subscriptionAccepted = connection_->sendPendingSelectiveSubscription(this, methodName);
- if (!subscriptionAccepted) {
- selectiveBroadcasts.second->onError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED);
- }
+ connection_->sendPendingSelectiveSubscription(this, methodName, selectiveBroadcasts.second.first,
+ selectiveBroadcasts.second.second);
}
}
} else {
@@ -160,38 +359,33 @@ void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabili
}
}
}
- availabilityStatusMutex_.lock();
+ availabilityMutex_.lock();
availabilityCondition_.notify_one();
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
}
-DBusProxyConnection::DBusSignalHandlerToken DBusProxy::subscribeForSelectiveBroadcastOnConnection(
- bool& subscriptionAccepted,
+void DBusProxy::insertSelectiveSubscription(const std::string& interfaceMemberName,
+ DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, uint32_t tag) {
+ std::lock_guard < std::mutex > queueLock(selectiveBroadcastHandlersMutex_);
+ selectiveBroadcastHandlers[interfaceMemberName] = std::make_pair(dbusSignalHandler, tag);
+}
+
+void DBusProxy::subscribeForSelectiveBroadcastOnConnection(
const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler) {
-
- DBusProxyConnection::DBusSignalHandlerToken token =
- getDBusConnection()->subscribeForSelectiveBroadcast(
- subscriptionAccepted,
- objectPath,
- interfaceName,
- interfaceMemberName,
- interfaceMemberSignature,
- dbusSignalHandler,
- this);
-
- if (!isAvailable()) {
- subscriptionAccepted = true;
- }
- if (subscriptionAccepted) {
- std::lock_guard < std::mutex > queueLock(selectiveBroadcastHandlersMutex_);
- selectiveBroadcastHandlers[interfaceMemberName] = dbusSignalHandler;
- }
-
- return token;
+ DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ uint32_t tag) {
+
+ getDBusConnection()->subscribeForSelectiveBroadcast(
+ objectPath,
+ interfaceName,
+ interfaceMemberName,
+ interfaceMemberSignature,
+ dbusSignalHandler,
+ this,
+ tag);
}
void DBusProxy::unsubscribeFromSelectiveBroadcast(const std::string& eventName,
@@ -204,7 +398,7 @@ void DBusProxy::unsubscribeFromSelectiveBroadcast(const std::string& eventName,
std::string interfaceMemberName = std::get<2>(subscription);
auto its_handler = selectiveBroadcastHandlers.find(interfaceMemberName);
if (its_handler != selectiveBroadcastHandlers.end()) {
- selectiveBroadcastHandlers.erase(its_handler);
+ selectiveBroadcastHandlers.erase(interfaceMemberName);
}
}
@@ -251,9 +445,9 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler(
justAddFilter,
false);
- availabilityStatusMutex_.lock();
+ availabilityMutex_.lock();
if (availabilityStatus_ == AvailabilityStatus::AVAILABLE) {
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
signalHandlerToken = connection_->addSignalMemberHandler(
objectPath,
interfaceName,
@@ -263,7 +457,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler(
justAddFilter);
std::get<7>(signalMemberHandler) = true;
} else {
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
}
addSignalMemberHandlerToQueue(signalMemberHandler);
} else {
@@ -333,24 +527,25 @@ void DBusProxy::getCurrentValueForSignalListener(
DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
const uint32_t subscription) {
- availabilityStatusMutex_.lock();
+ availabilityMutex_.lock();
if (availabilityStatus_ == AvailabilityStatus::AVAILABLE) {
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
DBusMessage message = createMethodCall(getMethodName, "");
- DBusProxyAsyncSignalMemberCallbackHandler::FunctionType myFunc = std::bind(&DBusProxy::signalInitialValueCallback,
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::Delegate::FunctionType myFunc = std::bind(&DBusProxy::signalInitialValueCallback,
this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3,
std::placeholders::_4);
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::Delegate delegate(shared_from_this(), myFunc);
connection_->sendDBusMessageWithReplyAsync(
message,
- DBusProxyAsyncSignalMemberCallbackHandler::create(myFunc, dbusSignalHandler, subscription),
- &signalMemberHandlerInfo_);
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::create(delegate, dbusSignalHandler, subscription),
+ &defaultCallInfo);
} else {
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
}
}
@@ -360,9 +555,9 @@ void DBusProxy::freeDesktopGetCurrentValueForSignalListener(
const std::string &interfaceName,
const std::string &propertyName) {
- availabilityStatusMutex_.lock();
+ availabilityMutex_.lock();
if (availabilityStatus_ == AvailabilityStatus::AVAILABLE) {
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
DBusAddress itsAddress(getDBusAddress());
itsAddress.setInterface("org.freedesktop.DBus.Properties");
@@ -372,20 +567,21 @@ void DBusProxy::freeDesktopGetCurrentValueForSignalListener(
::serialize(output, interfaceName, propertyName);
if (success) {
output.flush();
- DBusProxyAsyncSignalMemberCallbackHandler::FunctionType myFunc = std::bind(&DBusProxy::signalInitialValueCallback,
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::Delegate::FunctionType myFunc = std::bind(&DBusProxy::signalInitialValueCallback,
this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3,
std::placeholders::_4);
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::Delegate delegate(shared_from_this(), myFunc);
connection_->sendDBusMessageWithReplyAsync(
_message,
- DBusProxyAsyncSignalMemberCallbackHandler::create(myFunc, dbusSignalHandler, subscription),
- &signalMemberHandlerInfo_);
+ DBusProxyAsyncSignalMemberCallbackHandler<DBusProxy>::create(delegate, dbusSignalHandler, subscription),
+ &defaultCallInfo);
}
} else {
- availabilityStatusMutex_.unlock();
+ availabilityMutex_.unlock();
}
}
diff --git a/src/CommonAPI/DBus/DBusProxyManager.cpp b/src/CommonAPI/DBus/DBusProxyManager.cpp
index 8ea30e3..e36f6e1 100644
--- a/src/CommonAPI/DBus/DBusProxyManager.cpp
+++ b/src/CommonAPI/DBus/DBusProxyManager.cpp
@@ -54,6 +54,7 @@ void
DBusProxyManager::getAvailableInstances(
CommonAPI::CallStatus &_status,
std::vector<std::string> &_availableInstances) {
+ _availableInstances.clear();
DBusObjectManagerStub::DBusObjectPathAndInterfacesDict dict;
DBusProxyHelper<
@@ -161,6 +162,10 @@ DBusProxyManager::translateCommonApiAddresses(
CommonAPI::Address itsAddress;
DBusAddress itsDBusAddress;
+ // get service information from proxy
+ const std::string &_service = proxy_.getDBusAddress().getService();
+ itsDBusAddress.setService(_service);
+
for (const auto &objectPathIter : _dict) {
itsDBusAddress.setObjectPath(objectPathIter.first);
diff --git a/src/CommonAPI/DBus/DBusServiceRegistry.cpp b/src/CommonAPI/DBus/DBusServiceRegistry.cpp
index 0ee7705..65290fc 100644
--- a/src/CommonAPI/DBus/DBusServiceRegistry.cpp
+++ b/src/CommonAPI/DBus/DBusServiceRegistry.cpp
@@ -37,6 +37,12 @@ DBusServiceRegistry::get(std::shared_ptr<DBusProxyConnection> _connection) {
return registry;
}
+void
+DBusServiceRegistry::remove(std::shared_ptr<DBusProxyConnection> _connection) {
+ std::lock_guard<std::mutex> itsGuard(registriesMutex_);
+ registries_.erase(_connection);
+}
+
DBusServiceRegistry::DBusServiceRegistry(std::shared_ptr<DBusProxyConnection> dbusProxyConnection) :
dbusDaemonProxy_(std::make_shared<CommonAPI::DBus::DBusDaemonProxy>(dbusProxyConnection)),
initialized_(false),
@@ -70,8 +76,9 @@ DBusServiceRegistry::~DBusServiceRegistry() {
const bool isSubscriptionCancelled = dbusProxyConnection->removeObjectManagerSignalMemberHandler(
dbusServiceUniqueName,
this);
- assert(isSubscriptionCancelled);
- (void)isSubscriptionCancelled;
+ if (!isSubscriptionCancelled) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), ": still subscribed too ", std::string(dbusServiceUniqueName));
+ }
}
}
@@ -105,12 +112,13 @@ DBusServiceRegistry::subscribeAvailabilityListener(
COMMONAPI_ERROR(
"You must not build proxies in callbacks of ProxyStatusEvent.",
" Please refer to the documentation for suggestions how to avoid this.");
- assert(false);
}
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
auto& dbusServiceListenersRecord = dbusServiceListenersMap[dbusAddress.getService()];
- assert(dbusServiceListenersRecord.uniqueBusNameState != DBusRecordState::AVAILABLE);
+ if (dbusServiceListenersRecord.uniqueBusNameState == DBusRecordState::AVAILABLE) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " uniqueBusName ", dbusServiceListenersRecord.uniqueBusName, " already AVAILABLE");
+ }
auto& dbusInterfaceNameListenersMap = dbusServiceListenersRecord.dbusObjectPathListenersMap[dbusAddress.getObjectPath()];
auto& dbusInterfaceNameListenersRecord = dbusInterfaceNameListenersMap[dbusAddress.getInterface()];
@@ -166,6 +174,8 @@ DBusServiceRegistry::subscribeAvailabilityListener(
dbusInterfaceNameListenersRecord.listenerList.push_front(std::move(serviceListener));
+ dbusServicesMutex_.unlock();
+
return dbusInterfaceNameListenersRecord.listenerList.begin();
}
@@ -175,11 +185,12 @@ DBusServiceRegistry::unsubscribeAvailabilityListener(
DBusAddress dbusAddress;
translator_->translate(_address, dbusAddress);
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
auto dbusServiceListenersIterator = dbusServiceListenersMap.find(dbusAddress.getService());
const bool isDBusServiceListenersRecordFound = (dbusServiceListenersIterator != dbusServiceListenersMap.end());
if (!isDBusServiceListenersRecordFound) {
+ dbusServicesMutex_.unlock();
return; // already unsubscribed
}
@@ -190,6 +201,7 @@ DBusServiceRegistry::unsubscribeAvailabilityListener(
(dbusObjectPathListenersIterator != dbusServiceListenersRecord.dbusObjectPathListenersMap.end());
if (!isDBusObjectPathListenersRecordFound) {
+ dbusServicesMutex_.unlock();
return; // already unsubscribed
}
@@ -199,6 +211,7 @@ DBusServiceRegistry::unsubscribeAvailabilityListener(
(dbusInterfaceNameListenersIterator != dbusInterfaceNameListenersMap.end());
if (!isDBusInterfaceNameListenersRecordFound) {
+ dbusServicesMutex_.unlock();
return; // already unsubscribed
}
@@ -213,6 +226,8 @@ DBusServiceRegistry::unsubscribeAvailabilityListener(
dbusServiceListenersRecord.dbusObjectPathListenersMap.erase(dbusObjectPathListenersIterator);
}
}
+
+ dbusServicesMutex_.unlock();
}
// d-feet mode until service is found
@@ -283,7 +298,10 @@ bool DBusServiceRegistry::isServiceInstanceAlive(const std::string& dbusInterfac
dbusServicesMutex_.unlock();
- assert(dbusUniqueNameRecord != NULL);
+ if (NULL == dbusUniqueNameRecord) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no unique name record found for IF: ", dbusInterfaceName,
+ " service: ", dbusServiceName, "object path: ", dbusObjectPath);
+ }
auto& dbusObjectPathsCache = dbusUniqueNameRecord->dbusObjectPathsCache;
auto dbusObjectPathCacheIterator = dbusObjectPathsCache.find(dbusObjectPath);
@@ -319,14 +337,17 @@ bool DBusServiceRegistry::isServiceInstanceAlive(const std::string& dbusInterfac
dbusObjectPathCache = &(dbusObjectPathCacheIterator->second);
- std::future<DBusRecordState> futureObjectPathResolved = dbusObjectPathCache->promiseOnResolve.get_future();
+ newDbusObjectPathCache.futureOnResolve = dbusObjectPathCache->promiseOnResolve.get_future();
dbusServicesMutex_.unlock();
introspectDBusObjectPath(uniqueName, dbusObjectPath);
- futureObjectPathResolved.wait_for(timeout);
+ newDbusObjectPathCache.futureOnResolve.wait_for(timeout);
}
- assert(dbusObjectPathCache != NULL);
+ if (NULL == dbusObjectPathCache) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no object path cache entry found for IF: ", dbusInterfaceName,
+ " service: ", dbusServiceName, "object path: ", dbusObjectPath);
+ }
dbusServicesMutex_.lock();
if(dbusObjectPathCache->state != DBusRecordState::RESOLVED) {
@@ -471,9 +492,15 @@ void DBusServiceRegistry::getAvailableServiceInstancesAsync(CommonAPI::Factory::
void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) {
const std::string& dbusServiceUniqueName = _dbusMessage.getSender();
- assert(_dbusMessage.isSignalType());
- assert(_dbusMessage.hasInterfaceName("org.freedesktop.DBus.ObjectManager"));
- assert(_dbusMessage.hasMemberName("InterfacesAdded") || _dbusMessage.hasMemberName("InterfacesRemoved"));
+ if (!_dbusMessage.isSignalType()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " signal message expected, got ", _dbusMessage.getMember(), " type: ", int(_dbusMessage.getType()));
+ }
+ if (!_dbusMessage.hasInterfaceName("org.freedesktop.DBus.ObjectManager")) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unexpected interface ", _dbusMessage.getInterface());
+ }
+ if (!_dbusMessage.hasMemberName("InterfacesAdded") && !_dbusMessage.hasMemberName("InterfacesAdded")) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unexpected member ", _dbusMessage.getMember());
+ }
DBusInputStream dbusInputStream(_dbusMessage);
std::string dbusObjectPath;
@@ -491,7 +518,9 @@ void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) {
dbusInputStream.align(8);
dbusInputStream >> dbusInterfaceName;
dbusInputStream.skipMap();
- assert(!dbusInputStream.hasError());
+ if (dbusInputStream.hasError()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " input stream error");
+ }
dbusInterfaceNames.insert(dbusInterfaceName);
}
dbusInputStream.endReadMapOfSerializableStructs();
@@ -515,7 +544,7 @@ void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) {
return;
}
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
auto dbusServiceUniqueNameIterator = dbusUniqueNamesMap_.find(dbusServiceUniqueName);
const bool isDBusServiceUniqueNameFound = (dbusServiceUniqueNameIterator != dbusUniqueNamesMap_.end());
@@ -523,6 +552,7 @@ void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) {
if (!isDBusServiceUniqueNameFound) {
// LB TODO: unsubscribe here!
// Needs to be reworked in order to store the subscription identifier!
+ dbusServicesMutex_.unlock();
return;
}
@@ -530,12 +560,15 @@ void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) {
DBusObjectPathCache *dbusObjectPathRecord;
auto dbusObjectPathCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath);
- if(dbusObjectPathCacheIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end())
+ if(dbusObjectPathCacheIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end()) {
dbusObjectPathRecord = &(dbusObjectPathCacheIterator->second);
- else
+ } else {
+ dbusServicesMutex_.unlock();
return;
+ }
if (dbusObjectPathRecord->state != DBusRecordState::RESOLVED) {
+ dbusServicesMutex_.unlock();
return;
}
@@ -548,6 +581,8 @@ void DBusServiceRegistry::onSignalDBusMessage(const DBusMessage &_dbusMessage) {
}
notifyDBusServiceListeners(dbusUniqueNameRecord, dbusObjectPath, dbusInterfaceNames, dbusInterfaceNameState);
+
+ dbusServicesMutex_.unlock();
}
void DBusServiceRegistry::setDBusServicePredefined(const std::string& _serviceName) {
@@ -556,22 +591,30 @@ void DBusServiceRegistry::setDBusServicePredefined(const std::string& _serviceNa
void DBusServiceRegistry::resolveDBusServiceName(const std::string& dbusServiceName,
DBusServiceListenersRecord& dbusServiceListenersRecord) {
- assert(dbusServiceListenersRecord.uniqueBusNameState != DBusRecordState::RESOLVED);
- assert(dbusServiceListenersRecord.uniqueBusName.empty());
+ if (dbusServiceListenersRecord.uniqueBusNameState == DBusRecordState::RESOLVED) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " already resolved ", dbusServiceName);
+ }
+ if (!dbusServiceListenersRecord.uniqueBusName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unique name not empty ", dbusServiceListenersRecord.uniqueBusName);
+ }
mutexServiceResolveCount.lock();
servicesToResolve++;
mutexServiceResolveCount.unlock();
if (dbusDaemonProxy_->isAvailable()) {
- dbusDaemonProxy_->getNameOwnerAsync(
- dbusServiceName,
- std::bind(
- &DBusServiceRegistry::onGetNameOwnerCallback,
- this->shared_from_this(),
- std::placeholders::_1,
- std::placeholders::_2,
- dbusServiceName));
+
+ auto func = std::bind(
+ &DBusServiceRegistry::onGetNameOwnerCallback,
+ this->shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2,
+ dbusServiceName);
+
+ DBusProxyAsyncCallbackHandler<DBusServiceRegistry,
+ std::string>::Delegate delegate(shared_from_this(), func);
+
+ dbusDaemonProxy_->getNameOwnerAsync<DBusServiceRegistry>(dbusServiceName, delegate);
dbusServiceListenersRecord.uniqueBusNameState = DBusRecordState::RESOLVING;
}
@@ -580,7 +623,7 @@ void DBusServiceRegistry::resolveDBusServiceName(const std::string& dbusServiceN
void DBusServiceRegistry::onGetNameOwnerCallback(const CallStatus& status,
std::string dbusServiceUniqueName,
const std::string& dbusServiceName) {
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
auto dbusServiceListenerIterator = dbusServiceListenersMap.find(dbusServiceName);
const bool isDBusServiceListenerRecordFound = (dbusServiceListenerIterator != dbusServiceListenersMap.end());
@@ -609,16 +652,25 @@ void DBusServiceRegistry::onGetNameOwnerCallback(const CallStatus& status,
servicesToResolve--;
mutexServiceResolveCount.unlock();
monitorResolveAllServices_.notify_all();
+
+ dbusServicesMutex_.unlock();
}
DBusServiceRegistry::DBusRecordState
DBusServiceRegistry::resolveDBusInterfaceNameState(
const DBusAddress &_dbusAddress, DBusServiceListenersRecord &dbusServiceListenersRecord) {
- assert(dbusServiceListenersRecord.uniqueBusNameState == DBusRecordState::RESOLVED);
- assert(!dbusServiceListenersRecord.uniqueBusName.empty());
+
+ if (dbusServiceListenersRecord.uniqueBusNameState != DBusRecordState::RESOLVED) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unresolved ", dbusServiceListenersRecord.uniqueBusName);
+ }
+ if (dbusServiceListenersRecord.uniqueBusName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unique bus name is empty");
+ }
auto& dbusServiceUniqueNameRecord = dbusUniqueNamesMap_[dbusServiceListenersRecord.uniqueBusName];
- assert(!dbusServiceUniqueNameRecord.ownedBusNames.empty());
+ if (dbusServiceListenersRecord.uniqueBusName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty ownedBusNames");
+ }
auto& dbusObjectPathRecord = getDBusObjectPathCacheReference(
_dbusAddress.getObjectPath(),
@@ -661,8 +713,9 @@ DBusServiceRegistry::getDBusObjectPathCacheReference(
const bool isSubscriptionSuccessful = dbusProxyConnection->addObjectManagerSignalMemberHandler(
dbusServiceUniqueName,
this);
- assert(isSubscriptionSuccessful);
- (void)isSubscriptionSuccessful;
+ if (!isSubscriptionSuccessful) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " cannot subscribe too ", dbusServiceUniqueName);
+ }
}
if (dbusObjectPathCacheIterator->second.state == DBusRecordState::UNKNOWN
@@ -683,19 +736,28 @@ void DBusServiceRegistry::releaseDBusObjectPathCacheReference(const std::string&
return;
}
- assert(!dbusServiceListenersRecord.uniqueBusName.empty());
+ if (dbusServiceListenersRecord.uniqueBusName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unique bus name is empty");
+ }
auto& dbusUniqueNameRecord = dbusUniqueNamesMap_[dbusServiceListenersRecord.uniqueBusName];
- assert(!dbusUniqueNameRecord.ownedBusNames.empty());
- assert(!dbusUniqueNameRecord.dbusObjectPathsCache.empty());
+ if (dbusServiceListenersRecord.uniqueBusName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty ownedBusNames");
+ }
+ if (dbusUniqueNameRecord.dbusObjectPathsCache.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " empty dbusObjectPathsCache");
+ }
auto dbusObjectPathCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath);
const bool isDBusObjectPathCacheFound = (dbusObjectPathCacheIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end());
- assert(isDBusObjectPathCacheFound);
- (void)isDBusObjectPathCacheFound;
+ if (!isDBusObjectPathCacheFound) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " no object path cache entry found for ", dbusObjectPath);
+ }
auto& dbusObjectPathCache = dbusObjectPathCacheIterator->second;
- assert(dbusObjectPathCache.referenceCount > 0);
+ if (0 == dbusObjectPathCache.referenceCount) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " reference count is 0");
+ }
dbusObjectPathCache.referenceCount--;
@@ -704,12 +766,15 @@ void DBusServiceRegistry::releaseDBusObjectPathCacheReference(const std::string&
const bool isLastDBusObjectPathCache = dbusUniqueNameRecord.dbusObjectPathsCache.empty();
if (isLastDBusObjectPathCache) {
+ dbusServicesMutex_.unlock();
auto dbusProxyConnection = dbusDaemonProxy_->getDBusConnection();
const bool isSubscriptionCancelled = dbusProxyConnection->removeObjectManagerSignalMemberHandler(
dbusServiceListenersRecord.uniqueBusName,
this);
- assert(isSubscriptionCancelled);
- (void)isSubscriptionCancelled;
+ if (!isSubscriptionCancelled) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), ": still subscribed too ", dbusServiceListenersRecord.uniqueBusName);
+ }
+ dbusServicesMutex_.lock();
}
}
}
@@ -732,7 +797,9 @@ bool DBusServiceRegistry::getManagedObjects(const std::string& dbusServiceUnique
bool isSendingInProgress = false;
auto dbusConnection = dbusDaemonProxy_->getDBusConnection();
- assert(!dbusServiceUniqueName.empty());
+ if (dbusServiceUniqueName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusServiceUniqueName empty");
+ }
if(dbusConnection->isConnected()) {
@@ -754,11 +821,17 @@ bool DBusServiceRegistry::getManagedObjects(const std::string& dbusServiceUnique
dbusServiceUniqueName,
dbusObjectPath);
+ DBusProxyAsyncCallbackHandler<
+ DBusServiceRegistry,
+ DBusObjectManagerStub::DBusObjectPathAndInterfacesDict
+ >::Delegate delegate(shared_from_this(), getManagedObjectsCallback);
+
dbusConnection->sendDBusMessageWithReplyAsync(
dbusMessageCall,
DBusProxyAsyncCallbackHandler<
+ DBusServiceRegistry,
DBusObjectManagerStub::DBusObjectPathAndInterfacesDict
- >::create(getManagedObjectsCallback, std::tuple<DBusObjectManagerStub::DBusObjectPathAndInterfacesDict>()),
+ >::create(delegate, std::tuple<DBusObjectManagerStub::DBusObjectPathAndInterfacesDict>()),
&serviceRegistryInfo);
isSendingInProgress = true;
@@ -852,12 +925,13 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolveFurther(const CallSt
// No further managed objects
}
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
auto dbusServiceUniqueNameIterator = dbusUniqueNamesMap_.find(dbusServiceUniqueName);
const bool isDBusServiceUniqueNameFound = (dbusServiceUniqueNameIterator != dbusUniqueNamesMap_.end());
if (!isDBusServiceUniqueNameFound) {
+ dbusServicesMutex_.unlock();
return;
}
@@ -866,13 +940,16 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolveFurther(const CallSt
const bool isDBusObjectPathFound = (dbusObjectPathIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end());
if (!isDBusObjectPathFound) {
+ dbusServicesMutex_.unlock();
return;
}
DBusObjectPathCache& dbusObjectPathRecord = dbusObjectPathIterator->second;
dbusObjectPathRecord.state = DBusRecordState::RESOLVED;
- dbusObjectPathRecord.promiseOnResolve.set_value(dbusObjectPathRecord.state);
+ if(dbusObjectPathRecord.futureOnResolve.valid()) {
+ dbusObjectPathRecord.promiseOnResolve.set_value(dbusObjectPathRecord.state);
+ }
mutexObjectPathsResolveCount.lock();
objectPathsToResolve--;
mutexObjectPathsResolveCount.unlock();
@@ -885,6 +962,8 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolveFurther(const CallSt
dbusObjectPath,
dbusObjectPathRecord.dbusInterfaceNamesCache,
DBusRecordState::RESOLVED);
+
+ dbusServicesMutex_.unlock();
}
void DBusServiceRegistry::processManagedObject(const std::string& dbusObjectPath,
@@ -905,7 +984,9 @@ bool DBusServiceRegistry::introspectDBusObjectPath(const std::string& dbusServic
bool isResolvingInProgress = false;
auto dbusConnection = dbusDaemonProxy_->getDBusConnection();
- assert(!dbusServiceUniqueName.empty());
+ if (dbusServiceUniqueName.empty()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusServiceUniqueName empty");
+ }
if (dbusConnection->isConnected()) {
mutexObjectPathsResolveCount.lock();
@@ -924,11 +1005,17 @@ bool DBusServiceRegistry::introspectDBusObjectPath(const std::string& dbusServic
dbusServiceUniqueName,
dbusObjectPath);
+ DBusProxyAsyncCallbackHandler<
+ DBusServiceRegistry,
+ std::string
+ >::Delegate delegate(shared_from_this(), instrospectAsyncCallback);
+
dbusConnection->sendDBusMessageWithReplyAsync(
dbusMessageCall,
DBusProxyAsyncCallbackHandler<
+ DBusServiceRegistry,
std::string
- >::create(instrospectAsyncCallback, std::tuple<std::string>()),
+ >::create(delegate, std::tuple<std::string>()),
&serviceRegistryInfo);
isResolvingInProgress = true;
@@ -956,7 +1043,7 @@ void DBusServiceRegistry::onIntrospectCallback(const CallStatus& callStatus,
parseIntrospectionData(xmlData, dbusObjectPath, dbusServiceUniqueName);
}
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
// Error CallStatus will result in empty parsedDBusInterfaceNameSet (and not available notification)
@@ -964,6 +1051,7 @@ void DBusServiceRegistry::onIntrospectCallback(const CallStatus& callStatus,
const bool isDBusServiceUniqueNameFound = (dbusServiceUniqueNameIterator != dbusUniqueNamesMap_.end());
if (!isDBusServiceUniqueNameFound) {
+ dbusServicesMutex_.unlock();
return;
}
@@ -972,6 +1060,7 @@ void DBusServiceRegistry::onIntrospectCallback(const CallStatus& callStatus,
const bool isDBusObjectPathFound = (dbusObjectPathIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end());
if (!isDBusObjectPathFound) {
+ dbusServicesMutex_.unlock();
return;
}
@@ -991,6 +1080,8 @@ void DBusServiceRegistry::onIntrospectCallback(const CallStatus& callStatus,
dbusObjectPath,
dbusObjectPathRecord.dbusInterfaceNamesCache,
DBusRecordState::RESOLVED);
+
+ dbusServicesMutex_.unlock();
}
void DBusServiceRegistry::parseIntrospectionNode(const pugi::xml_node& node, const std::string& rootObjectPath, const std::string& fullObjectPath, const std::string& dbusServiceUniqueName) {
@@ -1069,9 +1160,11 @@ void DBusServiceRegistry::parseIntrospectionData(const std::string& xmlData,
void DBusServiceRegistry::onDBusDaemonProxyStatusEvent(const AvailabilityStatus& availabilityStatus) {
- assert(availabilityStatus != AvailabilityStatus::UNKNOWN);
+ if (availabilityStatus == AvailabilityStatus::UNKNOWN) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unexpected availability status ", int(availabilityStatus));
+ }
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
for (auto& dbusServiceListenersIterator : dbusServiceListenersMap) {
const auto& dbusServiceName = dbusServiceListenersIterator.first;
@@ -1083,6 +1176,8 @@ void DBusServiceRegistry::onDBusDaemonProxyStatusEvent(const AvailabilityStatus&
onDBusServiceNotAvailable(dbusServiceListenersRecord, dbusServiceName);
}
}
+
+ dbusServicesMutex_.unlock();
}
void DBusServiceRegistry::checkDBusServiceWasAvailable(const std::string& dbusServiceName,
@@ -1105,7 +1200,7 @@ void DBusServiceRegistry::onDBusDaemonProxyNameOwnerChangedEvent(const std::stri
const bool isDBusServiceNameLost = newOwner.empty();
const std::string& dbusServiceUniqueName = (isDBusServiceNameLost ? oldOwner : newOwner);
- std::lock_guard<std::mutex> dbusServicesLock(dbusServicesMutex_);
+ dbusServicesMutex_.lock();
if (isDBusServiceNameLost) {
checkDBusServiceWasAvailable(affectedName, dbusServiceUniqueName);
@@ -1113,6 +1208,8 @@ void DBusServiceRegistry::onDBusDaemonProxyNameOwnerChangedEvent(const std::stri
onDBusServiceAvailable(affectedName, dbusServiceUniqueName);
}
+ dbusServicesMutex_.unlock();
+
return;
}
@@ -1175,7 +1272,7 @@ void DBusServiceRegistry::onDBusServiceAvailable(const std::string& dbusServiceN
}
void DBusServiceRegistry::onDBusServiceNotAvailable(DBusServiceListenersRecord& dbusServiceListenersRecord, const std::string &_serviceName) {
- const std::unordered_set<std::string> dbusInterfaceNamesCache;
+ const std::unordered_set<std::string> dbusInterfaceNamesCache {};
const DBusUniqueNamesMapIterator dbusUniqueNameRecordIterator = dbusUniqueNamesMap_.find(dbusServiceListenersRecord.uniqueBusName);
@@ -1268,9 +1365,9 @@ void DBusServiceRegistry::notifyDBusObjectPathChanged(DBusInterfaceNameListeners
const DBusRecordState& dbusInterfaceNamesState) {
const bool isDBusInterfaceNameAvailable = (dbusInterfaceNamesState == DBusRecordState::AVAILABLE);
- assert(
- dbusInterfaceNamesState == DBusRecordState::AVAILABLE
- || dbusInterfaceNamesState == DBusRecordState::NOT_AVAILABLE);
+ if ((dbusInterfaceNamesState != DBusRecordState::AVAILABLE) && (dbusInterfaceNamesState != DBusRecordState::NOT_AVAILABLE)) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " unexpected state ", int(dbusInterfaceNamesState));
+ }
for (const auto& dbusInterfaceName : dbusInterfaceNames) {
auto dbusInterfaceNameListenersIterator = dbusInterfaceNameListenersMap.find(dbusInterfaceName);
@@ -1305,12 +1402,6 @@ void DBusServiceRegistry::notifyDBusInterfaceNameListeners(DBusInterfaceNameList
}
void DBusServiceRegistry::removeUniqueName(const DBusUniqueNamesMapIterator& dbusUniqueNamesIterator, const std::string &_serviceName) {
- const bool isSubscriptionCancelled = dbusDaemonProxy_->getDBusConnection()->removeObjectManagerSignalMemberHandler(
- dbusUniqueNamesIterator->first,
- this);
- assert(isSubscriptionCancelled);
- (void)isSubscriptionCancelled;
-
if ("" != _serviceName) {
auto findServiceName = dbusUniqueNamesIterator->second.ownedBusNames.find(_serviceName);
if (findServiceName != dbusUniqueNamesIterator->second.ownedBusNames.end())
@@ -1320,7 +1411,16 @@ void DBusServiceRegistry::removeUniqueName(const DBusUniqueNamesMapIterator& dbu
}
if (dbusUniqueNamesIterator->second.ownedBusNames.size() == 0) {
+ std::string dbusUniqueName = dbusUniqueNamesIterator->first;
dbusUniqueNamesMap_.erase(dbusUniqueNamesIterator);
+ dbusServicesMutex_.unlock();
+ const bool isSubscriptionCancelled = dbusDaemonProxy_->getDBusConnection()->removeObjectManagerSignalMemberHandler(
+ dbusUniqueName,
+ this);
+ if (!isSubscriptionCancelled) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), ": still subscribed too ", dbusUniqueName);
+ }
+ dbusServicesMutex_.lock();
} else {
//delete object path cache entry of service
auto& dbusObjectPathsCache = dbusUniqueNamesIterator->second.dbusObjectPathsCache;
diff --git a/src/CommonAPI/DBus/DBusStubAdapter.cpp b/src/CommonAPI/DBus/DBusStubAdapter.cpp
index 6a3a8cf..422a419 100644
--- a/src/CommonAPI/DBus/DBusStubAdapter.cpp
+++ b/src/CommonAPI/DBus/DBusStubAdapter.cpp
@@ -5,6 +5,7 @@
#include <CommonAPI/DBus/DBusAddressTranslator.hpp>
#include <CommonAPI/DBus/DBusStubAdapter.hpp>
+#include <CommonAPI/DBus/DBusFactory.hpp>
namespace CommonAPI {
namespace DBus {
@@ -15,10 +16,12 @@ DBusStubAdapter::DBusStubAdapter(const DBusAddress &_dbusAddress,
: dbusAddress_(_dbusAddress),
connection_(_connection),
isManaging_(_isManaging) {
+ Factory::get()->incrementConnection(connection_);
}
DBusStubAdapter::~DBusStubAdapter() {
deinit();
+ Factory::get()->decrementConnection(connection_);
}
void DBusStubAdapter::init(std::shared_ptr<DBusStubAdapter> _instance) {