Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support select coro and channel #535

Merged
merged 9 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmake/develop.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ int main()
endmacro()

# Enable address sanitizer
option(ENABLE_SANITIZER "Enable sanitizer(Debug+Gcc/Clang/AppleClang)" ON)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
option(ENABLE_SANITIZER "Enable sanitizer(Debug+Gcc/Clang/AppleClang)" OFF)
else()
option(ENABLE_SANITIZER "Enable sanitizer(Debug+Gcc/Clang/AppleClang)" ON)
endif()
if(ENABLE_SANITIZER AND NOT MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
check_asan(HAS_ASAN)
Expand Down
73 changes: 0 additions & 73 deletions include/async_simple/CMakeLists.txt

This file was deleted.

14 changes: 14 additions & 0 deletions include/async_simple/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@
#endif // __SANITIZE_ADDRESS__
#endif // __GNUC__

#if defined(__alibaba_clang__) && \
__has_cpp_attribute(ACC::coro_only_destroy_when_complete)
#define CORO_ONLY_DESTROY_WHEN_DONE [[ACC::coro_only_destroy_when_complete]]
#else
#define CORO_ONLY_DESTROY_WHEN_DONE
#endif

#if defined(__alibaba_clang__) && \
__has_cpp_attribute(ACC::elideable_after_await)
#define ELIDEABLE_AFTER_AWAIT [[ACC::elideable_after_await]]
#else
#define ELIDEABLE_AFTER_AWAIT
#endif

namespace async_simple {
// Different from assert, logicAssert is meaningful in
// release mode. logicAssert should be used in case that
Expand Down
14 changes: 10 additions & 4 deletions include/async_simple/Executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#include <functional>
#include <string>
#include <thread>
#include "async_simple/MoveWrapper.h"
#include "async_simple/experimental/coroutine.h"
#include "async_simple/util/move_only_function.h"

namespace async_simple {
// Stat information for an executor.
Expand Down Expand Up @@ -86,6 +88,13 @@ class Executor {
// func will not be executed. In case schedule return true, the executor
// should guarantee that the func would be executed.
virtual bool schedule(Func func) = 0;

// Schedule a move only functor
bool schedule_move_only(util::move_only_function<void()> func) {
MoveWrapper<decltype(func)> tmp(std::move(func));
return schedule([func = tmp]() { func.get()(); });
}

// Return true if caller runs in the executor.
virtual bool currentThreadInExecutor() const {
throw std::logic_error("Not implemented");
Expand Down Expand Up @@ -143,10 +152,7 @@ class Executor::TimeAwaiter {

template <typename PromiseType>
void await_suspend(std::coroutine_handle<PromiseType> continuation) {
std::function<void()> func = [c = continuation]() mutable {
c.resume();
};
_ex->schedule(func, _dur);
_ex->schedule(std::move(continuation), _dur);
}
void await_resume() const noexcept {}

Expand Down
7 changes: 6 additions & 1 deletion include/async_simple/Future.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Future {

public:
using value_type = T;

Future(FutureState<inner_value_type>* fs) : _sharedState(fs) {
if (_sharedState) {
_sharedState->attachOne();
Expand Down Expand Up @@ -89,6 +90,8 @@ class Future {
return *this;
}

auto coAwait(Executor*) && noexcept { return std::move(*this); }

public:
bool valid() const {
return _sharedState != nullptr || _localState.hasResult();
Expand Down Expand Up @@ -349,7 +352,9 @@ template <typename T>
Future<T> makeReadyFuture(std::exception_ptr ex) {
return Future<T>(Try<T>(ex));
}
inline Future<void> makeReadyFuture() { return Future<void>(Try<Unit>()); }
inline Future<void> makeReadyFuture() {
return Future<void>(Try<Unit>(Unit()));
}

} // namespace async_simple

Expand Down
13 changes: 6 additions & 7 deletions include/async_simple/FutureState.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#include <thread>
#include "async_simple/Common.h"
#include "async_simple/Executor.h"
#include "async_simple/MoveWrapper.h"
#include "async_simple/Try.h"
#include "async_simple/util/move_only_function.h"

namespace async_simple {

Expand Down Expand Up @@ -62,7 +62,7 @@ constexpr State operator&(State lhs, State rhs) {
template <typename T>
class FutureState {
private:
using Continuation = std::function<void(Try<T>&& value)>;
using Continuation = util::move_only_function<void(Try<T>&& value)>;

private:
// A helper to help FutureState to count the references to guarantee
Expand Down Expand Up @@ -228,11 +228,10 @@ class FutureState {
void setContinuation(F&& func) {
logicAssert(!hasContinuation(),
"FutureState already has a continuation");
MoveWrapper<F> lambdaFunc(std::move(func));
new (&_continuation) Continuation([lambdaFunc](Try<T>&& v) mutable {
auto& lambda = lambdaFunc.get();
lambda(std::forward<Try<T>>(v));
});
new (&_continuation)
Continuation([func = std::move(func)](Try<T>&& v) mutable {
func(std::forward<Try<T>>(v));
});

auto state = _state.load(std::memory_order_acquire);
switch (state) {
Expand Down
1 change: 0 additions & 1 deletion include/async_simple/LocalState.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <utility>
#include "async_simple/Common.h"
#include "async_simple/Executor.h"
#include "async_simple/MoveWrapper.h"
#include "async_simple/Try.h"

namespace async_simple {
Expand Down
25 changes: 13 additions & 12 deletions include/async_simple/MoveWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define ASYNC_SIMPLE_MOVEWRAPPER_H

#include <exception>

#include "async_simple/Common.h"

namespace async_simple {
Expand All @@ -26,23 +27,23 @@ namespace async_simple {
// copy as move.
template <typename T>
class MoveWrapper {
public:
MoveWrapper() = default;
MoveWrapper(T&& value) : _value(std::move(value)) {}
public:
MoveWrapper() = default;
MoveWrapper(T&& value) : _value(std::move(value)) {}

MoveWrapper(const MoveWrapper& other) : _value(std::move(other._value)) {}
MoveWrapper(MoveWrapper&& other) : _value(std::move(other._value)) {}
MoveWrapper(const MoveWrapper& other) : _value(std::move(other._value)) {}
MoveWrapper(MoveWrapper&& other) : _value(std::move(other._value)) {}

MoveWrapper& operator=(const MoveWrapper&) = delete;
MoveWrapper& operator=(MoveWrapper&&) = delete;
MoveWrapper& operator=(const MoveWrapper&) = delete;
MoveWrapper& operator=(MoveWrapper&&) = delete;

T& get() { return _value; }
const T& get() const { return _value; }
T& get() { return _value; }
const T& get() const { return _value; }

~MoveWrapper() {}
~MoveWrapper() {}

private:
mutable T _value;
private:
mutable T _value;
};

} // namespace async_simple
Expand Down
2 changes: 1 addition & 1 deletion include/async_simple/Try.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Try {
}
std::exception_ptr getException() const {
logicAssert(std::holds_alternative<std::exception_ptr>(_value),
"Try object do not has on error");
"Try object do not has an error");
return std::get<std::exception_ptr>(_value);
}

Expand Down
Loading
Loading