Implement reference counting in NameServer_create/delete (SDOCM00103730)
authorvwan@ti.com <vwan@ti.com>
Mon, 23 Sep 2013 21:57:22 +0000 (14:57 -0700)
committerChris Ring <cring@ti.com>
Wed, 25 Sep 2013 17:32:56 +0000 (10:32 -0700)
linux/src/daemon/NameServer_daemon.c
linux/src/tests/NameServerApp.c
packages/ti/ipc/NameServer.h
packages/ti/ipc/tests/NameServerApp.c [new file with mode: 0644]
packages/ti/ipc/tests/package.bld
packages/ti/sdo/utils/NameServer.c
packages/ti/sdo/utils/NameServer.xdc
packages/ti/sdo/utils/NameServer.xs
qnx/src/ipc3x_dev/ti/syslink/utils/hlos/knl/NameServer_daemon.c
qnx/src/tests/NameServerApp/NameServerApp.c

index f7104eac8698446e218dec5e900e08611ae859e9..f4dd2ddeebfc48c9249de86a68bc7e115bf96c3e 100644 (file)
@@ -113,6 +113,7 @@ struct NameServer_Object {
     String             name;            /* name of the instance */
     NameServer_Params  params;          /* the parameter structure */
     UInt32             count;           /* count of entries */
+    UInt32             refCount;        /* reference count to this object */
     pthread_mutex_t    gate;            /* crit sect gate */
 } NameServer_Object;
 
@@ -628,9 +629,16 @@ NameServer_Handle NameServer_create(String name,
     }
 
     /* check if the name is already created or not */
-    if (NameServer_getHandle(name)) {
-        LOG0("NameServer_create NameServer_E_INVALIDARG Name is in use!\n")
-        handle = NULL;
+    handle = NameServer_getHandle(name);
+    if (handle != NULL) {
+        if (memcmp((Ptr)&handle->params, (Ptr)params,
+            sizeof(NameServer_Params)) == 0) {
+            handle->refCount++;
+        }
+        else {
+            LOG0("NameServer_create: NameServer params mismatch\n")
+            handle = NULL;
+        }
         goto leave;
     }
     else {
@@ -642,6 +650,7 @@ NameServer_Handle NameServer_create(String name,
         goto leave;
     }
 
+    handle->refCount = 1;
     handle->name = (String)malloc(strlen(name) + 1u);
     if (!handle->name) {
         LOG0("NameServer_create: instance name alloc failed\n")
@@ -696,6 +705,11 @@ Int NameServer_delete(NameServer_Handle * handle)
 
     pthread_mutex_lock(&NameServer_module->modGate);
 
+    (*handle)->refCount--;
+    if ((*handle)->refCount != 0) {
+        goto leave;
+    }
+
     if ((*handle)->count == 0) {
         CIRCLEQ_REMOVE(&NameServer_module->objList, *handle, elem);
 
@@ -710,6 +724,7 @@ Int NameServer_delete(NameServer_Handle * handle)
         (*handle) = NULL;
     }
 
+leave:
     pthread_mutex_unlock(&NameServer_module->modGate);
 
     return (status);
index 45830ab7eb1005d8caafb4e0d4dc5e5ce3d419c0..1cb6e555a0c1698afba320e31114e5725960a2a1 100644 (file)
@@ -193,6 +193,7 @@ NameServerApp_startup()
     Int32 status = 0;
     NameServer_Params params;
     NameServer_Handle nsHandle;
+    NameServer_Handle nsHandleAlias;
     NameServer_Handle nsHandle2;
     Int iteration = 0;
 #ifdef USE_NSD
@@ -218,12 +219,14 @@ NameServerApp_startup()
 
 again:
     NameServer_Params_init(&params);
+
+    params.maxValueLen = sizeof(UInt32);
+    params.maxNameLen = 32;
+
     printf("params.maxValueLen=%d\n", params.maxValueLen);
     printf("params.maxNameLen=%d\n", params.maxNameLen);
     printf("params.checkExisting=%d\n", params.checkExisting);
 
-    params.maxValueLen = sizeof(UInt32);
-    params.maxNameLen = 32;
     nsHandle = NameServer_create(NSNAME, &params);
     if (nsHandle == NULL) {
         printf("Failed to create NameServer '%s'\n", NSNAME);
@@ -233,6 +236,15 @@ again:
         printf("Created NameServer '%s'\n", NSNAME);
     }
 
+    nsHandleAlias = NameServer_create(NSNAME, &params);
+    if (nsHandleAlias == NULL) {
+        printf("Failed to get handle to NameServer '%s'\n", NSNAME);
+        return -1;
+    }
+    else {
+        printf("Got another handle to NameServer '%s'\n", NSNAME);
+    }
+
     NameServer_Params_init(&params);
 
     params.maxValueLen = sizeof(UInt32);
@@ -246,13 +258,36 @@ again:
         printf("Created NameServer '%s'\n", NSNAME2);
     }
 
+    printf("Testing nsHandle\n");
     status = testNS(nsHandle, "Key");
+    if (status != 0) {
+        printf("test failed on nsHandle\n");
+        return status;
+    }
+    printf("Testing nsHandle2\n");
     status = testNS(nsHandle2, "Key");
+    if (status != 0) {
+        printf("test failed on nsHandle2\n");
+        return status;
+    }
 
     printf("Deleting nsHandle and nsHandle2...\n");
     NameServer_delete(&nsHandle);
     NameServer_delete(&nsHandle2);
 
+    /*
+     * Verify that we can still use the alias handle after deleting the
+     * initial handle
+     */
+    printf("Testing nsHandleAlias\n");
+    status = testNS(nsHandleAlias, "Key");
+    if (status != 0) {
+        printf("test failed on nsHandleAlias\n");
+        return status;
+    }
+    printf("Deleting nsHandleAlias...\n");
+    NameServer_delete(&nsHandleAlias);
+
     iteration++;
     if (iteration < 2) {
         goto again;
index 770b2f27651a6512a31a87e7569e50da900d3293..b77929e6d99a19c40794a9701844314b6f6ab1b6 100644 (file)
@@ -263,6 +263,11 @@ Void NameServer_Params_init(NameServer_Params *params);
 /*!
  *  @brief      Creates a NameServer instance
  *
+ *  If NameServer_create() was previously called to create an instance with the
+ *  same name, subsequent calls to NameServer_create() on the same name will
+ *  simply return a valid handle to the existing NameServer instance, similar
+ *  to what is done by NameServer_getHandle().
+ *
  *  @param      name    Instance name
  *  @param      params  Instance param structure
  *
@@ -279,6 +284,10 @@ NameServer_Handle NameServer_create(String name,
  *  If the instance is not empty, the contents is freed back to the
  *  heap it was allocated from.
  *
+ *  If NameServer_create() was called multiple times on the same name,
+ *  a matching number of calls to NameServer_delete() is necessary in
+ *  order to fully deallocate the instance.
+ *
  *  @param      handlePtr  Pointer to a NameServer handle
  *
  *  @return     Status
diff --git a/packages/ti/ipc/tests/NameServerApp.c b/packages/ti/ipc/tests/NameServerApp.c
new file mode 100644 (file)
index 0000000..bb72506
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/* =============================================================================
+ *  @file   NameServerApp.c
+ *
+ *  @brief  Sample application for NameServer module between MPU and Remote Proc
+ *
+ *  ============================================================================
+ */
+
+/* this define must precede inclusion of any xdc header file */
+#define Registry_CURDESC Test__Desc
+#define MODULE_NAME "Server"
+
+/* Standard headers */
+#include <stdio.h>
+
+/* Ipc Standard header */
+#include <xdc/std.h>
+#include <xdc/runtime/Diags.h>
+#include <xdc/runtime/Error.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/System.h>
+#include <xdc/runtime/Assert.h>
+#include <xdc/runtime/Registry.h>
+
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Task.h>
+
+#include <ti/ipc/Ipc.h>
+//#include <_NameServer.h>
+
+/* Module level headers */
+#include <ti/ipc/NameServer.h>
+
+
+/** ============================================================================
+ *  Macros and types
+ *  ============================================================================
+ */
+#define NSNAME "MyNS"
+#define NSNAME2 "MyNS2"
+
+/* private data */
+Registry_Desc               Registry_CURDESC;
+
+Void smain (UArg arg0, UArg arg1);
+
+/** ============================================================================
+ *  Globals
+ *  ============================================================================
+ */
+
+Int testNS(NameServer_Handle nsHandle, String name)
+{
+    Int32 status = 0;
+    Ptr ptr;
+    UInt32 val;
+    char key[16];
+    Int i;
+
+    ptr = NameServer_addUInt32(nsHandle, name, 0xdeadbeef);
+    if (ptr == NULL) {
+        Log_print0(Diags_INFO, "Failed to NameServer_addUInt32()\n");
+        return -1;
+    }
+    else {
+        Log_print1(Diags_INFO, "NameServer_addUInt32() returned %p\n", (IArg)ptr);
+    }
+
+    Log_print0(Diags_INFO, "Trying to add same key (should fail)...\n");
+    ptr = NameServer_addUInt32(nsHandle, name, 0xdeadc0de);
+    if (ptr == NULL) {
+        Log_print0(Diags_INFO, " ...got expected Failure from NameServer_addUInt32()\n");
+    }
+    else {
+        Log_print1(Diags_INFO, "    Error: NameServer_addUInt32() returned non-NULL %p (but was expected to fail)\n", (IArg)ptr);
+        return -1;
+    }
+
+    val = 0x00c0ffee;
+    status = NameServer_getUInt32(nsHandle, name, &val, NULL);
+    Log_print2(Diags_INFO, "NameServer_getUInt32() returned %d, val=0x%x (was 0x00c0ffee)\n", status, val);
+
+    Log_print0(Diags_INFO, "Removing 0xdeadbeef w/ NameServer_remove()...\n");
+    status = NameServer_remove(nsHandle, name);
+    if (status < 0) {
+        Log_print1(Diags_INFO, "NameServer_remove() failed: %d\n", status);
+        return -1;
+    }
+
+    ptr = NameServer_addUInt32(nsHandle, name, 0xdeadc0de);
+    if (ptr == NULL) {
+        Log_print0(Diags_INFO, "Error: NameServer_addUInt32() failed\n");
+        return -1;
+    }
+    else {
+        Log_print0(Diags_INFO, "NameServer_addUInt32(0xdeadc0de) succeeded\n");
+    }
+
+    val = 0x00c0ffee;
+    status = NameServer_getUInt32(nsHandle, name, &val, NULL);
+    Log_print2(Diags_INFO, "NameServer_getUInt32() returned %d, val=0x%x (was 0x00c0ffee)\n", status, val);
+
+    Log_print0(Diags_INFO, "Removing 0xdeadc0de w/ NameServer_removeEntry()...\n");
+    status = NameServer_removeEntry(nsHandle, ptr);
+    if (status < 0) {
+        Log_print1(Diags_INFO, "NameServer_remove() failed: %d\n", status);
+        return -1;
+    }
+
+    ptr = NameServer_addUInt32(nsHandle, name, 0x0badc0de);
+    if (ptr == NULL) {
+        Log_print0(Diags_INFO, "Error: NameServer_addUInt32() failed\n");
+        return -1;
+    }
+    else {
+        Log_print0(Diags_INFO, "NameServer_addUInt32(0x0badc0de) succeeded\n");
+    }
+
+    val = 0x00c0ffee;
+    status = NameServer_getUInt32(nsHandle, name, &val, NULL);
+    Log_print2(Diags_INFO, "NameServer_getUInt32() returned %d, val=0x%x (was 0x00c0ffee)\n", status, val);
+
+    status = NameServer_remove(nsHandle, name);
+    if (status < 0) {
+        Log_print0(Diags_INFO, "Error: NameServer_remove() failed\n");
+        return -1;
+    }
+    else {
+        Log_print1(Diags_INFO, "NameServer_remove(%s) succeeded\n", (IArg)name);
+    }
+
+    for (i = 0; i < 10; i++) {
+        sprintf(key, "foobar%d", i);
+
+        ptr = NameServer_addUInt32(nsHandle, key, 0x0badc0de + i);
+        if (ptr == NULL) {
+            Log_print0(Diags_INFO, "Error: NameServer_addUInt32() failed\n");
+            return -1;
+        }
+        else {
+            Log_print2(Diags_INFO, "NameServer_addUInt32(%s, 0x%x) succeeded\n", (IArg)key, 0x0badc0de + i);
+        }
+
+        val = 0x00c0ffee;
+        status = NameServer_getUInt32(nsHandle, key, &val, NULL);
+        Log_print3(Diags_INFO, "NameServer_getUInt32(%s) returned %d, val=0x%x (was 0x00c0ffee)\n", (IArg)key, status, val);
+
+        if (val != (0x0badc0de + i)) {
+            Log_print2(Diags_INFO, "get val (0x%x) != add val (0x%x)!\n", val, 0x0badc0de + i);
+        }
+    }
+
+    for (i = 0; i < 10; i++) {
+        sprintf(key, "foobar%d", i);
+
+        status = NameServer_remove(nsHandle, key);
+        if (status < 0) {
+            Log_print0(Diags_INFO, "Error: NameServer_remove() failed\n");
+            return -1;
+        }
+        else {
+            Log_print1(Diags_INFO, "NameServer_remove(%s) succeeded\n", (IArg)key);
+        }
+    }
+
+    return 0;
+}
+
+/** ============================================================================
+ *  Functions
+ *  ============================================================================
+ */
+Int
+NameServerApp_startup()
+{
+    Int32 status = 0;
+    NameServer_Params params;
+    NameServer_Handle nsHandle;
+    NameServer_Handle nsHandleAlias;
+    NameServer_Handle nsHandle2;
+    Int iteration = 0;
+
+    Log_print0(Diags_INFO, "Entered NameServerApp_startup\n");
+
+/*    status = Ipc_start();
+
+    if (status < 0) {
+        Log_print1(Diags_INFO, "Ipc_start failed: status = %d\n", status);
+        return -1;
+    }
+*/
+//    Log_print0(Diags_INFO, "Calling NameServer_setup()...\n");
+//    NameServer_setup();
+
+again:
+    NameServer_Params_init(&params);
+
+    params.maxValueLen = sizeof(UInt32);
+    params.maxNameLen = 32;
+
+    Log_print1(Diags_INFO, "params.maxValueLen=%d\n", params.maxValueLen);
+    Log_print1(Diags_INFO, "params.maxNameLen=%d\n", params.maxNameLen);
+    Log_print1(Diags_INFO, "params.checkExisting=%d\n", params.checkExisting);
+
+    nsHandle = NameServer_create(NSNAME, &params);
+    if (nsHandle == NULL) {
+        Log_print1(Diags_INFO, "Failed to create NameServer '%s'\n", (IArg)NSNAME);
+        return -1;
+    }
+    else {
+        Log_print1(Diags_INFO, "Created NameServer '%s'\n", (IArg)NSNAME);
+    }
+
+    nsHandleAlias = NameServer_create(NSNAME, &params);
+    if (nsHandleAlias == NULL) {
+        Log_print1(Diags_INFO, "Failed to get handle to NameServer '%s'\n", (IArg)NSNAME);
+        return -1;
+    }
+    else {
+        Log_print1(Diags_INFO, "Got another handle to NameServer '%s'\n", (IArg)NSNAME);
+    }
+
+    NameServer_Params_init(&params);
+
+    params.maxValueLen = sizeof(UInt32);
+    params.maxNameLen = 32;
+    nsHandle2 = NameServer_create(NSNAME2, &params);
+    if (nsHandle2 == NULL) {
+        Log_print1(Diags_INFO, "Failed to create NameServer '%s'\n", (IArg)NSNAME2);
+        return -1;
+    }
+    else {
+        Log_print1(Diags_INFO, "Created NameServer '%s'\n", (IArg)NSNAME2);
+    }
+
+    Log_print0(Diags_INFO, "Testing nsHandle\n");
+    status = testNS(nsHandle, "Key");
+    if (status != 0) {
+        Log_print0(Diags_INFO, "test failed on nsHandle\n");
+        return status;
+    }
+    Log_print0(Diags_INFO, "Testing nsHandle2\n");
+    status = testNS(nsHandle2, "Key");
+    if (status != 0) {
+        Log_print0(Diags_INFO, "test failed on nsHandle2\n");
+        return status;
+    }
+
+    Log_print0(Diags_INFO, "Deleting nsHandle and nsHandle2...\n");
+    NameServer_delete(&nsHandle);
+    NameServer_delete(&nsHandle2);
+
+    /*
+     * Verify that we can still use the alias handle after deleting the
+     * initial handle
+     */
+    Log_print0(Diags_INFO, "Testing nsHandleAlias\n");
+    status = testNS(nsHandleAlias, "Key");
+    if (status != 0) {
+        Log_print0(Diags_INFO, "test failed on nsHandleAlias\n");
+        return status;
+    }
+    Log_print0(Diags_INFO, "Deleting nsHandleAlias...\n");
+    NameServer_delete(&nsHandleAlias);
+
+    iteration++;
+    if (iteration < 2) {
+        goto again;
+    }
+
+//    Log_print0(Diags_INFO, "Calling NameServer_destroy()...\n");
+//    NameServer_destroy();
+
+    Log_print1(Diags_INFO, "Leaving NameServerApp_startup: status = 0x%x\n", status);
+
+    return status;
+}
+
+
+Int
+NameServerApp_execute()
+{
+    Int32 status = 0;
+
+    Log_print0(Diags_INFO, "Entered NameServerApp_execute\n");
+
+    Log_print0(Diags_INFO, "Leaving NameServerApp_execute\n\n");
+
+    return status;
+}
+
+Int
+NameServerApp_shutdown()
+{
+    Int32 status = 0;
+
+    Log_print0(Diags_INFO, "Entered NameServerApp_shutdown()\n");
+
+/*    status = Ipc_stop();
+    if (status < 0) {
+        Log_print1(Diags_INFO, "Ipc_stop failed: status = %d\n", status);
+    }
+*/
+    Log_print0(Diags_INFO, "Leave NameServerApp_shutdown()\n");
+
+    return status;
+}
+
+Int main(Int argc, Char* argv[])
+{
+    Error_Block     eb;
+    Task_Params     taskParams;
+    Registry_Result result;
+
+    Log_print0(Diags_ENTRY, "--> main:");
+
+    /* must initialize the error block before using it */
+    Error_init(&eb);
+
+    /* create main thread (interrupts not enabled in main on BIOS) */
+    Task_Params_init(&taskParams);
+    taskParams.instance->name = "smain";
+    taskParams.stackSize = 0x1000;
+    Task_create(smain, &taskParams, &eb);
+
+    if (Error_check(&eb)) {
+        System_abort("main: failed to create application startup thread");
+    }
+
+    /* register with xdc.runtime to get a diags mask */
+    result = Registry_addModule(&Registry_CURDESC, MODULE_NAME);
+    Assert_isTrue(result == Registry_SUCCESS, (Assert_Id)NULL);
+
+    /* start scheduler, this never returns */
+    BIOS_start();
+
+    /* should never get here */
+    Log_print0(Diags_EXIT, "<-- main:");
+    return (0);
+}
+
+Void smain (UArg arg0, UArg arg1)
+{
+    int status = 0;
+
+    Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
+
+    /* turn on Diags_INFO trace */
+    Diags_setMask("Server+F");
+
+    status = NameServerApp_startup();
+    if (status < 0) {
+        goto leave;
+    }
+
+    status = NameServerApp_execute();
+    if (status < 0) {
+        goto leave;
+    }
+
+    status = NameServerApp_shutdown();
+    if (status < 0) {
+        goto leave;
+    }
+
+leave:
+    Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
+    return;
+}
index 576c8594c8f4471572c1431827a6f552ef38b244..9abc3d07c891c4851fc626d5a28b675929c218b4 100644 (file)
@@ -529,6 +529,11 @@ for (var i = 0; i < Build.targets.length; i++) {
             defs: "-D BENCHMARK " + extraDefs
         }).addObjects(["messageq_single.c"]);
 
+        /* NameServerApp */
+        Pkg.addExecutable(name + "/NameServerApp", targ, platform, {
+            cfgScript: "rpmsg_transport",
+        }).addObjects(["NameServerApp.c"]);
+
         /* nano_test - demonstrates passing ptrs using CMEM */
         if (platform.match(/^ti\.platforms\.evmOMAPL138\:DSP/)) {
             Pkg.addExecutable(name + "/nano_test", targ, platform, {
index 2f176a23efb7075f55e1040d976571bf0d4a543f..f99fc3249999603503b355e74ac468436d677b6d 100644 (file)
@@ -274,24 +274,43 @@ NameServer_Handle NameServer_create(String name, const NameServer_Params *params
     ti_sdo_utils_NameServer_Params nsParams;
     ti_sdo_utils_NameServer_Object *obj;
     Error_Block eb;
+    NameServer_Handle handle = NULL;
 
     Error_init(&eb);
 
-    if (params != NULL) {
-        /* init the module params struct */
-        ti_sdo_utils_NameServer_Params_init(&nsParams);
-        nsParams.maxRuntimeEntries = params->maxRuntimeEntries;
-        nsParams.tableHeap         = params->tableHeap;
-        nsParams.checkExisting     = params->checkExisting;
-        nsParams.maxValueLen       = params->maxValueLen;
-        nsParams.maxNameLen        = params->maxNameLen;
-
-        /* call the module create */
-        obj = ti_sdo_utils_NameServer_create(name, &nsParams, &eb);
+    /* check if the name is already created or not */
+    handle = NameServer_getHandle(name);
+    if (handle != NULL) {
+        obj = (ti_sdo_utils_NameServer_Object *)handle;
+        if ((obj->numDynamic == params->maxRuntimeEntries) &&
+            (obj->tableHeap == params->tableHeap) &&
+            (obj->checkExisting == params->checkExisting) &&
+            (obj->maxValueLen == params->maxValueLen) &&
+            (obj->maxNameLen == params->maxNameLen)) {
+            obj->refCount++;
+        }
+        else {
+            Error_raise(&eb, ti_sdo_utils_NameServer_E_paramMismatch, name, 0);
+            handle = NULL;
+        }
     }
     else {
-        /* passing in NULL uses the default params */
-        obj = ti_sdo_utils_NameServer_create(name, NULL, &eb);
+        if (params != NULL) {
+            /* init the module params struct */
+            ti_sdo_utils_NameServer_Params_init(&nsParams);
+            nsParams.maxRuntimeEntries = params->maxRuntimeEntries;
+            nsParams.tableHeap         = params->tableHeap;
+            nsParams.checkExisting     = params->checkExisting;
+            nsParams.maxValueLen       = params->maxValueLen;
+            nsParams.maxNameLen        = params->maxNameLen;
+
+            /* call the module create */
+            obj = ti_sdo_utils_NameServer_create(name, &nsParams, &eb);
+        }
+        else {
+            /* passing in NULL uses the default params */
+            obj = ti_sdo_utils_NameServer_create(name, NULL, &eb);
+        }
     }
 
     return ((NameServer_Handle)obj);
@@ -302,8 +321,14 @@ NameServer_Handle NameServer_create(String name, const NameServer_Params *params
  */
 Int NameServer_delete(NameServer_Handle *handlePtr)
 {
-    ti_sdo_utils_NameServer_delete(
-        (ti_sdo_utils_NameServer_Handle *)handlePtr);
+    ti_sdo_utils_NameServer_Object * obj =
+        (ti_sdo_utils_NameServer_Object *)*handlePtr;
+
+    obj->refCount--;
+    if (obj->refCount == 0) {
+        ti_sdo_utils_NameServer_delete(
+            (ti_sdo_utils_NameServer_Handle *)handlePtr);
+    }
 
     return (NameServer_S_SUCCESS);
 }
@@ -614,6 +639,7 @@ Int ti_sdo_utils_NameServer_Instance_init(
     obj->table         = NULL;
     obj->values        = NULL;
     obj->names         = NULL;
+    obj->refCount      = 1;
 
     if (params->tableHeap == NULL) {
         obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
index 4d891b70c99b7741a994ef092dc516f5cc9d481c..cb90ed8d5d24a8931c474d2bef6e44a857071ccd 100644 (file)
@@ -153,6 +153,14 @@ module NameServer
         msg: "E_entryExists: %s name already in table "
     };
 
+    /*!
+     *  Error raised when creation parameters do not match those of an
+     *  existing NameServer
+     */
+    config Error.Id E_paramMismatch  = {
+        msg: "E_paramMismatch: parameters do not match existing NameServer %s "
+    };
+
     /*!
      *  Allow dynamic growth of the NameServer instance table
      *
@@ -482,6 +490,7 @@ internal:
         UInt8        values[];       /* Buffer for values              */
         IHeap.Handle tableHeap;      /* Heap used to alloc table       */
         Bool         checkExisting;  /* check ig name already exists   */
+        UInt32       refCount;       /* reference count to this instance */
     };
 
     struct Module_State {
index c35933720e352c186cbf67a94db3b6f22d7f24cb..ccdcdebc98589a6d22d003909fc3361ec028230d 100644 (file)
@@ -115,6 +115,7 @@ function instance$static$init(obj, name, params)
     obj.numDynamic    = params.maxRuntimeEntries;
     obj.checkExisting = params.checkExisting;
     obj.numStatic     = numStatic;
+    obj.refCount      = 1;
     obj.table.length  = numStatic;
     if (params.tableHeap == null) {
         obj.tableHeap     = NameServer.common$.instanceHeap;
index 210316778a9fc38ab46973c6e14bd15be557b146..c9db723b2b95791cfdfa62b6a32115a8d835a851 100644 (file)
@@ -115,6 +115,7 @@ struct NameServer_Object {
     String             name;            /* name of the instance */
     NameServer_Params  params;          /* the parameter structure */
     UInt32             count;           /* count of entries */
+    UInt32             refCount;        /* reference count to this object */
     pthread_mutex_t    gate;            /* crit sect gate */
 } NameServer_Object;
 
@@ -468,9 +469,16 @@ NameServer_Handle NameServer_create(String name,
     pthread_mutex_lock(&NameServer_module->modGate);
 
     /* check if the name is already created or not */
-    if (NameServer_getHandle(name)) {
-        LOG0("NameServer_create NameServer_E_INVALIDARG Name is in use!\n")
-        handle = NULL;
+    handle = NameServer_getHandle(name);
+    if (handle != NULL) {
+        if (memcmp((Ptr)&handle->params, (Ptr)params,
+            sizeof(NameServer_Params)) == 0) {
+            handle->refCount++;
+        }
+        else {
+            LOG0("NameServer_create: NameServer params mismatch\n")
+            handle = NULL;
+        }
         goto leave;
     }
     else {
@@ -482,6 +490,7 @@ NameServer_Handle NameServer_create(String name,
         goto leave;
     }
 
+    handle->refCount = 1;
     handle->name = (String)malloc(strlen(name) + 1u);
     if (!handle->name) {
         LOG0("NameServer_create: instance name alloc failed\n")
@@ -538,6 +547,11 @@ Int NameServer_delete(NameServer_Handle * handle)
 
     pthread_mutex_lock(&NameServer_module->modGate);
 
+    (*handle)->refCount--;
+    if ((*handle)->refCount != 0) {
+        goto leave;
+    }
+
     if ((*handle)->count == 0) {
         CIRCLEQ_REMOVE(&NameServer_module->objList, *handle, elem);
 
@@ -552,6 +566,7 @@ Int NameServer_delete(NameServer_Handle * handle)
         (*handle) = NULL;
     }
 
+leave:
     pthread_mutex_unlock(&NameServer_module->modGate);
 
     return (status);
index ff05ea47a5b1c1a74a70a4b0a9ab90208aedd655..288251b633681125a4644eda3e2ffb9f01c40dad 100644 (file)
@@ -189,6 +189,7 @@ NameServerApp_startup()
     Int32 status = 0;
     NameServer_Params params;
     NameServer_Handle nsHandle;
+    NameServer_Handle nsHandleAlias;
     NameServer_Handle nsHandle2;
     Int iteration = 0;
 
@@ -206,12 +207,14 @@ NameServerApp_startup()
 
 again:
     NameServer_Params_init(&params);
+
+    params.maxValueLen = sizeof(UInt32);
+    params.maxNameLen = 32;
+
     printf("params.maxValueLen=%d\n", params.maxValueLen);
     printf("params.maxNameLen=%d\n", params.maxNameLen);
     printf("params.checkExisting=%d\n", params.checkExisting);
 
-    params.maxValueLen = sizeof(UInt32);
-    params.maxNameLen = 32;
     nsHandle = NameServer_create(NSNAME, &params);
     if (nsHandle == NULL) {
         printf("Failed to create NameServer '%s'\n", NSNAME);
@@ -221,6 +224,15 @@ again:
         printf("Created NameServer '%s'\n", NSNAME);
     }
 
+    nsHandleAlias = NameServer_create(NSNAME, &params);
+    if (nsHandleAlias == NULL) {
+        printf("Failed to get handle to NameServer '%s'\n", NSNAME);
+        return -1;
+    }
+    else {
+        printf("Got another handle to NameServer '%s'\n", NSNAME);
+    }
+
     NameServer_Params_init(&params);
 
     params.maxValueLen = sizeof(UInt32);
@@ -234,13 +246,36 @@ again:
         printf("Created NameServer '%s'\n", NSNAME2);
     }
 
+    printf("Testing nsHandle\n");
     status = testNS(nsHandle, "Key");
+    if (status != 0) {
+        printf("test failed on nsHandle\n");
+        return status;
+    }
+    printf("Testing nsHandle2\n");
     status = testNS(nsHandle2, "Key");
+    if (status != 0) {
+        printf("test failed on nsHandle2\n");
+        return status;
+    }
 
     printf("Deleting nsHandle and nsHandle2...\n");
     NameServer_delete(&nsHandle);
     NameServer_delete(&nsHandle2);
 
+    /*
+     * Verify that we can still use the alias handle after deleting the
+     * initial handle
+     */
+    printf("Testing nsHandleAlias\n");
+    status = testNS(nsHandleAlias, "Key");
+    if (status != 0) {
+        printf("test failed on nsHandleAlias\n");
+        return status;
+    }
+    printf("Deleting nsHandleAlias...\n");
+    NameServer_delete(&nsHandleAlias);
+
     iteration++;
     if (iteration < 2) {
         goto again;