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

on 22 May 2012
Accepted Answer by Daniel

Daniel

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

0 Comments

per isakson

per isakson

Products

1 Answer

Answer by Daniel

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.

0 Comments

Daniel

Daniel

Contact us