Background: I'm experimenting with the file format, HDF5. In my code I open/create multiple objects, which need to be close in a specific order. The file itself shall be closed last. Not closing objects at run time errors during debugging causes problems. Thus, I use onCleanup, which in turn might cause problems by closing the object is the wrong order.
In the code every create/open is followed by a onCleanup
file_id = H5F.open( file_spec, 'H5F_ACC_RDWR', 'H5P_DEFAULT' ); file_id_c = onCleanup( @()H5F.close( file_id ) );.
Question: Is it defined in which order onCleanup callbacks are executed? Is there a good way to control that order? Do I need to put all "close" in one callback function and only have one onCleanup?
— Part 2 —
I done a test, which shows that the onCleanup callbacks are executed in the same order as they were defined. The other way round is needed to be useful with HDF5.
Furthermore, I learned that one must honor the rules on creating and closing the hdf-objects. I have seen strange performance degradation, which disappeared when I closed the objects correctly.
I need a onCleanup functionality to close the objects during debugging. It happens I click dbquit by mistake.
Now I have a code that I believe does what I intend it to do (see below). It includes a class, H5_on_clean_up. First, I tried make a simpler function, which included the line "persistent job_list". However, I failed to make that work.
Question: Is my solution more complicated than needed?
Excerpts from my function, which reads a hdf-file.
on_clean_up = H5_on_clean_up(); % see class definition below
.... code for ii = 1 : n_qty ... code clean_up_guard = onCleanup( @()doit(on_clean_up) ); on_clean_up.reset() ... code dataset_id = H5D.open( file_id, sprintf( '/%s', data_set_name ) ); on_clean_up.add( @()H5D.close( dataset_id ), 'late' ); ... code mem_type_id = H5D.get_type( dataset_id ); on_clean_up.add( @()H5T.close( mem_type_id ), 'early' ); ... code clear('clean_up_guard') % clear is needed because of the loop
end ... code end % end of file
.. classdef H5_on_clean_up < handle % H5_on_clean_up - Helper to close hdf5 objects in the correct order
%
properties job_list = cell(0); end methods function add( this, foo, str ) switch str case 'early' this.job_list = cat( 2, {foo}, this.job_list ); case 'late' this.job_list = cat( 2, this.job_list, {foo} ); otherwise error( 'C:B', 'error: %s', str ) end end function reset( this ) this.job_list = cell(0); end function doit( this ) for f = this.job_list feval( f{:} ); end end end end
.
— Part 3 —
The Tech Support send me this little demo today. It is a significant improvement compared to my construct above.
>> on_clean_up_test c a b
where
function on_clean_up_test % Have one single vector of clean-up functions
% Start with a
c = onCleanup( @()disp('a')); % Add b to the end
c = [c, onCleanup( @()disp('b'))]; % Add c to the front
c = [onCleanup( @()disp('c')), c]; end
Best Answer