Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

New to MATLAB?

Order of execution of multiple onCleanup callbacks

Asked by per isakson

per isakson (view profile)

on 22 May 2012
Accepted Answer by Daniel

Daniel (view profile)

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   = 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) );
    	... code
    	dataset_id = 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
    ... code
    end % end of file
    classdef    H5_on_clean_up  < handle
    %H5_on_clean_up - Helper to close hdf5 objects in the correct order
            job_list    = cell(0);
            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} );
                        error( 'C:B', 'error: %s', str )
            function    reset( this )
                this.job_list = cell(0);
            function    doit( this )
                for f = this.job_list
                    feval( f{:} );


--- 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


    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];


per isakson

per isakson (view profile)


1 Answer

Answer by Daniel

Daniel (view profile)

on 23 May 2012
Accepted 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.



Daniel (view profile)

Contact us