From 7582fb5ae6073eb6e60ad56802665e9d1fdb69fd Mon Sep 17 00:00:00 2001
From: Oliver Heidmann <oliver.heidmann@mpimet.mpg.de>
Date: Mon, 14 Oct 2024 09:31:29 +0200
Subject: [PATCH] implemented closing of netcdf mem streams

---
 src/cdf.c    |  2 ++
 src/cdi.h    |  1 +
 src/stream.c | 89 ++++++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 75 insertions(+), 17 deletions(-)

diff --git a/src/cdf.c b/src/cdf.c
index f0faf0034..78e7fff9f 100644
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -199,6 +199,8 @@ cdf4Open(const char *filename, const char *mode, int *filetype)
 static void
 cdfCloseFile(int fileID)
 {
+
+  if (CDF_Debug) Message( "Closing cdf file: %d", fileID);
   cdf_close(fileID);
 }
 
diff --git a/src/cdi.h b/src/cdi.h
index 81d67f853..ee46f35aa 100644
--- a/src/cdi.h
+++ b/src/cdi.h
@@ -355,6 +355,7 @@ int     cdiGetProtocol(const char *uri, const char **filename);
 
 int     streamOpenReadNCMem(int ncid);
 int     streamOpenWriteNCMem(int ncid);
+int     streamCloseNCMem(int ncid);
 
 //      streamOpenRead: Open a dataset for reading
 int     streamOpenRead(const char *path);
diff --git a/src/stream.c b/src/stream.c
index cdbc645e4..b26389ed5 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -747,17 +747,6 @@ streamOpenNCMem(int ncidp, char mode)
 
   return streamID;
 }
-
-int
-streamOpenReadNCMem(int ncidp)
-{
-  return streamOpenNCMem(ncidp, 'r');
-}
-int
-streamOpenWriteNCMem(int ncidp)
-{
-  return streamOpenNCMem(ncidp, 'w');
-}
 static int
 streamOpen(const char *filename, const char *filemode, int filetype)
 {
@@ -1274,14 +1263,10 @@ deallocate_sleveltable_t(sleveltable_t *entry)
 }
 
 static void
-streamDestroy(stream_t *streamptr)
+streamDestroyViaDelegate(stream_t *streamptr, void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted))
 {
-  xassert(streamptr);
-  int vlistID = streamptr->vlistID;
-
-  void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
-      = (void (*)(stream_t *, int)) namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
 
+  xassert(streamptr);
   if (streamptr->filetype != CDI_FILETYPE_UNDEF) streamCloseDelegate(streamptr, 1);
 
   if (streamptr->record)
@@ -1337,6 +1322,7 @@ streamDestroy(stream_t *streamptr)
     }
 #endif
 
+  int vlistID = streamptr->vlistID;
   if (vlistID != -1)
     {
       int taxisID = (streamptr->filemode != 'w') ? vlistInqTaxis(vlistID) : -1;
@@ -1351,6 +1337,16 @@ streamDestroy(stream_t *streamptr)
   Free(streamptr);
 }
 
+
+static void
+streamDestroy(stream_t *streamptr)
+{
+  void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
+      = (void (*)(stream_t *, int)) namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+
+  streamDestroyViaDelegate(streamptr, streamCloseDelegate);
+}
+
 static void
 streamDestroyP(void *streamptr)
 {
@@ -2041,6 +2037,65 @@ streamUnpack(char *unpackBuffer, int unpackBufferSize, int *unpackBufferPos, int
   return retval;
 }
 
+
+/* *
+ * This function does not really close the memio,
+ * this has to be done outside cdi to access the memory buffer*/
+void
+freePtrAfterNCMem(stream_t *streamptr, int recordBufIsToBeDeleted)
+{
+  int fileID = streamptr->fileID;
+  int filetype = streamptr->filetype;
+
+  if (fileID == CDI_UNDEFID)
+    {
+      Warning("File %s not open!", streamptr->filename);
+      return;
+    }
+
+  if (streamptr->ntsteps == 0 && streamptr->tsteps != NULL)
+    {
+      if (streamptr->tsteps[0].records)
+        {
+          Free(streamptr->tsteps[0].records);
+          streamptr->tsteps[0].records = NULL;
+        }
+      if (streamptr->tsteps[0].recIDs)
+        {
+          Free(streamptr->tsteps[0].recIDs);
+          streamptr->tsteps[0].recIDs = NULL;
+        }
+    }
+}
+
+
+int
+streamCloseNCMem(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+
+  bool lockIO = streamptr->lockIO;
+  if (lockIO) CDI_IO_LOCK();
+
+  if (CDI_Debug) Message("streamID = %d filename = %s", streamID, streamptr->filename);
+  streamDestroyViaDelegate(streamptr,freePtrAfterNCMem);
+  reshRemove(streamID, &streamOps);
+  if (CDI_Debug) Message("Removed stream %d from stream list", streamID);
+
+  if (lockIO) CDI_IO_UNLOCK();
+}
+
+int
+streamOpenReadNCMem(int ncidp)
+{
+  return streamOpenNCMem(ncidp, 'r');
+}
+int
+streamOpenWriteNCMem(int ncidp)
+{
+  return streamOpenNCMem(ncidp, 'w');
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
-- 
GitLab