0

While writing a new vst-plugin using VSTGUI I'm really struggling with how to use the library, and most progress is made from guessing and debugging after (because there really is no documentation besides the million lines and ygrabit, which states little more than the obvious).

So far it's going good, but my last contribution to the project involved threads which made the design a little bit more problematic. Specifically, I'm working on a set of textlabels in a container (doing non-atomic operations) and these may (and obviously does) get destructed without my knowledge, when a user closes the window. Even adding checks right before changing elements might still be a problem. So I actually need to control the lifetime of these objects (which is fine) except when they are shown in a CViewContainer, it automatically assumes ownership.

I have no idea how to write the backbone of the editor, so i used a program called VSTGUIBuilder for this, and appended (and basically rewrote) what i needed. However, since all 'views' you can work with requires either a parent or a systemwindow, you cannot instantiate any views/controls before reaching the AEffEditor::Open() function, which is called whenever your window is popped up. And the AEffEditor::close() method is called whenever the window is closed. Now, the vstguibuilder put a

delete frame;

inside the AEffEditor::close() method which suggests you rebuild and dispense all resources on every open and close. Can this really be true? And if it is, is there no way i can protect my container's contents (which for details is a vector< CTextLabel *>) from getting deleted mid-function? It's no problem to dispose of it afterwards, I'm just worrying about segfaults while changing it.

Using mutexes and the such is really the last resort (if the call is coming from the host), I don't want to hang the host in any case if my code faults and never releases.

Edit: I ended up finding a solution which is not so elegant, but works safely. Here's the code in the worker function:

        while(bLock) {
            Sleep(0);
        }
        bLock = true;

        if(msgs.empty())
            return;

        /*
            Prevent someone deletes our lines in close().
            we create a copy of the container to be 100% sure
            and increase the reference count, so we can safely
            work with our own container and we 'forget' them
            afterwards, so they will be deleted if needed.
            This ensures that close AND open can be called 
            meanwhile we are working with the lines
        */
        bDeleteLock = true;
        // also the copy constructor should work as expected here
        // since we are working with pointers, we still reference the same content.
        auto copy_lines = lines;

        for each(auto line in copy_lines) {
            line->remember();
        }
        bDeleteLock = false;

        ...

        for each(auto line in copy_lines) {
            line->forget();
        }
        cont->setDirty();

bLock is another 'mutex' that protects a message queue, which this function will print out. bDeleteLock protects the process of copying the line container and 'remembering' them, and instantly releases if afterwards. Both are declared as volatile bools, shouldn't that be enough? Here's the close() method btw.

    void CConsole::Close() {
        // locking lines while copying them over in a container we can work with
        while(bDeleteLock)
            Sleep(0);
        //waiting for bLock is not needed because it wont get deleted.
        if(!visible) //if we are not visible it's our responsibility to remove the view
            delete cont;

        lines.clear();

    }
Shaggi
  • 1,121
  • 1
  • 9
  • 31

1 Answers1

0

Ahh, VSTGUI, that brings back some dark memories. ;) But seriously, yes, you will probably have to use a mutex to prevent the host from hanging. Having to instantiate everything when the window reopens seems kind of silly, but you can see many plugins do just that.

One potential workaround is to use a shared memory segment for cached view data, and then pass a reference to the location back to your plugin

Nik Reiman
  • 39,067
  • 29
  • 104
  • 160
  • Yes.. I bet it does. Yeah i ended up locking the data in a basic mutex, you can see the posted solution. I really find the instantiation weird, but I guess it's a way of sparing memory while the window isn't open (at the cost of processing power when opening it). – Shaggi May 29 '13 at 14:02