So, I have the following two functions in THE SAME class:
void start()
{
...
m_pRunnable = createRunnable(
[spDiskManager = m_spDiskManager,
path = m_path,
&success = m_isFolderCreated]() {
success = spDiskManager->createDirectory(path);
});
m_spWorkThread->invokeWithDelay(m_pRunnable.get());
}
handle(ThreadDoneEvent& e)
{
if(m_isFolderCreated)
{...}
}
In start()
, the m_pRunnable
is a member variable, which is assigned a lambda functions with the variable m_isFolderCreated
captured by reference. The reason for this is that it returns the result of the spDiskManager
method createDirectory
, and will later be used in the function handle(ThreadDoneEvent& e)
to check if a folder was created or not. The lambda will be executed in a separate thread, not in the thread the class executes in. Note that handle(ThreadDoneEvent& e)
will be called only AFTER the worker thread finishes execution, since the event ThreadDoneEvent
will only be published when the worker thread has finished executing.
My question is: In this particular case, and in general, would you consider the capture of a member variable by reference, an ok practice, when to be used in another thread like here?
I mean, it is meant to only be used as a read-only variable in the class, but once someone else chooses to do changes in this class(which in reality happens to big quite big), there is a small chance that he will try to change this variable and we can get a race condition.
In other cases, you may want to capture more variables by reference for your lambda to execute, which seems even more dangerous.
Another way of doing this would be to have a separate class which will hold the success
boolean and run the function createDirectory
through that class. Once it has run, you could extract the success
bool, set by createDirectory, through a getter. But that would be more code to write...
std::aromic<>
.this
instead? At least it will make that obvious.