Skip to content

Commit 0c64331

Browse files
committed
dat1Reopen: Ensure all ids for a file are closed before trying to reopen it
This uses code factored out of dat1Annul into new function dat1CloseAllIds.c
1 parent e9b4a01 commit 0c64331

File tree

5 files changed

+170
-102
lines changed

5 files changed

+170
-102
lines changed

Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ hdsgroups.c
142142
PRIVATE_C_ROUTINES = \
143143
dat1AllocLoc.c \
144144
dat1Annul.c \
145+
dat1CloseAllIds.c \
145146
dat1Coords2CellName.c \
146147
dat1CreateStructureCell.c \
147148
dat1CvtChar.c \

dat1.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ hdsbool_t hds1GetLockCheck();
453453
hds_shell_t hds1GetShell();
454454

455455
int dat1Annul( HDSLoc *locator, int * status );
456-
457456
hid_t dat1GetParentID( hid_t objid, hdsbool_t allow_root, int *status );
457+
int dat1CloseAllIds( hid_t file_id, int* status );
458458

459459
int
460460
dat1GetStructureDims( const HDSLoc * locator, int maxdims, hdsdim dims[], int *status );

dat1Annul.c

+3-71
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@
6666
* Re-written to avoid recursive calls to this function from within
6767
* hds1UnregLocator.
6868
* 2020-09-11 (DSB):
69-
* When the last primary locator is annulled, close all HDF5
70-
* identifiers associated with the file, not just the file identifier
69+
* When the last primary locator is annulled, close all HDF5
70+
* identifiers associated with the file, not just the file identifier
7171
* in the supplied locator.
7272
* {enter_further_changes_here}
7373
@@ -115,19 +115,13 @@ static void dat1Anloc( HDSLoc *locator, int * status );
115115
int dat1Annul( HDSLoc *locator, int * status ) {
116116

117117
/* Local Variables: */
118-
H5I_type_t objtype;
119118
HDSLoc *loc = NULL;
120119
Handle *tophandle = NULL;
121120
HdsFile *context = NULL;
122121
HdsFile *hdsFile = NULL;
123-
herr_t herr;
124-
hid_t *objs;
125122
hid_t file_id = 0;
126123
int erase = 0;
127124
int errstat = 0;
128-
int howmany;
129-
int i;
130-
ssize_t cnt;
131125

132126
/* Return if a null locator is supplied, but do not check the inherited
133127
status. */
@@ -174,69 +168,7 @@ int dat1Annul( HDSLoc *locator, int * status ) {
174168
dat1Anloc( locator, status );
175169

176170
/* If required, close all HDF5 identifiers associated with the file. */
177-
if( file_id ) {
178-
179-
/* Get the number of active HDF5 identifiers of any type associated with
180-
the file. */
181-
cnt = H5Fget_obj_count( file_id, H5F_OBJ_ALL );
182-
183-
/* There should always be at least one active identifier (the supplied
184-
file identifier). */
185-
if( cnt == 0 ) {
186-
*status = DAT__FATAL;
187-
emsRepf( " ", "dat1Annul: No active HDF5 idenfifiers for supplied file.",
188-
status );
189-
190-
/* Alocate an array to hold the active identifiers then store the active
191-
identifiers in it. */
192-
} else {
193-
objs = MEM_CALLOC( cnt, sizeof(hid_t) );
194-
if( objs ) {
195-
howmany = H5Fget_obj_ids( file_id, H5F_OBJ_ALL, cnt, objs );
196-
197-
/* Loop round closing each one, except for the supplied file identifier. */
198-
for( i = 0; i < howmany; i++ ) {
199-
if( objs[i] != file_id ){
200-
objtype = H5Iget_type( objs[i] );
201-
if ( objtype == H5I_FILE ) {
202-
herr = H5Fclose( objs[i] );
203-
} else if ( objtype == H5I_GROUP || objtype == H5I_DATASET ) {
204-
herr = H5Oclose( objs[i] );
205-
} else if ( objtype == H5I_DATASPACE ) {
206-
herr = H5Dclose( objs[i] );
207-
} else if( *status == SAI__OK ){
208-
herr = 0;
209-
*status = DAT__FATAL;
210-
emsRepf( " ", "dat1Annul: Cannot close HDF5 idenfifier - wrong type.",
211-
status );
212-
}
213-
214-
if( herr < 0 && *status == SAI__OK ){
215-
*status = DAT__FATAL;
216-
dat1H5EtoEMS( status );
217-
emsRepf( " ", "dat1Annul: Cannot close HDF5 idenfifier.",
218-
status );
219-
}
220-
}
221-
}
222-
223-
/* Free the memory allocated above. */
224-
MEM_FREE( objs );
225-
}
226-
}
227-
228-
/* Close the supplied file id. */
229-
if( H5Fclose( file_id ) < 0 && *status == SAI__OK ){
230-
*status = DAT__FATAL;
231-
dat1H5EtoEMS( status );
232-
if( hdsFile && hdsFile->path ) {
233-
emsRepf( " ", "dat1Annul: Failed to close file '%s'.",
234-
status, hdsFile->path );
235-
} else {
236-
emsRepf( " ", "dat1Annul: Failed to close file.", status );
237-
}
238-
}
239-
}
171+
if( file_id ) dat1CloseAllIds( file_id, status );
240172

241173
/* If required, delete the file. */
242174
if( erase && hdsFile && hdsFile->path ) {

dat1CloseAllIds.c

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
*+
3+
* Name:
4+
* dat1CloseAllIds
5+
6+
* Purpose:
7+
* Close all HDF5 identifiers associated with a given file id.
8+
9+
* Language:
10+
* Starlink ANSI C
11+
12+
* Type of Module:
13+
* Library routine
14+
15+
* Invocation:
16+
* dat1CloseAllIds( hid_t file_id, int * status );
17+
18+
* Arguments:
19+
* file_id = hid_t (Given)
20+
* The file id containing the objects t be closed.
21+
* status = int* (Given and Returned)
22+
* Pointer to global status. Attempts to run even if status is bad.
23+
24+
* Description:
25+
* Close all HDF5 object identifiers currently associated with a file,
26+
* either throught the supplied file id or some other file id. All
27+
* file ids associated with the file (inclusing the supplied file id) are
28+
* also closed.
29+
30+
* Authors:
31+
* DSB: David S Berry (EAO)
32+
* {enter_new_authors_here}
33+
34+
* Notes:
35+
* - This routine attempts to execute even if status is set on entry,
36+
* although no further error report will be made if it subsequently
37+
* fails under these circumstances.
38+
39+
* History:
40+
* 2020-10-13 (DSB):
41+
* Initial version
42+
* {enter_further_changes_here}
43+
44+
* Copyright:
45+
* Copyright (C) 2020 East Asian Observatory
46+
* All Rights Reserved.
47+
48+
* Licence:
49+
* This program is free software; you can redistribute it and/or
50+
* modify it under the terms of the GNU General Public License as
51+
* published by the Free Software Foundation; either version 3 of
52+
* the License, or (at your option) any later version.
53+
*
54+
* This program is distributed in the hope that it will be
55+
* useful, but WITHOUT ANY WARRANTY; without even the implied
56+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
57+
* PURPOSE. See the GNU General Public License for more details.
58+
*
59+
* You should have received a copy of the GNU General Public License
60+
* along with this program; if not, write to the Free Software
61+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
62+
* MA 02110-1301, USA.
63+
64+
* Bugs:
65+
* {note_any_bugs_here}
66+
*-
67+
*/
68+
69+
70+
#include "hdf5.h"
71+
#include "sae_par.h"
72+
#include "ems.h"
73+
#include "hds1.h"
74+
#include "dat1.h"
75+
#include "dat_err.h"
76+
#include "hds.h"
77+
78+
int dat1CloseAllIds( hid_t file_id, int * status ){
79+
80+
/* Local Variables: */
81+
H5I_type_t objtype;
82+
HdsFile *hdsFile = NULL;
83+
herr_t herr;
84+
hid_t *objs;
85+
int howmany;
86+
int i;
87+
ssize_t cnt;
88+
89+
/* Return if a null file_id is supplied, but do not check the inherited
90+
status. */
91+
if( file_id <= 0 ) return *status;
92+
93+
/* Begin an entirely new error context as we need to run this
94+
regardless of external errors */
95+
emsBegin( status );
96+
97+
/* Get the number of active HDF5 identifiers of any type associated with
98+
the file. */
99+
cnt = H5Fget_obj_count( file_id, H5F_OBJ_ALL );
100+
101+
/* There should always be at least one active identifier (the supplied
102+
file identifier). */
103+
if( cnt == 0 ) {
104+
*status = DAT__FATAL;
105+
emsRepf( " ", "dat1CloseAllIds: No active HDF5 idenfifiers for supplied file.",
106+
status );
107+
108+
/* Alocate an array to hold the active identifiers then store the active
109+
identifiers in it. */
110+
} else {
111+
objs = MEM_CALLOC( cnt, sizeof(hid_t) );
112+
if( objs ) {
113+
howmany = H5Fget_obj_ids( file_id, H5F_OBJ_ALL, cnt, objs );
114+
115+
/* Loop round closing each one, except for the supplied file identifier. */
116+
for( i = 0; i < howmany; i++ ) {
117+
if( objs[i] != file_id ){
118+
objtype = H5Iget_type( objs[i] );
119+
if ( objtype == H5I_FILE ) {
120+
herr = H5Fclose( objs[i] );
121+
} else if ( objtype == H5I_GROUP || objtype == H5I_DATASET ) {
122+
herr = H5Oclose( objs[i] );
123+
} else if ( objtype == H5I_DATASPACE ) {
124+
herr = H5Dclose( objs[i] );
125+
} else if( *status == SAI__OK ){
126+
herr = 0;
127+
*status = DAT__FATAL;
128+
emsRepf( " ", "dat1CloseAllIds: Cannot close HDF5 idenfifier - wrong type.",
129+
status );
130+
}
131+
132+
if( herr < 0 && *status == SAI__OK ){
133+
*status = DAT__FATAL;
134+
dat1H5EtoEMS( status );
135+
emsRepf( " ", "dat1CloseAllIds: Cannot close HDF5 idenfifier.",
136+
status );
137+
}
138+
}
139+
}
140+
141+
/* Free the memory allocated above. */
142+
MEM_FREE( objs );
143+
}
144+
}
145+
146+
/* Close the supplied file id. */
147+
if( H5Fclose( file_id ) < 0 && *status == SAI__OK ){
148+
*status = DAT__FATAL;
149+
dat1H5EtoEMS( status );
150+
if( hdsFile && hdsFile->path ) {
151+
emsRepf( " ", "dat1CloseAllIds: Failed to close file '%s'.",
152+
status, hdsFile->path );
153+
} else {
154+
emsRepf( " ", "dat1CloseAllIds: Failed to close file.", status );
155+
}
156+
}
157+
158+
/* End the error context and return the final status */
159+
emsEnd( status );
160+
161+
return *status;
162+
}
163+

dat1Reopen.c

+2-30
Original file line numberDiff line numberDiff line change
@@ -177,36 +177,8 @@ hid_t dat1Reopen( hid_t file_id, unsigned int flags, hid_t fapl,
177177
/* Get the path for the file. */
178178
H5Fget_name( file_id, path, sizeof(path) );
179179

180-
/* Close all HDF5 file_ids associated with file. */
181-
if( *status == SAI__OK ) {
182-
int this_closed = 0;
183-
184-
if( file_ids ) {
185-
int i = -1;
186-
while( file_ids[ ++i ] ) {
187-
188-
if( file_ids[ i ] == file_id ) this_closed = 1;
189-
190-
if( H5Fclose( file_ids[ i ] ) < 0 ) {
191-
*status = DAT__FATAL;
192-
dat1H5EtoEMS( status );
193-
emsRepf( " ", "hdsOpen: Failed to close file '%s' prior to "
194-
"re-opening it.", status, path );
195-
break;
196-
}
197-
}
198-
}
199-
200-
/* Close the supplied file_id if it has not already been closed. */
201-
if( !this_closed ) {
202-
if( H5Fclose( file_id ) < 0 ) {
203-
*status = DAT__FATAL;
204-
dat1H5EtoEMS( status );
205-
emsRepf( " ", "hdsOpen: Failed to close file '%s' prior to "
206-
"re-opening it.", status, path );
207-
}
208-
}
209-
}
180+
/* Close all remaining HDF5 file_ids and objects associated with file. */
181+
dat1CloseAllIds( file_id, status );
210182

211183
/* Re-open it. */
212184
if( *status == SAI__OK ) {

0 commit comments

Comments
 (0)