0

In matlab, I have a class that ties up a shared resource during construction and releases it when deleted. (In my specific case, the shared resource is a port I can interact with it via http://localhost:1234)

It looks like this:

classdef myClass < handle
    methods
        function myClass()
            OpenExecutableUsingPort1234();
        end
        function delete(this)
            CloseExecutableUsingPort1234();
        end
    end
end

when I use it like this:

instance = myClass();
clear instance;

everything works fine. I open and close it without a problem. But when I use it like this:

instance = myClass();
instance = myClass(); % can't access the port during construction, because it's in use.

I can't start the executable because the port is in use.

The order of events is this:

  1. a first copy of myClass is constructed. there is no problem with ports
  2. the copy is assigned to the 'instance' variable.
  3. a second copy of myClass is constructed. It can't start the executable because the port is in use
  4. the new copy is assigned to the 'instance' variable
  5. the first copy no longer has any references to it, and calls its delete method. This frees up the port.

What kind of workarounds are possible?

Ideally, I'd like step 5 to just know it needs to run early:

  1. a first copy of myClass is constructed. there is no problem with ports
  2. the copy is assigned to the 'instance' variable.

5. the first copy no longer has any references to it, and calls its delete method. This frees up the port.

  1. a second copy of myClass is constructed. the port is free too!
  2. the new copy is assigned to the 'instance' variable
bwall
  • 984
  • 8
  • 22
  • MATLAB doesn’t do garbage collection. It seems to me that you should look for a different architecture altogether. Something like a singleton pattern: https://en.m.wikipedia.org/wiki/Singleton_pattern – Cris Luengo Sep 14 '21 at 23:04
  • 3
    Use `CloseExecutableUsingPort1234 ` in the constructor before calling `OpenExecutableUsingPort1234 `. – rahnema1 Sep 15 '21 at 02:39
  • I think reference counting is a type of garbage collection. That seems to be a common usage of it. – Andrew Janke Sep 18 '21 at 15:16

1 Answers1

1

You have to do a manual clear if you want the old instance to go away before the new instance starts creation.

If you do this:

instance = myClass();
instance = myClass();

The second line calls the myClass constructor before the instance variable gets reassigned, triggering GC on the first instance. It doesn't change instance until the second constructor returns, and it has a new value to put in it. (E.g. if the myClass constructor threw an error, instance should remain unchanged.)

Just stick a clear in there:

instance = myClass;
clear instance
instance = myClass;

(This behavior isn't guaranteed by the Matlab language specification as far as I can tell, but it's how things currently work.)

Example:

classdef Deletable < handle
    
    properties
        id
    end
    
    methods
        
        function this = Deletable
            persistent nextId
            if isempty(nextId)
                nextId = 1;
            end
            this.id = nextId;
            nextId = nextId + 1;
            fprintf('Hello! id=%d\n', this.id);
        end
        
        function delete(this)
            fprintf('Bye bye! id=%d\n', this.id);
        end
        
    end
    
end

function without_clear

instance = Deletable;
instance = Deletable;

end


function with_clear

instance = Deletable;
clear instance
instance = Deletable;

end

Behavior:

>> without_clear
Hello! id=5
Hello! id=6
Bye bye! id=5
Bye bye! id=6
>> 
>> with_clear
Hello! id=7
Bye bye! id=7
Hello! id=8
Bye bye! id=8
>> 

If you really wanted it to work differently, you could write your class so that there can only be one active instance. Hold on to that in a persistent variable in the class definition. When a new instance is created, have it blow away the actual connection in the prior instance. I think that's kinda gross, though.

Or just work with a single Singleton instance of your class, and have its properties be mutable so you can alter its state instead of creating a new instance.

Andrew Janke
  • 23,508
  • 5
  • 56
  • 85
  • "You have to do a manual clear" - That's kind of what I was afraid of. Thank you for your thorough answer! – bwall Sep 21 '21 at 17:41