Remove mutex locks from rpl for now.

This commit is contained in:
John Preston 2017-09-19 17:50:02 +03:00
parent 5586d231de
commit 1c5abaa518
2 changed files with 31 additions and 49 deletions

View File

@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <mutex>
#include <gsl/gsl_assert>
#include <rpl/lifetime.h>
#include <rpl/details/callable.h>
@ -138,7 +137,6 @@ public:
protected:
lifetime _lifetime;
bool _terminated = false;
std::mutex _mutex;
};
@ -279,10 +277,7 @@ inline void consumer<Value, Error>::terminate() const {
template <typename Value, typename Error>
inline void consumer<Value, Error>::abstract_instance::add_lifetime(
lifetime &&lifetime) {
std::unique_lock<std::mutex> lock(_mutex);
if (_terminated) {
lock.unlock();
lifetime.destroy();
} else {
_lifetime.add(std::move(lifetime));
@ -293,20 +288,15 @@ template <typename Value, typename Error>
template <typename Type, typename... Args>
inline Type *consumer<Value, Error>::abstract_instance::make_state(
Args&& ...args) {
std::unique_lock<std::mutex> lock(_mutex);
Expects(!_terminated);
return _lifetime.make_state<Type>(std::forward<Args>(args)...);
}
template <typename Value, typename Error>
inline void consumer<Value, Error>::abstract_instance::terminate() {
std::unique_lock<std::mutex> lock(_mutex);
if (!_terminated) {
_terminated = true;
auto handler = std::exchange(_lifetime, lifetime());
lock.unlock();
handler.destroy();
base::take(_lifetime).destroy();
}
}
@ -314,17 +304,11 @@ template <typename Value, typename Error>
template <typename OnNext, typename OnError, typename OnDone>
bool consumer<Value, Error>::instance<OnNext, OnError, OnDone>::put_next(
Value &&value) {
std::unique_lock<std::mutex> lock(this->_mutex);
if (this->_terminated) {
return false;
}
auto handler = this->_next;
lock.unlock();
details::callable_helper(
handler,
std::move(value),
details::is_callable_plain<OnNext, Value>());
details::callable_invoke(std::move(handler), std::move(value));
return true;
}
@ -332,17 +316,11 @@ template <typename Value, typename Error>
template <typename OnNext, typename OnError, typename OnDone>
bool consumer<Value, Error>::instance<OnNext, OnError, OnDone>::put_next_copy(
const Value &value) {
std::unique_lock<std::mutex> lock(this->_mutex);
if (this->_terminated) {
return false;
}
auto handler = this->_next;
lock.unlock();
details::const_ref_call_helper(
handler,
value,
details::allows_const_ref<OnNext, Value>());
details::const_ref_call_invoke(std::move(handler), value);
return true;
}
@ -350,12 +328,10 @@ template <typename Value, typename Error>
template <typename OnNext, typename OnError, typename OnDone>
void consumer<Value, Error>::instance<OnNext, OnError, OnDone>::put_error(
Error &&error) {
std::unique_lock<std::mutex> lock(this->_mutex);
if (!this->_terminated) {
auto handler = std::move(this->_error);
lock.unlock();
details::callable_invoke(handler, std::move(error));
details::callable_invoke(
std::move(this->_error),
std::move(error));
this->terminate();
}
}
@ -364,15 +340,10 @@ template <typename Value, typename Error>
template <typename OnNext, typename OnError, typename OnDone>
void consumer<Value, Error>::instance<OnNext, OnError, OnDone>::put_error_copy(
const Error &error) {
std::unique_lock<std::mutex> lock(this->_mutex);
if (!this->_terminated) {
auto handler = std::move(this->_error);
lock.unlock();
details::const_ref_call_helper(
handler,
error,
details::allows_const_ref<OnError, Error>());
details::const_ref_call_invoke(
std::move(this->_error),
error);
this->terminate();
}
}
@ -380,12 +351,8 @@ void consumer<Value, Error>::instance<OnNext, OnError, OnDone>::put_error_copy(
template <typename Value, typename Error>
template <typename OnNext, typename OnError, typename OnDone>
void consumer<Value, Error>::instance<OnNext, OnError, OnDone>::put_done() {
std::unique_lock<std::mutex> lock(this->_mutex);
if (!this->_terminated) {
auto handler = std::move(this->_done);
lock.unlock();
handler();
std::move(this->_done)();
this->terminate();
}
}

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#pragma once
#include "base/build_config.h"
#include <tuple>
// Custom libc++ build used for old OS X versions already has this.
@ -150,12 +151,14 @@ constexpr bool is_callable_v = is_callable<Method, Args...>::value;
template <typename Method, typename Arg>
inline decltype(auto) callable_helper(Method &&method, Arg &&arg, std::true_type) {
return std::move(method)(std::forward<Arg>(arg));
return std::forward<Method>(method)(std::forward<Arg>(arg));
}
template <typename Method, typename Arg>
inline decltype(auto) callable_helper(Method &&method, Arg &&arg, std::false_type) {
return std::apply(std::move(method), std::forward<Arg>(arg));
return std::apply(
std::forward<Method>(method),
std::forward<Arg>(arg));
}
template <typename Method, typename Arg>
@ -192,19 +195,31 @@ struct allows_const_ref
template <typename Method, typename Arg>
inline decltype(auto) const_ref_call_helper(
Method &method,
Method &&method,
const Arg &arg,
std::true_type) {
return callable_invoke(method, arg);
return callable_invoke(std::forward<Method>(method), arg);
}
template <typename Method, typename Arg>
inline decltype(auto) const_ref_call_helper(
Method &method,
Method &&method,
const Arg &arg,
std::false_type) {
auto copy = arg;
return callable_invoke(method, std::move(copy));
return callable_invoke(
std::forward<Method>(method),
std::move(copy));
}
template <typename Method, typename Arg>
inline decltype(auto) const_ref_call_invoke(
Method &&method,
const Arg &arg) {
return const_ref_call_helper(
std::forward<Method>(method),
arg,
allows_const_ref<Method, Arg>());
}
} // namespace details