VFLib & plugin issue


#1

hi,

Here below is the crash I got, which tells me that "calls are being made after the queue is closed, and probably there is no one around to process it."
But I really don’t get what’s going on…

The plugin is simpleDJ, embedded in an introjucer generated plugin.
So what I just added in the introjucer generated code is :

in PluginProcessor.h :

public: ScopedPointer <Mixer> m_mixer;

in PluginProcessor.cpp :

NewProjectAudioProcessor::NewProjectAudioProcessor()
{
    m_mixer = Mixer::New ();
}

in PluginEditor.cpp :

NewProjectAudioProcessorEditor::NewProjectAudioProcessorEditor (NewProjectAudioProcessor* ownerFilter)
    : AudioProcessorEditor (ownerFilter)
{
    CMain* contentComponent = new CMain (*ownerFilter->m_mixer);
    addAndMakeVisible(contentComponent);
    setSize (800, 500);
}

NewProjectAudioProcessorEditor::~NewProjectAudioProcessorEditor()
{
    deleteAllChildren();
}

Everything seems to be ok when I use jule’s pluginHost.
But it crashes when I use my VST in reaper.
everything seems fine at first, I can instantiate many plugins, etc.
The issue appears if I remove all the instantiated plugins and create a new one.
(i.e, to reproduce, I create one instance, remove it, then create a new one).

Any idea what’s going on?


#2

The question, is which queue is getting calls? There are two queues of interest. One is the ManualCallQueue in Mixer. The other is from the vf::MessageThread::getInstance.

Set a breakpoint where the assert goes off and inspect the name field of the call queue in question to figure out which one it is.

Once you find out which queue it is, then you need to set a breakpoint in CallQueue::close and find out why it is getting closed. Most likely you have a threading issue where you are destroying an object containing the call queue, but another thread is trying to put messages on it. You need to have an orderly set of shutdown steps. There are often bugs in destruction of objects in multithreaded systems, this is all perfectly normal. Debugging it will be difficult.


#3

thanks vinnie for your answer.

the name field doesn’t seem to be anything valid when the assert goes off…
I have seen it ‘\x0’, ‘\x17’, or ‘\x06’ (so when I print it, either nothing or ‘¿’)

as well it seems that most of the time I haven’t got that assert, but got an “EXC_BAD_ACCESS” in getPageBytes() in vf_PagedFreeStore.h (l.56).

Any other clue you could give me to debug that?

void CallQueue::queuep (Work* c)
{
  DBG("queue name = "+ m_name);
  jassert (!m_closed.isSignaled ());
...
}

give as last print :


#4

Sounds to me like a thread is accessing a queue after it is deleted.


#5

What I don’t understand is that the first instance of the plugin is ALWAYS running nicely. It’s only when I remove it and create another one that this goes off.
Do you mean that it’s probably due to the host doing something strange, and that I can’t do anything about it?


#6

Do you think it could be related to something like that :

http://www.rawmaterialsoftware.com/viewtopic.php?f=8&t=6879&hilit=Leaked+objects+Thread

where jules says [quote]Because the host is in charge of the event queue, it’s quite possible that the plugin posts one of these messages, and then gets deleted before the event is delivered - so inevitably the event is lost[/quote]


#7

If that was true then AsyncUpdaters would sometimes cause crashes independent of VFLib so no.


#8

Ok. But you think it’s a host-related issue ?
I’m a bit lost here. I don’t really get why I’ve got such a threading issue during the creation of the plugin, but only if I already created and destructed it once. Isn’t it strange I don’t have the issue during the first creation of the plugin ?
sorry for such a naive question, but I’m really new to threading stuff :
Do you think I can do something about that issue then, or is it something I can’t change ?
I would really like to use vflib for my plugs…


#9

If you want to use VFLib you need to write the code yourself, one step at a time, and make sure that each piece works. Trying to take SimpleDJ objects and instantiate them inside your plugin without understanding fully how they work, is probably going to create problems for you. The worst part about it is that you are going from a plugin containing nothing, to a plugin containing a lot of code. You need to build your plugin up incrementally - one step at a time. This way when it breaks, you can narrow your search to the most recent change instead of having to suspect the entire code base.


#10

Ok, I think identified where the issue comes from.

I did a really simple plug, with just the following change from the introjucer created one :

in PluginEditor.h, an inner class :

public:
class Listener
    {
        public:
            virtual void fct () { }
    };

public:
    Listener listener;
    vf::Listeners <Listener> listeners;

in the PluginEditor constructor :

listeners.add (&listener, vf::MessageThread::getInstance ());
listeners.queue1 (&listener, &Listener::fct);

and in the destructor :

It seems there’s a singleton problem with DeletedAtShutdown & the message queue.
When I first instantiate the plugin and then delete it ~MessageThread () is called and the queue is closed.
Then, when I create a new instance of the plugin, MessageThread::getInstance () return me the same queue, which is closed.


#11

[quote=“lalala”]It seems there’s a singleton problem with DeletedAtShutdown & the message queue.
When I first instantiate the plugin and then delete it ~MessageThread () is called and the queue is closed.
Then, when I create a new instance of the plugin, MessageThread::getInstance () return me the same queue, which is closed.[/quote]

Okay, good job narrowing this down.

What does DeletedAtShutdown have to do with any of this? Why is the destructor for MessageThread getting called? That should only be called if your DLL is unloaded (I think).


#12

Hum. don’t forget i’m a newb :slight_smile:

the MessageThread destructor is getting called because MessageThread inherits DeletedAtShutdown, and it seems the normal behaviour that DeletedAtShutdown is getting called when all the plugins instances are deleted :

Singletons and DeletedAtShutdown : http://www.rawmaterialsoftware.com/viewtopic.php?f=2&t=7491
Singleton && DeletedAtShutdown Class in Plug-In : http://www.rawmaterialsoftware.com/viewtopic.php?f=8&t=4733


#13

Jules can you point me towards a clearer picture of this problem? I have not worked with DLLs at all…


#14

First, I didn’t reproduce the problem. Seems I am too stupid to debug a vst plugin using Visual Studio :wink:

But I gathered so much that using static objects are not a good idea when using dlls. So maybe you can side step the problem: Try using a vf::GuiCallQueue instead of the vf::MessageThread.


#15

I wouldn’t use DeletedAtShutdown in a Plugin, because there isn’t is a classic “shutdown” in plugin environments, it depends all on the host.

Better use ref-counted objects or just open an instance of what you need for any of your plugin.


#16

I’d agree with chkn - best to avoid DeletedAtShutdown in a plugin. It should work, being called when shutdownJuce_GUI() is called, which should happen when all your plugin instances are deleted, or before the DLL is unloaded, but hosts can be unpredictable.

Something I keep meaning to create but never quite get around to is a ref-counted singleton… That’d be handy in this kind of circumstance.


#17

For lalala’s specific problem this means using a vf::GuiCallQueue instead of the vf::MessageThread.


#18

You mean like vf::RefCountedSingleton<>?

:lol: :lol: :smiley:


#19

thanks all for your comments!
So to conclude I should use a RefCountedSingleton instead of MessageThread, is that right ?


#20

[quote=“lalala”]thanks all for your comments!
So to conclude I should use a RefCountedSingleton instead of MessageThread, is that right ?[/quote]

Try it and see ^^

Actually, I don’t think it even needs to be that complicated. Just make GuiCallQueue a member of one of your long lived classes (like the plugin instance for example). You can have more than one GuiCallQueue in your plugin, it doesn’t need to be any sort of singleton.