Garbage values in lambda-captured variables as callback - c++

I know that this may be fairly confusing, but I'm writing a unit test using the Boost test framework. I'm trying to simply increment a variable to test that a specific callback was executed as expected.
This is the test code excerpt:
uint32_t nSuccessCallbacks = 0;
uint32_t nFailureCallbacks = 0;
auto successCallback = [&nSuccessCallbacks, this] {
std::cout << "Running success callback...\n";
++nSuccessCallbacks;
};
auto failureCallback = [&nFailureCallbacks, this] (const std::string& str) {
std::cout << "Error code: " << str << "\n";
std::cout << "Running failure callback...\n";
++nFailureCallbacks;
};
dest.advertise(rr, successCallback, failureCallback);
The definition of advertise:
void
NfdRibReadvertiseDestination::advertise(nfd::rib::ReadvertisedRoute& rr,
std::function<void()> successCb,
std::function<void(const std::string&)> failureCb)
{
m_controller.start<ndn::nfd::RibRegisterCommand>(
ControlParameters().setName(rr.getPrefix()).setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT).setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT),
[&] (const ControlParameters& cp) { successCb(); },
[&] (const ControlResponse& cr) { failureCb(cr.getText()); });
}
Just for reference, dest is defined in the test fixture.
I'm not able to modify nSuccessCallbacks. Whenever the callback is called, we step through it correctly, but after the callback exits and we are in code after dest.advertise(), the value is still 0. We successfully reach the callback lambda, but the gdb reports that there is no such variable in the scope. I've tried every reasonable combination of all-capture, specific capture, mixing in the this and removing it, etc. I don't know why the capture clause incorrectly captures the variable. My best guess is that since the lambda is passed into another lambda, the capture clause of the first is lost?
EDIT: The callback is executed when an interface object receives data. We mock that up later in the test, and was unimportant so I chose not to include it.

Using a crystal ball, your lambda is run after one of the many scopes where you capture something by reference (either advertise or your "test code exerpt") has exited. Thus the by-reference captured variable has left scope, and UB results, and you see garbage.
Your code as posted does not actually run the lambda, so clearly the code as posted has no such problem with the lambda containing garbage.
As a general rule, never capture by reference if your lambda or any copies of it could possibly outlive the current scope. Capture by copy, or (in C++14) by move. There are exceptions to this rule, but they are easy sources of bugs.
As a second rule, if your lambda outlives the current scope, explicitly capture everything you capture. Have no default capture. That way you won't be surprised by something being captured whose lifetime (or pointed-to lifetime) is not long enough, like this or some pointer or somesuch.
At the least do this:
[successCb] (const ControlParameters& cp) { successCb(); },
[failureCb] (const ControlResponse& cr) { failureCb(cr.getText()); }
Then ensure that this, and no copies of this:
auto successCallback = [&nSuccessCallbacks, this] {
std::cout << "Running success callback...\n";
++nSuccessCallbacks;
};
does not outlive its scope. If it does, change how you capture.

The start call will, given the name, start an asynchronous thread to process the request. Unfortunately this means that the variables captured by reference in the lambda will have been already deallocated when they're accessed.
C++ only allows you to capture by copy (and you've no lifetime problems) or to capture by reference but you must ensure that the lambda will not outlive the referenced variables.
To solve correctly the "upward funarg" problem (a lambda capturing a variable - not a value - from a context and outliving the context) a garbage collector is needed (a stack isn't enough) and C++ doesn't provide one.
A solution (if you pay attention to avoiding loops) is to capture by value a shared_ptr to the mutable shared state needed.

Related

Pass context through composed promises in KJ

Playing with the KJ library, I wrote a small TCP servers that reads a "PING" and responds a "PONG". I managed to compose the promises like this:
char buffer[4];
kj::Own<kj::AsyncIoStream> clientStream;
addr->listen()->accept()
.then([&buffer, &clientStream](kj::Own<kj::AsyncIoStream> stream) {
clientStream = kj::mv(stream);
return clientStream->tryRead(buffer, 4, 4);
}).then([&buffer, &clientStream](size_t read) {
KJ_LOG(INFO, kj::str("Received", read, " bytes: ", buffer));
return clientStream->write("PONG", 4);
}).wait(waitScope);
I had to keep buffer out of the promises and pass a reference to it. This means that buffer has to stay in scope until the last promise finishes. That's the case here, but is there a solution in case it isn't?
Same thing for clientStream: I had to declare it before, then wait until I receives it from accept(), and at this point move it outside and use the reference to it.
Is there a better way to do it? Say like a way to pass some kind of context from promise to promise, always owned by the promises and therefore not having to stay "outside"?
It seems your problem is that your second lambda wants access to the scope of the first lambda, but the way you've organised things prevents that. You've worked around that by just adding variables to their shared "global" scope.
Instead, you could put the second lambda inside the first, something like this:
addr->listen()->accept()
.then([](kj::Own<kj::AsyncIoStream> stream) {
auto buffer = kj::heapArray<char>(4);
auto promise = stream->tryRead(buffer.begin(),4,4);
return promise.then([stream=kj::mv(stream), buffer=kj::mv(buffer)] (size_t read) mutable {
KJ_LOG(INFO, kj::str("Received", read, " bytes: ", buffer));
return stream->write("PONG", 4);
});
}).wait(waitScope);

tweaking captured lambda values

I have the following situation:
int p;
[p]() {
// really complex and really long code executing outside the main thread
}
The lambda object should be instantiated in several places in my code, p being captured every time. The problem is, that the code of the lambda is rather long and depends on p and I don't want to copy&paste the same code everywhere. I am reluctant to capture by reference, as the lambda is executing in the context of a thread and the referenced object may change. What would be the best thing to do? Could capturing a thread_local variable by reference help in some way?
EDIT:
in the end I went like this:
::std::function<void(int)> f; // captures the lambda
int p;
run_in_thread(::std::bind(f, p));
The reason why I didn't think of this before, was a discussion about the superiority of lambdas over ::std::bind, but apparently they are not for all purposes.
If you want clean code you should generally avoid lambdas with large bodies. So the cleanest solution is probably to move your code into a new function which the lambda in turn calls.
void complexFunction(int p) {
// really complex and really long code executing outside the main thread
}
void run() {
for(int i = 0; i < 10; ++i)
runThread([i]() {complexFunction(i);});
}

Can I build a bidirectional coroutine with Boost 1.55?

The current Boost 1.55 implementation offers two kinds of unidirectional coroutines. One is a pull-type, which is a coroutine that takes no parameters and returns a value to the main context; the other is the push-type, which is a coroutine that accepts a parameter from the main context but returns no value.
How can I combine these two to create a bidirectional coroutine that both accepts a parameter and returns a value? On the surface it seems like it should be possible, but I can't quite figure out how to do it with the building blocks I have in boost::coroutine. There used to be a bidirectional coroutine in older Boosts, but it is now deprecated and undocumented, so I shouldn't rely on it.
ie, I would like something analogous to this:
void accumulate( pull_func &in, push_func &out )
{
int x = 0;
while ( in )
{
x += in.get() ; // transfers control from main context
out(x); // yields control to main context
}
}
void caller( int n )
{
bidirectional_coro( accumulate );
for ( int i = 0 ; i < n ; ++i )
{
int y = accumulate(i);
printf( "%d ", y ); // "0 1 3 6 10" etc
}
}
Actually, boost coroutine was bidirectional when it was first included in boost(1.53 I think).
http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm
That code should still be compatible with the most recent version of boost, with minor modification if anything.
Also, you could use boost::context directly to create your own coroutine class.
http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html
The parameter 'intptr_t vp' of fcontext_swap can be use to pass values/pointers back and forth, or you could store values in the coroutine itself, as member variables of your coroutine class should be valid from both contexts.
edit:
The short answer to your original question is no. What you are asking cannot be done. Each coroutine has it's own stack and context, which are not accessible from other coroutine instances. Also, when you jump into the coroutine's context, the state of the calling context is stored in that coroutine instance, and a jump back to the original context can only be made by calling into the argument that that coroutine passed into your function.
But, variables declared outside the local scope of the coroutine will be valid from inside and outside the coroutine function. So you could use a coroutine::push_type, and push a pointer instead of a value. You could use the value, and then modify it before jumping back to the original context.
Also, you can safely pass pointers to local variables into the coroutine, since they won't be destroyed until you jump back out of the coroutine and run the calling scope to completion.
you could look at the example contained in boost.coroutine
https://github.com/boostorg/coroutine/blob/master/example/cpp03/chaining.cpp

c++ member function thread safe

I am writing a function for logging messages .
I will be calling this print function from different threads .
My code is as follows :
MyLog::printLog(const char* s)
{
std::string myline(s);
//m_Mutex is class member and there will be only object for this class
// shared by all threads
int ret = pthread_mutex_lock(&m_Mutex);
if ( ret != 0 )
{
std::cout<<" trying to lock same mutex char* "<<std::endl;
}
//code to log message in File
pthread_mutex_unlock(&m_Mutex);
}
My question is if above function is called from different threads with argument like "from thread1" , "from thread 2" ,... will there be any chance const char *s will be jumbled up printing wrong values .?
I hope my question is clear .
Your function will work as you expect, since myline is a local variable (each thread has its own stack, so would have its own instance of myline)
If you're calling this function from different threads, and any changes you make to your argument const char* s are protected by your mutex m_Mutex then you'll be just fine and nothing will be jumbled.
EDIT
Actually, each call to this function will have it's own stack when called from a different thread, and seeing that it const char* you cannot change your argument, so there's no need to protect it with a mutex.
Your variable s is a variable local to the thread it's being called in, and it's const.
Then copying into the local variable myline is definitely not going to mess with anything, cause each thread has it's call stack, on which lives an instance of myline when this function is called, which is totally separate and independent of any other thread.
It depends on how you are calling the printLog function. If the string whose address you pass to the function gets mutated by a different thread, then you may not see a consistent view of it inside the log function. If you pass in a pointer to an immutable string, like a literal for example, then you're fine, though.
Here's an example that's fine:
void from_thread_one()
{
MyLog::printLog("Hello World"); // immutable string
}
void from_thread_two()
{
MyLog::printLog("Another text"); // ditto
}
On the other hand, here's an example that's not OK and has a race:
char globalString[] = "This is a really long string";
void from_thread_one()
{
globalString[5] = 'A';
MyLog::printLog(globalString);
}
void from_thread_two()
{
globalString[8] = 'Q';
MyLog::printLog(globalString);
}
In this setting, you are making a copy of the string (via std::string myline(s);) while the contents of the array pointed to by s can simultaneously be changed in the other thread. In this scenario, dereferencing the char pointer has to happen inside the critical section as well.
The fundamental problem with your setup is that the raw char pointer has no implicit semantics that tell the user which behaviour is acceptable and which isn't. Had you passed in an actual std::string by value, you would have removed the uncertainty about synchronising access to the string from your printLog function and moved the responsibility entirely into the caller.

Difficult concurrent design

I have a class called Root which serves as some kind of phonebook for dynamic method calls: it holds a dictionary of url keys pointing to objects. When a command wants to execute a given method it calls a Root instance with an url and some parameter:
root_->call("/some/url", ...);
Actually, the call method in Root looks close to this:
// Version 0
const Value call(const Url &url, const Value &val) {
// A. find object
if (!objects_.get(url.path(), &target))
return ErrorValue(NOT_FOUND_ERROR, url.path());
}
// B. trigger the object's method
return target->trigger(val);
}
From the code above, you can see that this "call" method is not thread safe: the "target" object could be deleted between A and B and we have no guarantee that the "objects_" member (dictionary) is not altered while we read it.
The first solution that occurred to me was:
// Version I
const Value call(const Url &url, const Value &val) {
// Lock Root object with a mutex
ScopedLock lock(mutex_);
// A. find object
if (!objects_.get(url.path(), &target))
return ErrorValue(NOT_FOUND_ERROR, url.path());
}
// B. trigger the object's method
return target->trigger(val);
}
This is fine until "target->trigger(val)" is a method that needs to alter Root, either by changing an object's url or by inserting new objects. Modifying the scope and using a RW mutex can help (there are far more reads than writes on Root):
// Version II
const Value call(const Url &url, const Value &val) {
// A. find object
{
// Use a RW lock with smaller scope
ScopedRead lock(mutex_);
if (!objects_.get(url.path(), &target))
return ErrorValue(NOT_FOUND_ERROR, url.path());
}
}
// ? What happens to 'target' here ?
// B. trigger the object's method
return target->trigger(val);
}
What happens to 'target' ? How do we ensure it won't be deleted between finding and calling ?
Some ideas: object deletion could be post-poned in a message queue in Root. But then we would need another RW mutex read-locking deletion on the full method scope and use a separate thread to process the delete queue.
All this seems very convoluted to me and I'm not sure if concurrent design has to look like this or I just don't have the right ideas.
PS: the code is part of an open source project called oscit (OpenSoundControl it).
To avoid the deletion of 'target', I had to write a thread safe reference counted smart pointer. It is not that hard to do. The only thing you need to ensure is that the reference count is accessed within a critical section. See this post for more information.
You are on the wrong track with this. Keep in mind: you can't lock data, you can only block code. You cannot protect the "objects" member with a locally defined mutex. You need the exact same mutex in the code that alters the objects collection. It must block that code when another thread is executing the call() method. The mutex must be defined at least at class scope.