Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
More bandaids to avoid #1309
Browse files Browse the repository at this point in the history
Even though we only bind the shared_ptr in the after callback, the
worker thread was still copying the callback and therefore gaining
a shared reference. Here we try to eliminate the copies.
  • Loading branch information
jfirebaugh committed May 1, 2015
1 parent dac4b7d commit 24695f6
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 15 deletions.
2 changes: 1 addition & 1 deletion platform/default/sqlite_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void SQLiteCache::get(const Resource &resource, Callback callback) {
// Will try to load the URL from the SQLite database and call the callback when done.
// Note that the callback is probably going to invoked from another thread, so the caller
// must make sure that it can run in that thread.
thread->invokeWithResult(&Impl::get, callback, resource);
thread->invokeWithResult(&Impl::get, std::move(callback), resource);
}

std::unique_ptr<Response> SQLiteCache::Impl::get(const Resource &resource) {
Expand Down
14 changes: 7 additions & 7 deletions src/mbgl/util/run_loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,31 @@ class RunLoop : private util::noncopyable {

// Invoke fn() in the runloop thread, then invoke callback(result) in the current thread.
template <class Fn, class R>
void invokeWithResult(Fn&& fn, std::function<void (R)> callback) {
void invokeWithResult(Fn&& fn, std::function<void (R)>&& callback) {
RunLoop* outer = current.get();
assert(outer);

invoke([fn, callback, outer] {
/*
With C++14, we could write:
outer->invoke([callback, result = std::move(fn())] () mutable {
callback(std::move(result));
outer->invoke([cb = std::move(callback), result = std::move(fn())] () mutable {
cb(std::move(result));
});
Instead we're using a workaround with std::bind
to obtain move-capturing semantics with C++11:
http://stackoverflow.com/a/12744730/52207
*/
outer->invoke(std::bind([callback] (R& result) {
callback(std::move(result));
}, std::move(fn())));
outer->invoke(std::bind([] (std::function<void (R)>& cb, R& result) {
cb(std::move(result));
}, std::move(callback), std::move(fn())));
});
}

// Invoke fn() in the runloop thread, then invoke callback() in the current thread.
template <class Fn>
void invokeWithResult(Fn&& fn, std::function<void ()> callback) {
void invokeWithResult(Fn&& fn, std::function<void ()>&& callback) {
RunLoop* outer = current.get();
assert(outer);

Expand Down
8 changes: 4 additions & 4 deletions src/mbgl/util/thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ class Thread {

// Invoke object->fn(args...) in the runloop thread, then invoke callback(result) in the current thread.
template <typename Fn, class R, class... Args>
void invokeWithResult(Fn fn, std::function<void (R)> callback, Args&&... args) {
loop->invokeWithResult(std::bind(fn, object, args...), callback);
void invokeWithResult(Fn fn, std::function<void (R)>&& callback, Args&&... args) {
loop->invokeWithResult(std::bind(fn, object, args...), std::move(callback));
}

// Invoke object->fn(args...) in the runloop thread, then invoke callback() in the current thread.
template <typename Fn, class... Args>
void invokeWithResult(Fn fn, std::function<void ()> callback, Args&&... args) {
loop->invokeWithResult(std::bind(fn, object, args...), callback);
void invokeWithResult(Fn fn, std::function<void ()>&& callback, Args&&... args) {
loop->invokeWithResult(std::bind(fn, object, args...), std::move(callback));
}

// Invoke object->fn(args...) in the runloop thread, and wait for the result.
Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/util/worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Worker::Worker(std::size_t count) {

Worker::~Worker() = default;

void Worker::send(Fn work, Fn after) {
threads[current]->invokeWithResult(&Worker::Impl::doWork, after, work);
void Worker::send(Fn&& work, Fn&& after) {
threads[current]->invokeWithResult(&Worker::Impl::doWork, std::move(after), std::move(work));
current = (current + 1) % threads.size();
}

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/util/worker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Worker : public mbgl::util::noncopyable {
Worker(std::size_t count);
~Worker();

void send(Fn work, Fn after);
void send(Fn&& work, Fn&& after);

private:
class Impl;
Expand Down

0 comments on commit 24695f6

Please sign in to comment.