From a4e342ea84150a550f2cf9b998706f37190eda6c Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Wed, 27 May 2015 17:02:28 +0200
Subject: [PATCH] Implemented memory free in renaming registry

---
 lib/c/2014/labcomm2014_renaming.h             | 13 +----
 lib/c/2014/labcomm2014_renaming_private.h     | 42 ++++++++++++++
 lib/c/2014/labcomm2014_renaming_registry.c    | 58 +++++++++++++++++--
 .../test/test_labcomm_renaming_registry.c     | 13 ++++-
 4 files changed, 109 insertions(+), 17 deletions(-)
 create mode 100644 lib/c/2014/labcomm2014_renaming_private.h

diff --git a/lib/c/2014/labcomm2014_renaming.h b/lib/c/2014/labcomm2014_renaming.h
index 296e9e1..6ec3d6f 100644
--- a/lib/c/2014/labcomm2014_renaming.h
+++ b/lib/c/2014/labcomm2014_renaming.h
@@ -31,21 +31,12 @@ char *labcomm2014_renaming_prefix(struct labcomm2014_memory *m,
 char *labcomm2014_renaming_suffix(struct labcomm2014_memory *m,
                                   char *name, void *context);
 
-struct labcomm2014_renaming_registry;
 struct labcomm2014_renaming_registry *labcomm2014_renaming_registry_new(
   struct labcomm2014_error_handler *error,
   struct labcomm2014_memory *memory,
   struct labcomm2014_scheduler *scheduler);
 
-/* semi private */
-
-struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
-  struct labcomm2014_renaming_registry *r,
-  const struct labcomm2014_signature *signature,
-  char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
-  void *context);
-
-const struct labcomm2014_signature *labcomm2014_renaming_rename_signature(
-  struct labcomm2014_renaming_rename *rename);
+void labcomm2014_renaming_registry_free(
+  struct labcomm2014_renaming_registry *r);
 
 #endif
diff --git a/lib/c/2014/labcomm2014_renaming_private.h b/lib/c/2014/labcomm2014_renaming_private.h
new file mode 100644
index 0000000..a692677
--- /dev/null
+++ b/lib/c/2014/labcomm2014_renaming_private.h
@@ -0,0 +1,42 @@
+/*
+  labcomm2014_renaming_private.h -- functions intended for renaming
+                                    encoders and decoders
+
+  Copyright 2015 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LABCOMM2014_RENAMING__PRIVATE_H__
+#define __LABCOMM2014_RENAMING_PRIVATE_H__
+
+#include "labcomm2014.h"
+#include "labcomm2014_renaming.h"
+
+struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
+  struct labcomm2014_renaming_registry *r,
+  const struct labcomm2014_signature *signature,
+  char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
+  void *context);
+
+void labcomm2014_renaming_rename_free(
+  struct labcomm2014_renaming_registry *r,
+  struct labcomm2014_renaming_rename *rename);
+
+const struct labcomm2014_signature *labcomm2014_renaming_rename_signature(
+  const struct labcomm2014_renaming_rename *rename);
+
+#endif
diff --git a/lib/c/2014/labcomm2014_renaming_registry.c b/lib/c/2014/labcomm2014_renaming_registry.c
index cbf82f5..dd489e0 100644
--- a/lib/c/2014/labcomm2014_renaming_registry.c
+++ b/lib/c/2014/labcomm2014_renaming_registry.c
@@ -21,6 +21,7 @@
 
 #include "labcomm2014.h"
 #include "labcomm2014_private.h"
+#include "labcomm2014_renaming_private.h"
 
 struct alias {
   int usecount;
@@ -67,6 +68,13 @@ struct labcomm2014_renaming_registry *labcomm2014_renaming_registry_new(
   }
 }
 
+void labcomm2014_renaming_registry_free(
+  struct labcomm2014_renaming_registry *r)
+{
+  LABCOMM_SIGNATURE_ARRAY_FREE(r->memory, r->registry, struct registry *);
+  labcomm2014_memory_free(r->memory, 0, r);
+}
+
 static struct registry *registry_new(
   struct labcomm2014_renaming_registry *r,
   const struct labcomm2014_signature *signature,
@@ -138,10 +146,8 @@ struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
 
       entry = labcomm2014_memory_alloc(r->memory, 0, sizeof(*entry));
       if (entry == NULL) { goto out; }
-      entry->next = NULL;
-      entry->use_count = 0;
-      entry->base = base;
       entry->signature.name = new_name;
+      new_name = NULL;
       entry->signature.encoded_size = signature->encoded_size;
       entry->signature.size = signature->size;
       entry->signature.signature = signature->signature;
@@ -163,6 +169,9 @@ struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
         labcomm2014_memory_free(r->memory, 0, entry);
         goto out;
       } else {
+        entry->next = NULL;
+        entry->use_count = 0;
+        entry->base = base;
         (*l) = entry;
       }
     }
@@ -171,14 +180,53 @@ struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
       result->use_count++;
     }
   out:
-    ;
+    if (new_name != NULL) {
+      labcomm2014_memory_free(r->memory, 0, new_name);
+    }
   }
   labcomm2014_scheduler_data_unlock(r->scheduler);
   return result;
 }
 
-const struct labcomm2014_signature *labcomm2014_renaming_rename_signature(
+void labcomm2014_renaming_rename_free(
+  struct labcomm2014_renaming_registry *r,
   struct labcomm2014_renaming_rename *rename)
+{
+  labcomm2014_scheduler_data_lock(r->scheduler);
+  rename->use_count--;
+  if (rename->use_count == 0) {
+    int index;
+    struct labcomm2014_renaming_rename **l;
+    struct registry **registry;
+
+    for (l = &rename->base->rename ; *l ; l = &(*l)->next) {
+      if (*l == rename) { break; }
+    }
+    *l = rename->next;
+    if (rename->base->rename == NULL) {
+      /* Last use of base signature */
+      index = labcomm2014_get_local_index(rename->base->signature);
+      registry = LABCOMM_SIGNATURE_ARRAY_REF(r->memory, r->registry,
+                                             struct registry *, index);
+      labcomm2014_memory_free(r->memory, 0, *registry);
+      *registry = NULL;
+    }
+    index = labcomm2014_get_local_index(&rename->signature);
+    registry = LABCOMM_SIGNATURE_ARRAY_REF(r->memory, r->registry,
+                                           struct registry *, index);
+    labcomm2014_memory_free(r->memory, 0, *registry);
+    *registry = NULL;
+       
+    /* TODO: We should return the index to the pool*/
+    labcomm2014_memory_free(r->memory, 0, rename->signature.name);
+    labcomm2014_memory_free(r->memory, 0, rename);
+  }
+  labcomm2014_scheduler_data_unlock(r->scheduler);
+
+}
+
+const struct labcomm2014_signature *labcomm2014_renaming_rename_signature(
+  const struct labcomm2014_renaming_rename *rename)
 {
   return &rename->signature;
 }
diff --git a/lib/c/2014/test/test_labcomm_renaming_registry.c b/lib/c/2014/test/test_labcomm_renaming_registry.c
index ded8f6d..2bc0fd3 100644
--- a/lib/c/2014/test/test_labcomm_renaming_registry.c
+++ b/lib/c/2014/test/test_labcomm_renaming_registry.c
@@ -15,7 +15,7 @@
 #include "labcomm2014_renaming.h"
 #include "test/gen/generated_encoding.h"
 
-int main(int argc, char **argv)
+static int do_test(int argc, char **argv)
 {
   struct labcomm2014_renaming_registry *registry;
   struct labcomm2014_renaming_rename *r1, *r2, *r3, *r4;
@@ -41,4 +41,15 @@ int main(int argc, char **argv)
     labcomm2014_renaming_rename_signature(r3),
     labcomm2014_renaming_prefix, "p:");
   assert(r2 == r4);
+  labcomm2014_renaming_rename_free(registry, r1);
+  labcomm2014_renaming_rename_free(registry, r2);
+  labcomm2014_renaming_rename_free(registry, r3);
+  labcomm2014_renaming_rename_free(registry, r4);
+  labcomm2014_renaming_registry_free(registry);
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  return do_test(argc, argv);
 }
-- 
GitLab