ERROR_CODE CConnectivityAgentProxy::deallocateChannel(UInt32 channel_id) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel(chID = " + convertIntegerToString(channel_id) + ")"); ERROR_CODE ret = ERR_NOTFOUND; mRegistryMutex.lockWrite(); // Channel info will be saved in info and removed from registry here. // In case of some errors, it will be restored in registry. tChannelInfo info; tChannelsRegistryMap::iterator iter = mChannelRegistry.find(channel_id); if (iter == mChannelRegistry.end()) { LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::deallocateChannel(chID = " + convertIntegerToString(channel_id) + ") => ERROR: Channel not found! "); } else { ret = ERR_OK; info = iter->second; iter->second.mChannelBuffer.forgetData(); mChannelRegistry.erase(iter); mChannelOnDeallocSet.insert(channel_id); } mRegistryMutex.unlockWrite(); if (ret != ERR_OK) return ret; CDataAccessor requestDA; requestDA.setChannelID(channel_id); requestDA.setOpCode(E_DEALLOCATE_CHANNEL); UInt8* buf = new UInt8[requestDA.getObjectSize()]; requestDA.copyToRawArray(buf); // response will be sent later as a separate request UInt32 respSize = 0; CError err = mpIpc->request(mMsgIdGen.next(), buf, requestDA.getObjectSize(), NULL, respSize); delete[] buf; if (!err.isNoError()) { LOG4CPLUS_WARN(logger, static_cast<std::string>(err)); ret = ERR_FAIL; } else { CDataAccessor responseDA; mDeallocateRequestResultCond.lock(); { LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel waiting for mLastRequestResultDA"); while (mDeallocateRequestResultMap.find(channel_id) == mDeallocateRequestResultMap.end()) { LOG4CPLUS_INFO(logger, "before wait"); mDeallocateRequestResultCond.wait(); LOG4CPLUS_INFO(logger, "after wait"); } responseDA = mDeallocateRequestResultMap[channel_id]; mDeallocateRequestResultMap.erase(channel_id); } mDeallocateRequestResultCond.unlock(); if (responseDA.getData()) { if ((E_DEALLOCATE_CHANNEL_RESP == responseDA.getOpCode()) && (channel_id == responseDA.getChannelID())) { UInt32 data = 0; memcpy(&data, responseDA.getData(), sizeof(UInt32)); responseDA.resetAll(); ret = static_cast<ERROR_CODE>(data); } else { LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::deallocateChannel() => ERROR: wrong response type(" + convertIntegerToString(responseDA.getOpCode()) + ") from Agent !!! "); ret = ERR_WRONG_SEQUENCE; } } else { LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel() => " "channel already deleted form other side"); ret = ERR_OK; } } if (ret != ERR_OK) { // something gone wrong, we need to restore information in registry mRegistryMutex.lockWrite(); if (mChannelRegistry.find(channel_id) != mChannelRegistry.end()) { LOG4CPLUS_WARN(logger, "CConnectivityAgentProxy::deallocateChannel: " "something gone wrong and I'm unable to restore channel info - " "there is a channel in registry with such id"); } else { mChannelRegistry[channel_id] = info; info.mChannelBuffer.forgetData(); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel:" "unable to delete channel " + convertIntegerToString(channel_id) + ", so channel info is restored"); } mRegistryMutex.unlockWrite(); } mRegistryMutex.lockWrite(); mChannelOnDeallocSet.erase(channel_id); mRegistryMutex.unlockWrite(); return ret; }
ERROR_CODE CConnectivityAgentProxy::allocateChannel(TChannelPriority prio, UInt32 channel_id, IChannelObserver* observer) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::allocateChannel(type = " + convertIntegerToString((int) prio) + ", id = " + convertIntegerToString(channel_id) + " ), this = " + convertIntegerToString((intptr_t) this)); ERROR_CODE ret = ERR_FAIL; if ((channel_id > 0) && (channel_id <= 0xFFFF) && (NULL != observer)) { mRegistryMutex.lockWrite(); bool channel_unknown = mChannelRegistry.find(channel_id) == mChannelRegistry.end(); mRegistryMutex.unlockWrite(); if (channel_unknown) { mAllocateRequestCond.lock(); bool channel_requested = mAllocateRequestMap.find(channel_id) != mAllocateRequestMap.end(); if (channel_requested) { ret = ERR_IN_PROGRESS; channel_unknown = false; LOG4CPLUS_WARN(logger, "CConnectivityAgentProxy::allocateChannel() => ERROR: channel allocation in progress!"); } else { LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::allocateChannel() => insert request"); mAllocateRequestMap.insert( std::make_pair(channel_id, AllocateRequestInfo(prio, observer, false, ERR_UNKNOWN))); } mAllocateRequestCond.unlock(); } if (channel_unknown) { CDataAccessor requestDA; requestDA.setChannelID(channel_id); requestDA.setOpCode(E_ALLOCATE_CHANNEL); UInt32 data = prio; requestDA.setData(reinterpret_cast<UInt8 *>(&data), sizeof(UInt32)); UInt8* buf = new UInt8[requestDA.getObjectSize()]; requestDA.copyToRawArray(buf); UInt8 respBuf[100]; UInt32 respSize = sizeof(respBuf); CError err = mpIpc->request(mMsgIdGen.next(), buf, requestDA.getObjectSize(), respBuf, respSize); delete[] buf; if (!err.isNoError()) { LOG4CPLUS_WARN(logger, static_cast<std::string>(err)); ret = ERR_FAIL; mAllocateRequestCond.lock(); mAllocateRequestMap.erase(channel_id); mAllocateRequestCond.unlock(); LOG4CPLUS_WARN(logger, "CConnectivityAgentProxy::allocateChannel() => ERROR: failed to send request"); } else { CDataAccessor responseDA; if (respSize > 0) { responseDA = CDataAccessor(respBuf, respSize); ret = static_cast<ERROR_CODE>(responseDA.getErrorCode()); mAllocateRequestCond.lock(); mAllocateRequestMap.erase(channel_id); mAllocateRequestCond.unlock(); LOG4CPLUS_WARN(logger, "CConnectivityAgentProxy::allocateChannel() => ERROR: got error response"); } else { mAllocateRequestCond.lock(); while (true) { tAllocateRequestMap::iterator it = mAllocateRequestMap.find(channel_id); if (it == mAllocateRequestMap.end()) { ret = ERR_FAIL; LOG4CPLUS_WARN(logger, "CConnectivityAgentProxy::allocateChannel() => ERROR: request was removed"); break; } AllocateRequestInfo & info = it->second; if (info.mRequestDone) { LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::allocateChannel() => request done"); ret = info.mResult; mAllocateRequestMap.erase(it); break; } LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::allocateChannel() => before wait"); mAllocateRequestCond.wait(); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::allocateChannel() => after wait"); } mAllocateRequestCond.unlock(); } // if response empty } // if no ipc err } else { LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::allocateChannel() => ERROR: channel already exists! "); ret = ERR_NUMBER_BUSY; } } return ret; }