Order of execution of multiple onCleanup callbacks

3 views (last 30 days)
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

Accepted Answer

Daniel Shub
Daniel Shub on 23 May 2012
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.
  1 Comment
Adam Danz
Adam Danz on 4 Feb 2021
From the documentation (years after this answer)
If your program contains multiple cleanup objects, MATLAB does not guarantee the order that it destroys these objects. If the order of your cleanup functions matters, define one onCleanup object for all the tasks.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!