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

View File

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