I have seen CriticalSection/ScopedLock not working issue - #7 by xsd121, and there it is mentioned:
It looks like what I questioned earlier. Your
code shows each thread having it’s own critical section which will do
nothing. The threads need to act on the same CriticalSection instance.e.g. (something to this effect)
CriticalSection cs; //the single critical section used by all the threads CSTrial cst1 (cs); //pass the critical section to cst1 CSTrial cst2 (cs); //pass the same critical section to cst2
Ok, so I tried to implement this: I created a new GUI application in Projucer, and then used the following code:
MainComponent.h
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainContentComponent : public Component
{
public:
//==============================================================================
MainContentComponent();
~MainContentComponent();
void paint (Graphics&) override;
void resized() override;
CriticalSection maincs;
private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
#endif // MAINCOMPONENT_H_INCLUDED
MainComponent.cpp
#include "MainComponent.h"
// if you comment this define, compilation succeeds:
#define PASSCS
static int counter = 0;
class CSTrial : public Thread
{
public:
#ifndef PASSCS
CSTrial(): Thread("CS Trial " + String(++counter)) //OK
#else
CSTrial(CriticalSection incs): Thread("CS Trial " + String(++counter)),
cs(incs)
#endif
{
id = counter;
startThread(1);
}
~CSTrial()
{
signalThreadShouldExit();
waitForThreadToExit(-1);
}
//@override
void run()
{
const ScopedLock sl(cs);
doStuff();
sleep(500);
std::cerr << id << ": about to end run()\n";
}
void doStuff()
{
std::cerr << id << ": do Stuff\n";
}
CriticalSection cs;
int id;
};
//==============================================================================
MainContentComponent::MainContentComponent()
{
setSize (600, 400);
#ifndef PASSCS
CSTrial cst1; //ok
CSTrial cst2; //ok
#else
CSTrial cst1(maincs);
CSTrial cst2(maincs);
#endif
}
MainContentComponent::~MainContentComponent()
{
}
void MainContentComponent::paint (Graphics& g)
{
g.fillAll (Colour (0xff001F36));
g.setFont (Font (16.0f));
g.setColour (Colours::white);
g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);
}
void MainContentComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}
So, here if the PASSCS
is not defined (#define PASSCS
is commented), then everything compiles, however, the critical section locking doesn’t work, as in the original posting.
If PASSCS
is defined (#define PASSCS
is not commented), then I cannot compile, getting this compilation error:
Compiling MainComponent.cpp
In file included from ../../../../modules/juce_core/system/juce_StandardHeader.h:65:0,
from ../../../../modules/juce_core/juce_core.h:182,
from ../../../../modules/juce_audio_basics/juce_audio_basics.h:60,
from ../../Source/../JuceLibraryCode/JuceHeader.h:18,
from ../../Source/MainComponent.h:12,
from ../../Source/MainComponent.cpp:9:
../../../../modules/juce_core/threads/juce_CriticalSection.h: In constructor ‘CSTrial::CSTrial(juce::CriticalSection)’:
../../../../modules/juce_core/threads/juce_CriticalSection.h:124:32: error: ‘juce::CriticalSection::CriticalSection(const juce::CriticalSection&)’ is private
JUCE_DECLARE_NON_COPYABLE (CriticalSection)
^
../../../../modules/juce_core/system/juce_PlatformDefs.h:224:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
className (const className&) JUCE_DELETED_FUNCTION;\
^
../../Source/MainComponent.cpp:22:44: error: within this context
cs(incs)
^
../../Source/MainComponent.cpp:22:44: error: use of deleted function ‘juce::CriticalSection::CriticalSection(const juce::CriticalSection&)’
In file included from ../../../../modules/juce_core/system/juce_StandardHeader.h:65:0,
from ../../../../modules/juce_core/juce_core.h:182,
from ../../../../modules/juce_audio_basics/juce_audio_basics.h:60,
from ../../Source/../JuceLibraryCode/JuceHeader.h:18,
from ../../Source/MainComponent.h:12,
from ../../Source/MainComponent.cpp:9:
../../../../modules/juce_core/threads/juce_CriticalSection.h:124:32: error: declared here
JUCE_DECLARE_NON_COPYABLE (CriticalSection)
^
../../../../modules/juce_core/system/juce_PlatformDefs.h:224:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
className (const className&) JUCE_DELETED_FUNCTION;\
^
../../../../modules/juce_core/threads/juce_CriticalSection.h: In constructor ‘MainContentComponent::MainContentComponent()’:
../../../../modules/juce_core/threads/juce_CriticalSection.h:124:32: error: ‘juce::CriticalSection::CriticalSection(const juce::CriticalSection&)’ is private
JUCE_DECLARE_NON_COPYABLE (CriticalSection)
^
../../../../modules/juce_core/system/juce_PlatformDefs.h:224:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
className (const className&) JUCE_DELETED_FUNCTION;\
^
../../Source/MainComponent.cpp:57:24: error: within this context
CSTrial cst1(maincs);
^
../../Source/MainComponent.cpp:57:24: error: use of deleted function ‘juce::CriticalSection::CriticalSection(const juce::CriticalSection&)’
In file included from ../../../../modules/juce_core/system/juce_StandardHeader.h:65:0,
from ../../../../modules/juce_core/juce_core.h:182,
from ../../../../modules/juce_audio_basics/juce_audio_basics.h:60,
from ../../Source/../JuceLibraryCode/JuceHeader.h:18,
from ../../Source/MainComponent.h:12,
from ../../Source/MainComponent.cpp:9:
../../../../modules/juce_core/threads/juce_CriticalSection.h:124:32: error: declared here
JUCE_DECLARE_NON_COPYABLE (CriticalSection)
^
../../../../modules/juce_core/system/juce_PlatformDefs.h:224:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
className (const className&) JUCE_DELETED_FUNCTION;\
^
../../Source/MainComponent.cpp:21:5: error: initializing argument 1 of ‘CSTrial::CSTrial(juce::CriticalSection)’
CSTrial(CriticalSection incs): Thread("CS Trial " + String(++counter)),
^
In file included from ../../../../modules/juce_core/system/juce_StandardHeader.h:65:0,
from ../../../../modules/juce_core/juce_core.h:182,
from ../../../../modules/juce_audio_basics/juce_audio_basics.h:60,
from ../../Source/../JuceLibraryCode/JuceHeader.h:18,
from ../../Source/MainComponent.h:12,
from ../../Source/MainComponent.cpp:9:
../../../../modules/juce_core/threads/juce_CriticalSection.h:124:32: error: ‘juce::CriticalSection::CriticalSection(const juce::CriticalSection&)’ is private
JUCE_DECLARE_NON_COPYABLE (CriticalSection)
^
../../../../modules/juce_core/system/juce_PlatformDefs.h:224:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
className (const className&) JUCE_DELETED_FUNCTION;\
^
../../Source/MainComponent.cpp:58:24: error: within this context
CSTrial cst2(maincs);
^
../../Source/MainComponent.cpp:58:24: error: use of deleted function ‘juce::CriticalSection::CriticalSection(const juce::CriticalSection&)’
In file included from ../../../../modules/juce_core/system/juce_StandardHeader.h:65:0,
from ../../../../modules/juce_core/juce_core.h:182,
from ../../../../modules/juce_audio_basics/juce_audio_basics.h:60,
from ../../Source/../JuceLibraryCode/JuceHeader.h:18,
from ../../Source/MainComponent.h:12,
from ../../Source/MainComponent.cpp:9:
../../../../modules/juce_core/threads/juce_CriticalSection.h:124:32: error: declared here
JUCE_DECLARE_NON_COPYABLE (CriticalSection)
^
../../../../modules/juce_core/system/juce_PlatformDefs.h:224:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
className (const className&) JUCE_DELETED_FUNCTION;\
^
../../Source/MainComponent.cpp:21:5: error: initializing argument 1 of ‘CSTrial::CSTrial(juce::CriticalSection)’
CSTrial(CriticalSection incs): Thread("CS Trial " + String(++counter)),
^
make: *** [build/intermediate/Debug/MainComponent_a6ffb4a5.o] Error 1
This is on Linux (Ubuntu 14.04).
So, apparently I cannot pass a CriticalSection, as noted in the original post? Or can I, and I simply don’t know how to do it? In my case, I’d want to synchronize code parts that reside in two different components, which is why I’d need to create one CriticalSection on MainComponent level, and then pass it to the “child” classes that need the code synchronized. How do I do that?
Unfortunately, it seems there is no example for this “passing” anywhere in ./examples or ./extras, which is why I need to ask this question in the first place - if I have missed the example, kindly point me to it…