// Constructor // ============================================================================================= Subscription::Subscription( LoggerFactory* loggerFactory, const SubscriptionSettings& subscriptionSettings, ClientSubscriptionHandle clientSubscriptionHandle, ClientConnectionId clientConnectionId, UaClientSdk::UaSession* uaSession, UaClientSdk::UaSubscriptionCallback* uaSubscriptionCallback, uafc::ClientInterface* clientInterface, Database* database) : uaSession_(uaSession), uaSubscriptionCallback_(uaSubscriptionCallback), subscriptionSettings_(subscriptionSettings), clientSubscriptionHandle_(clientSubscriptionHandle), clientConnectionId_(clientConnectionId), database_(database), clientInterface_(clientInterface), clientHandle_(0) { // build the logger name: stringstream loggerName; loggerName << "Subscription-" << int(clientSubscriptionHandle); logger_ = new Logger(loggerFactory, loggerName.str()); subscriptionState_ = uafc::subscriptionstates::Deleted; uaSubscription_ = 0; logger_->debug("Subscription %d has been constructed", clientSubscriptionHandle); logger_->debug("Subscription settings:"); logger_->debug(subscriptionSettings.toString()); }
// Construct a subscription if needed // ============================================================================================= Status SubscriptionFactory::acquireSubscription( const SubscriptionSettings& subscriptionSettings, Subscription*& subscription) { logger_->debug("Acquiring subscription with the following settings:"); logger_->debug(subscriptionSettings.toString()); Status ret; subscription = 0; // lock the mutex to make sure the subscriptionMap_ is not being manipulated UaMutexLocker locker(&subscriptionMapMutex_); // we'll try to find a similar subscription that can be re-used, // unless we're creating an "unique" subscription // (one that is only created for -and used by- the current request) if (subscriptionSettings.unique) { logger_->debug("The requested subscription must be unique"); } else { // loop trough the subscriptions ... for (SubscriptionMap::const_iterator it = subscriptionMap_.begin(); it != subscriptionMap_.end(); ++it) { // ... until a suitable one is found if (it->second->subscriptionSettings() == subscriptionSettings) { subscription = it->second; logger_->debug("A suitable subscription (ClientSubscriptionHandle=%d) already exists", subscription->clientSubscriptionHandle()); // get the ClientSubscriptionHandle of the subscription ClientSubscriptionHandle handle = subscription->clientSubscriptionHandle(); // now increment the activity count of the subscription activityMapMutex_.lock(); activityMap_[handle] = activityMap_[handle] + 1; activityMapMutex_.unlock(); ret = statuscodes::Good; break; } } } // if no subscription exists yet, we create one if (subscription == 0) { ClientSubscriptionHandle clientSubscriptionHandle; clientSubscriptionHandle = database_->createUniqueClientSubscriptionHandle(); logger_->debug("We create a new subscription with clientSubscriptionHandle %d", clientSubscriptionHandle); // create a new subscription instance subscription = new Subscription( logger_->loggerFactory(), subscriptionSettings, clientSubscriptionHandle, clientConnectionId_, uaSession_, this, clientInterface_, database_); // store the new subscription instance in the subscriptionMap subscriptionMap_[clientSubscriptionHandle] = subscription; logger_->debug("The new subscription has been created"); // create an activity count for the subscription activityMapMutex_.lock(); activityMap_[clientSubscriptionHandle] = 1; activityMapMutex_.unlock(); // create the subscription on the server ret = subscription->createSubscription(); } // 'subscription' now points to an existing Subscription instance // (i.e. a valid memory location) // add some diagnostics if (ret.isGood()) { activityMapMutex_.lock(); logger_->debug("The requested subscription is acquired (#activities: %d)", activityMap_[subscription->clientSubscriptionHandle()]); activityMapMutex_.unlock(); } else { logger_->error("The requested subscription could not be acquired"); } return ret; }