MATLAB: Order of execution of multiple onCleanup callbacks

classhdf5MATLABoncleanup

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

While I believe the ordering is stable and either first defined or last defined (I cannot remember), I don't think you want to depend on this. Since the opening/closing order matters, I would make a single function/object that handles it.