Beispiel #1
0
    // 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;
    }