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

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit:

Order of execution of multiple onCleanup callbacks

Asked by per isakson on 22 May 2012

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


1 Answer

Answer by Daniel 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.



Contact us