QNX: NameServer_delete in NameServer daemon leaks memory
authorAngela Stegmaier <angelabaker@ti.com>
Fri, 24 Mar 2017 21:57:37 +0000 (16:57 -0500)
committerAngela Stegmaier <angelabaker@ti.com>
Fri, 30 Jun 2017 15:42:30 +0000 (10:42 -0500)
Remove an invalid assertion that the name list must be empty.
This is not true and the instance might still be in use by
another client (object is reference counted). Add a while loop
to delete each entry on the name list. Destroy the object's
gate (was not being done). Remove the macro to destruct a
list object (not needed).

[Ported from commits 8a52a6a5fa20ac028158a3ad346da46555ce45b7
    "SDOCM00115434 NameServer_delete in LAD daemon leaks memory"
    and 6c4799151327f2c83b9f253ea25c52bef4e10803
    "Remove NameServer instance from module list in NameServer_delete()"]

Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
qnx/src/ipc3x_dev/ti/syslink/utils/hlos/knl/NameServer_daemon.c

index 425b0678dca960b22b734e39199488c626d19c8e..5fb5d6f891859c13ca30d8f284158a993802bc19 100644 (file)
@@ -135,11 +135,6 @@ typedef struct NameServer_ModuleObject {
     pthread_mutex_t      modGate;
 } NameServer_ModuleObject;
 
-#define CIRCLEQ_destruct(head) { \
-        (head)->cqh_first = NULL; \
-        (head)->cqh_last = NULL; \
-}
-
 #define CIRCLEQ_elemClear(elem) { \
         (elem)->cqe_next = (elem)->cqe_prev = (Void *)(elem); \
 }
@@ -429,7 +424,7 @@ Int NameServer_destroy(void)
         MessageQCopy_delete(&NameServer_module->mq);
     }
 
-    CIRCLEQ_destruct(&NameServer_module->objList);
+    /* TODO: delete any remaining instances */
 
     close(NameServer_module->waitFdW);
     close(NameServer_module->waitFdR);
@@ -559,38 +554,50 @@ leave:
 }
 
 
-/* Function to delete a name server. */
-Int NameServer_delete(NameServer_Handle * handle)
+/*
+ *  ======== NameServer_delete ========
+ *  Delete a name server instance
+ */
+Int NameServer_delete(NameServer_Handle *handle)
 {
     Int status = NameServer_S_SUCCESS;
+    struct NameServer_Object *obj;
 
     assert(handle != NULL);
     assert(*handle != NULL);
-    assert((*handle)->count == 0);
     assert(NameServer_module->refCount != 0);
 
+    obj = *(struct NameServer_Object **)handle;
+
     pthread_mutex_lock(&NameServer_module->modGate);
 
-    (*handle)->refCount--;
-    if ((*handle)->refCount != 0) {
+    obj->refCount--;
+    if (obj->refCount != 0) {
         goto leave;
     }
 
-    if ((*handle)->count == 0) {
-        CIRCLEQ_REMOVE(&NameServer_module->objList, *handle, elem);
+    /* delete each entry on the name list */
+    while (obj->nameList.cqh_first != (void *)&obj->nameList) {
+        NameServer_removeEntry(*handle, (Ptr)(obj->nameList.cqh_first));
+    }
 
-        if ((*handle)->name != NULL) {
-            free((*handle)->name);
-            (*handle)->name = NULL;
-        }
+    /* free the instance name */
+    if (obj->name != NULL) {
+        free(obj->name);
+        obj->name = NULL;
+    }
 
-        CIRCLEQ_destruct(&(*handle)->nameList);
+    /* destroy the mutex */
+    pthread_mutex_destroy(&obj->gate);
 
-        pthread_mutex_destroy(&(*handle)->gate);
+    /* remove from objList */
+    CIRCLEQ_REMOVE(&NameServer_module->objList, obj, elem);
 
-        free((*handle));
-        (*handle) = NULL;
-    }
+    /* finally, free the instance object */
+    free(obj);
+
+    /* set the caller's handle to null */
+    (*handle) = NULL;
 
 leave:
     pthread_mutex_unlock(&NameServer_module->modGate);