NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.

To learn about what's going on, see About the Archive Site.

Re: [netcdfgroup] Bug in nc4file.c

 Hello,

Here is a patch which corrects the problem.
May be it is not the better way but it works (except for a program which
opens more than 65536 files à the same time: infinite loop in the
function added).

Expecting this will help,
regards,
Philippe.

Le 30/09/2010 14:56, Philippe Poilbarbe a écrit :
>  Hello,
>
> I think I have found a bug in nc4file.c of NetCDF version 4.1.1.
>
> It is the way the external file id is created (in nc_open_file and
> nc_create_file functions).
> The formula to obtain a new external file id (the one seen by programs
> calling the library NetCDF) is:
>     ++last_file_id << ID_SHIFT
> where last_file_id is initialized with 0.
>
> The problem comes when a program open/close many files, the external ids
> are not reused so last_file_id grows each time a nc_open or nc_create is
> called.
>
> When last_file_id reaches 65536, the external file id is 0 (65536
> ...
> As a solution, maybe the external file handle should be reused (as in
> necdf3) or, which may be simpler, the formula "++last_file_id <<
> ID_SHIFT" may be evaluated while the returned number is already in use.
>
> Philippe.
>
--- libsrc4/nc4file.c.orig      2010-09-30 15:09:23.000000000 +0200
+++ libsrc4/nc4file.c   2010-09-30 16:14:17.000000000 +0200
@@ -75,6 +75,27 @@
 
 int nc4_free_global_hdf_string_typeid();
 
+/* Find a valid external file id
+ */
+static int
+find_free_external_file_id (void)
+{
+    int check;
+    int limit; /* to avoid infinite loop */
+
+    /* NOTE: Possibility of infinite loop if 65536 files
+     *       are simultaneously opened */
+    while (1)
+    {
+       check   = (++last_file_id << ID_SHIFT);
+       if (! nc4_find_nc_file(check))
+       {
+           return check;
+       }
+    }
+}
+
+
 /* Set chunk cache size. Only affects files opened/created *after* it
  * is called.  */
 int
@@ -351,7 +372,7 @@
    /* Allocate the storage for this file info struct, and fill it with
       zeros. This add the file metadata to the front of the global
       nc_file list. */
-   if ((res = nc4_file_list_add((++last_file_id << ID_SHIFT))))
+   if ((res = nc4_file_list_add(find_free_external_file_id())))
       return res;
 
    /* Apply default create format. */
@@ -2295,7 +2316,7 @@
 
    /* Allocate the storage for this file info struct, and fill it with
       zeros. */
-   if ((res = nc4_file_list_add(++last_file_id << ID_SHIFT)))
+   if ((res = nc4_file_list_add(find_free_external_file_id())))
       return res;
 
    /* Depending on the type of file, open it. */
  • 2010 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: