瀏覽代碼

fixes 292, fixing some leaks, missing inializers, bugs... there seem be no subscription-related leaks anylonger

Stasik0 9 年之前
父節點
當前提交
d5002592c8

+ 2 - 2
src/server/ua_server.c

@@ -155,7 +155,7 @@ void UA_Server_delete(UA_Server *server) {
     // Delete all internal data
     UA_ApplicationDescription_deleteMembers(&server->description);
     UA_SecureChannelManager_deleteMembers(&server->secureChannelManager);
-    UA_SessionManager_deleteMembers(&server->sessionManager);
+    UA_SessionManager_deleteMembers(&server->sessionManager, server);
     UA_NodeStore_delete(server->nodestore);
 #ifdef UA_EXTERNAL_NAMESPACES
     UA_Server_deleteExternalNamespaces(server);
@@ -183,7 +183,7 @@ void UA_Server_delete(UA_Server *server) {
 /* Recurring cleanup. Removing unused and timed-out channels and sessions */
 static void UA_Server_cleanup(UA_Server *server, void *nothing) {
     UA_DateTime now = UA_DateTime_now();
-    UA_SessionManager_cleanupTimedOut(&server->sessionManager, now);
+    UA_SessionManager_cleanupTimedOut(&server->sessionManager, server, now);
     UA_SecureChannelManager_cleanupTimedOut(&server->secureChannelManager, now);
 }
 

+ 1 - 1
src/server/ua_server_binary.c

@@ -161,7 +161,7 @@ static void invoke_service(UA_Server *server, UA_SecureChannel *channel, UA_UInt
     } else if(session->activated == UA_FALSE) {
         response->serviceResult = UA_STATUSCODE_BADSESSIONNOTACTIVATED;
         /* the session is invalidated FIXME: do this delayed*/
-        UA_SessionManager_removeSession(&server->sessionManager, &request->authenticationToken);
+        UA_SessionManager_removeSession(&server->sessionManager, server, &request->authenticationToken);
     } else {
         UA_Session_updateLifetime(session);
         service(server, session, request, response);

+ 2 - 2
src/server/ua_services_session.c

@@ -30,7 +30,7 @@ void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
         response->responseHeader.serviceResult |=
             UA_ByteString_copy(&server->endpointDescriptions->serverCertificate, &response->serverCertificate);
     if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
-        UA_SessionManager_removeSession(&server->sessionManager, &newSession->authenticationToken);
+        UA_SessionManager_removeSession(&server->sessionManager, server, &newSession->authenticationToken);
          return;
     }
 }
@@ -119,5 +119,5 @@ void Service_CloseSession(UA_Server *server, UA_Session *session, const UA_Close
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
 	else 
         response->responseHeader.serviceResult =
-            UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
+            UA_SessionManager_removeSession(&server->sessionManager, server, &session->authenticationToken);
 }

+ 1 - 7
src/server/ua_services_subscription.c

@@ -123,15 +123,9 @@ void Service_Publish(UA_Server *server, UA_Session *session, const UA_PublishReq
     UA_Subscription  *sub;
     UA_MonitoredItem *mon;
     
+    UA_PublishResponse_init(response);
     // Verify Session and Subscription
     response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
-    response->diagnosticInfosSize = 0;
-    response->diagnosticInfos     = 0;
-    response->availableSequenceNumbersSize = 0;
-    response->resultsSize = 0;
-    response->subscriptionId = 0;
-    response->moreNotifications = UA_FALSE;
-    response->notificationMessage.notificationDataSize = 0;
         
     UA_SubscriptionManager *manager= &session->subscriptionManager;
     if(!manager)

+ 6 - 6
src/server/ua_session_manager.c

@@ -12,22 +12,22 @@ UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt3
     return UA_STATUSCODE_GOOD;
 }
 
-void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager) {
+void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager, UA_Server *server) {
     session_list_entry *current;
     while((current = LIST_FIRST(&sessionManager->sessions))) {
         LIST_REMOVE(current, pointers);
-        UA_Session_deleteMembersCleanup(&current->session);
+        UA_Session_deleteMembersCleanup(&current->session, server);
         UA_free(current);
     }
 }
 
-void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_DateTime now) {
+void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_Server* server, UA_DateTime now) {
     session_list_entry *sentry = LIST_FIRST(&sessionManager->sessions);
     while(sentry) {
         if(sentry->session.validTill < now) {
             session_list_entry *next = LIST_NEXT(sentry, pointers);
             LIST_REMOVE(sentry, pointers);
-            UA_Session_deleteMembersCleanup(&sentry->session);
+            UA_Session_deleteMembersCleanup(&sentry->session, server);
             UA_free(sentry);
             sessionManager->currentSessionCount--;
             sentry = next;
@@ -74,7 +74,7 @@ UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, const UA_NodeId *token) {
+UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_Server* server, const UA_NodeId *token) {
     session_list_entry *current;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
         if(UA_NodeId_equal(&current->session.authenticationToken, token))
@@ -83,7 +83,7 @@ UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager,
     if(!current)
         return UA_STATUSCODE_BADSESSIONIDINVALID;
     LIST_REMOVE(current, pointers);
-    UA_Session_deleteMembersCleanup(&current->session);
+    UA_Session_deleteMembersCleanup(&current->session, server);
     UA_free(current);
     sessionManager->currentSessionCount--;
     return UA_STATUSCODE_GOOD;

+ 3 - 3
src/server/ua_session_manager.h

@@ -22,15 +22,15 @@ typedef struct UA_SessionManager {
 UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
                                     UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId);
 
-void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager);
+void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager, UA_Server *server);
 
-void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_DateTime now);
+void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_Server *server, UA_DateTime now);
 
 UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
                                               UA_SecureChannel *channel, const UA_CreateSessionRequest *request,
                                               UA_Session **session);
 
-UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, const UA_NodeId *token);
+UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_Server *server, const UA_NodeId *token);
 
 /** Finds the session which is identified by the authentication token */
 UA_Session * UA_SessionManager_getSession(UA_SessionManager *sessionManager, const UA_NodeId *token);

+ 6 - 4
src/server/ua_subscription.c

@@ -21,11 +21,11 @@ UA_Subscription *UA_Subscription_new(UA_Int32 SubscriptionID) {
     return new;
 }
 
-void UA_Subscription_deleteMembers(UA_Server *server, UA_Subscription *subscription) {
+void UA_Subscription_deleteMembers(UA_Subscription *subscription, UA_Server *server) {
     UA_unpublishedNotification *not;
     UA_MonitoredItem *mon;
     
-    // Just in case any parallel process attempts to acces this subscription
+    // Just in case any parallel process attempts to access this subscription
     // while we are deleting it... make it vanish.
     subscription->SubscriptionID = 0;
     
@@ -44,9 +44,10 @@ void UA_Subscription_deleteMembers(UA_Server *server, UA_Subscription *subscript
     }
     
     // Unhook/Unregister any timed work assiociated with this subscription
-    if (subscription->timedUpdateJob != UA_NULL)
+    if (subscription->timedUpdateJob != UA_NULL){
         Subscription_unregisterUpdateJob(server, subscription);
         UA_free(subscription->timedUpdateJob);
+    }
     
     return;
 }
@@ -167,7 +168,7 @@ void Subscription_updateNotifications(UA_Subscription *subscription) {
             msg->notification->notificationData[notmsgn].body.length =
                 UA_calcSizeBinary(changeNotification, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]);
             msg->notification->notificationData[notmsgn].body.data   =
-                UA_calloc(0, (msg->notification->notificationData[notmsgn]).body.length);
+                UA_calloc((msg->notification->notificationData[notmsgn]).body.length, sizeof(void*));
         
             notificationOffset = 0;
             UA_encodeBinary(changeNotification, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION],
@@ -512,6 +513,7 @@ void MonitoredItem_QueuePushDataValue(UA_Server *server, UA_MonitoredItem *monit
     newvalue->listEntry.tqe_next = UA_NULL;
     newvalue->listEntry.tqe_prev = UA_NULL;
     UA_Variant_init(&newvalue->value);
+
   
     // Verify that the *Node being monitored is still valid
     // Looking up the in the nodestore is only necessary if we suspect that it is changed during writes

+ 1 - 1
src/server/ua_subscription.h

@@ -92,7 +92,7 @@ typedef struct UA_Subscription_s {
 } UA_Subscription;
 
 UA_Subscription *UA_Subscription_new(UA_Int32 SubscriptionID);
-void UA_Subscription_deleteMembers(UA_Server *server, UA_Subscription *subscription);
+void UA_Subscription_deleteMembers(UA_Subscription *subscription, UA_Server *server);
 void Subscription_updateNotifications(UA_Subscription *subscription);
 UA_UInt32 Subscription_queuedNotifications(UA_Subscription *subscription);
 UA_UInt32 *Subscription_getAvailableSequenceNumbers(UA_Subscription *sub);

+ 10 - 5
src/server/ua_subscription_manager.c

@@ -34,9 +34,14 @@ void SubscriptionManager_init(UA_Session *session) {
     manager->LastJobGuid.data4[7] = (UA_Byte) (manager->LastJobGuid.data4[0]) ^ (guidInitL >> 58);
 }
 
-void SubscriptionManager_deleteMembers(UA_Session *session) {
-    // UA_SubscriptionManager *manager = &(session->subscriptionManager);
-    // todo: delete all subscriptions and monitored items
+void SubscriptionManager_deleteMembers(UA_Session *session, UA_Server *server) {
+    UA_SubscriptionManager *manager = &(session->subscriptionManager);
+    UA_Subscription *current;
+    while((current = LIST_FIRST(&manager->ServerSubscriptions))) {
+        LIST_REMOVE(current, listEntry);
+        UA_Subscription_deleteMembers(current, server);
+        UA_free(current);
+    }
 }
 
 void SubscriptionManager_addSubscription(UA_SubscriptionManager *manager, UA_Subscription *newSubscription) {
@@ -75,7 +80,7 @@ UA_Int32 SubscriptionManager_deleteSubscription(UA_Server *server, UA_Subscripti
     if(!sub)
         return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
 
-    UA_Subscription_deleteMembers(server, sub);
+    UA_Subscription_deleteMembers(sub, server);
     
     LIST_REMOVE(sub, listEntry);
     UA_free(sub);
@@ -97,4 +102,4 @@ UA_Guid SubscriptionManager_getUniqueGUID(UA_SubscriptionManager *manager) {
     UA_Guid_copy(&(manager->LastJobGuid), &id);
     
     return id;
-}
+}

+ 1 - 1
src/server/ua_subscription_manager.h

@@ -20,7 +20,7 @@ typedef struct UA_SubscriptionManager {
 } UA_SubscriptionManager;
 
 void SubscriptionManager_init(UA_Session *session);
-void SubscriptionManager_deleteMembers(UA_Session *session);
+void SubscriptionManager_deleteMembers(UA_Session *session, UA_Server *server);
 void SubscriptionManager_addSubscription(UA_SubscriptionManager *manager, UA_Subscription *subscription);
 UA_Subscription *SubscriptionManager_getSubscriptionByID(UA_SubscriptionManager *manager,
                                                          UA_Int32 SubscriptionID);

+ 7 - 7
src/ua_session.c

@@ -41,14 +41,14 @@ void UA_Session_init(UA_Session *session) {
     session->timeout = 0;
     UA_DateTime_init(&session->validTill);
     session->channel = UA_NULL;
-    #ifdef ENABLE_SUBSCRIPTIONS
-        SubscriptionManager_init(session);
-    #endif
+#ifdef ENABLE_SUBSCRIPTIONS
+    SubscriptionManager_init(session);
+#endif
     session->availableContinuationPoints = MAXCONTINUATIONPOINTS;
     LIST_INIT(&session->continuationPoints);
 }
 
-void UA_Session_deleteMembersCleanup(UA_Session *session) {
+void UA_Session_deleteMembersCleanup(UA_Session *session, UA_Server* server) {
     UA_ApplicationDescription_deleteMembers(&session->clientDescription);
     UA_NodeId_deleteMembers(&session->authenticationToken);
     UA_NodeId_deleteMembers(&session->sessionId);
@@ -62,9 +62,9 @@ void UA_Session_deleteMembersCleanup(UA_Session *session) {
     }
     if(session->channel)
         UA_SecureChannel_detachSession(session->channel, session);
-    #ifdef ENABLE_SUBSCRIPTIONS
-        SubscriptionManager_deleteMembers(session);
-    #endif
+#ifdef ENABLE_SUBSCRIPTIONS
+    SubscriptionManager_deleteMembers(session, server);
+#endif
 }
 
 void UA_Session_updateLifetime(UA_Session *session) {

+ 1 - 1
src/ua_session.h

@@ -47,7 +47,7 @@ extern UA_Session anonymousSession; ///< If anonymous access is allowed, this se
 extern UA_Session adminSession; ///< Local access to the services (for startup and maintenance) uses this Session with all possible access rights (Session ID: 1)
 
 void UA_Session_init(UA_Session *session);
-void UA_Session_deleteMembersCleanup(UA_Session *session);
+void UA_Session_deleteMembersCleanup(UA_Session *session, UA_Server *server);
 
 /** If any activity on a session happens, the timeout is extended */
 void UA_Session_updateLifetime(UA_Session *session);