Commit graph

171 commits

Author SHA1 Message Date
Lewis Baker eb8ad58c1d Avoid use of std::hardware_destructive_interference_size.
This is not yet implemented under libc++.
2018-08-03 08:26:05 -07:00
Lewis Baker 398fb1dc1f Fix static_thread_pool crashes.
- thread_state::m_mask was being incorrectly initialised
- Modified try_local_enqueue() to attempt to enlarge the local
  queue if it looks like it's run out of space.
- Removed doubly-linked list from schedule_operation as it wasn't
  needed.
- Catch any potential exceptions thrown by auto_reset_event::wait()
  and just sleep for 1ms in this case rather than terminating the
  thread.
2018-08-03 08:25:09 -07:00
Lewis Baker c6d5f6a738 WIP version of static_thread_pool.
Still seems to have some bugs that cause crashes in the tests.
2018-07-31 08:09:09 -07:00
mwinterb d3a569f6c5 Fixed move constructor for win32_overlapped_operation_cancellable. (#80)
Addresses aspects of #34.
2018-07-17 09:55:19 -07:00
Lewis Baker 4a66d0889f
Merge branch 'master' into generic_ops 2018-04-06 11:38:49 +09:30
Attila b0e5f765ba Fix typo in async_generator state description 2018-04-04 12:34:11 +09:30
Attila a4d2c7b003 Correct file_write_operation's friend class 2018-03-29 15:52:27 +02:00
Lewis Baker 16e0df5b5c Add basic send_to/recv_from functionality to socket class. 2018-01-12 06:35:51 +10:30
Lewis Baker be0c017186 Declare socket operation factory methods to be noexcept. 2018-01-12 06:35:45 +10:30
Lewis Baker b830b08324 Refactor async I/O operation classes to remove some duplication.
Factors out implementation of calls to OS that was duplicated in
both cancellable and non-cancellable operation objects into an
'impl' class that can be used by both.

Also, fixed potential data race in some try_start() methods when
trying to read the m_skipCompletionOnSuccess member of a socket
after starting the I/O operation. Now ensure that this flag is
read before starting the operation.

Simplified logic for file_[read/write]_operation slightly by
passing out-parameter to receive number of bytes read/written
if operation completes synchronously. This avoids an extra call
to GetOverlappedResult() to retrieve this information.
2018-01-12 06:35:30 +10:30
Lewis Baker 664537595e Add some basic Win32 async socket abstractions.
- Adds cppcoro::net::socket class with support for TCP/UDP
  over IPv4 or IPv6.
- Adds async accept/connect/disconnect/send/recv operations in
  both cancellable and non-cancellable variants.
- Still need to add send_to/recv_from as well as overloads for
  multi-buffer send/recv.
2018-01-12 06:35:15 +10:30
Lewis Baker a0fa1f84b7
Merge branch 'master' into generic_ops 2018-01-08 12:22:20 +10:30
Lewis Baker d2bb79c256 Disable some tests under MSVC x86 optimised build variants.
Compiler is generating bad code for these tests under Visual Studio
15 Update 5.
2018-01-08 11:17:20 +10:30
Lewis Baker 0b68f6f27c Fix typo in assert statement that broke debug win32 builds. 2017-12-27 20:28:21 +10:30
Lewis Baker 36be19a349 Refactor file_read/write_operation classes for Win32.
- Move common logic for Win32 OVERLAPPED-based operations out into
  new win32_overlapped_operation[_cancellable] base-classes.
  The concrete I/O operation classes are now greatly simplified
  due to the reduction of boilerplate.
- Added overloads for read() and write() functions that don't
  take a cancellation_token that return a simpler awaitable type
  that generates much simpler assembly.
2017-12-27 19:36:14 +10:30
Lewis Baker 338c43f227 Add ip_address and ip[v4/v6]_endpoint. 2017-12-18 22:48:00 +10:30
Lewis Baker 7e049f6b79 Add cppcoro::net::ipv6_address. 2017-12-16 21:31:41 +10:30
Lewis Baker 1c7ee9252d Add cppcoro::net::ipv4_address 2017-12-15 08:08:20 +10:30
Lewis Baker 0f92e2dcd5 Add multi_producer_sequencer.
This allows multiple producers to write concurrently to a ring
buffer.
2017-12-03 22:58:56 +10:30
Lewis Baker 2cd5fce40c Add cppcoro::single_producer_sequencer class.
- Add sequence_range in support of this.
- Add sequence_traits::size_type.
2017-11-28 22:59:21 +10:30
Lewis Baker c687f0d4bb Add sequence_barrier synchronisation primitive.
This is the first building block towards an async ring-buffer
data-structure.
2017-11-26 21:58:48 +10:30
Lewis Baker 03fd87422b Merge branch 'master' into feature/generic_ops 2017-11-23 13:12:55 +10:30
Lewis Baker f3909bff46 Fix include-guard for task.hpp.
It was still using the old LAZY_TASK terminology.
2017-11-22 22:04:18 +10:30
Lewis Baker b0eacb719e Add cppcoro::async_latch. 2017-11-22 21:55:45 +10:30
Lewis Baker 5162a969d7 Add CPPCORO_CPU_* macros for detecting target CPU. 2017-11-20 07:01:55 +10:30
Lewis Baker d7ef66dfb1 Fix sync_wait() under latest MSVC compiler.
A compiler workaround was only being applied for compiler versions
below a known version and would break whenever a new version comes
out without a fix. It now just applies the workaround for all MSVC
versions. I'll re-add the version limit once MSVC actually fixes
the bug.
2017-11-19 06:55:30 +10:30
Lewis Baker c76ba4ad56 Merge branch 'master' into feature/generic_ops 2017-11-17 13:32:33 +10:30
Lewis Baker 00b16e6a84 Add single_consumer_async_auto_reset_event. 2017-11-17 07:54:00 +10:30
Lewis Baker 9318cb7883 Merge remote-tracking branch 'remotes/github/generic_ops' into generic_ops 2017-10-26 22:14:09 +10:30
Lewis Baker 8ce850efcf Simplify shared_task reference counting.
No longer decrement the reference count in final_suspend()
as it's not needed for a lazy shared_task where there is
always guaranteed to be one awaiting shared_task.
This also fixes a potential memory leak of the coroutine
frame if a shared_task is never awaited.

Modified condition used for decrementing ref-count to
work around potential codegen bug in Clang (PR35068).
2017-10-26 22:12:45 +10:30
Lewis Baker 05d86d96d5 Fix CPPCORO_FORCE_INLINE for msvc 2017-10-19 14:00:20 +10:30
Lewis Baker 18d2b4d5aa Work around clang coroutine allocation elision bug.
Declare variadic when_all_ready() as forced-inline to
avoid it returning a reference to a when_all_read_task
object allocated in the stack-frame of when_all_ready().
2017-10-17 22:13:10 +10:30
Lewis Baker 0593def3a4 Change generator<T> to capture exceptions in exception_ptr.
This fixes an issue where Clang was calling std::terminate
when the exception was rethrown from within unhandled_exception().
2017-10-06 21:27:53 +10:30
Lewis Baker 512851563e Fix Clang warning about unused expression. 2017-10-06 21:21:39 +10:30
Lewis Baker 0170d60001 Remove cppcoro::detail::continuation.
It's no longer needed now that when_all() and sync_wait() have
been modified to work with arbitrary awaitables and create
coroutines to represent their continuations.
2017-10-04 22:22:31 +10:30
Lewis Baker c2576ad298 Refactor of when_all() and when_all_ready().
- Now supports when_all()/when_all_ready() on a std::vector of
  arbitrary awaitables.
- Changed when_all() to use an fmap() composition with result
  of when_all_ready() awaitable to extract the results from the
  when_all_task objects.
  This has the side-effect of meaning that
  'co_await lvalueWhenAllAwaitable' now returns a prvalue result
  rather than an lvalue-reference to the result.
  However, the prvalue tuple/vector will contain a copy of the
  results if awaiting an lvalue (allowing you to await it again
  and get another copy) whereas if you co_await an rvalue awaitable
  then the results will be moved into the tuple/vector.
- Re-added support for passing std::reference_wrapper-wrapped
  awaitables to when_all().
- Renamed when_all_awaitable_counter to when_all_counter.
- Removed when_all_awaitable/when_all_awaitable2 as they are no
  longer needed. Everything is built on when_all_ready_awaitable.
2017-10-04 07:33:38 +10:30
Lewis Baker 72d08e089a Modify variadic when_all_ready() to support arbitrary awaitables.
Now yields a tuple<when_all_task<T>...> when awaited which allows
the caller to retrieve individual results by calling .result()
without needing to co_await again. This should allow usage of the
result in non-coroutine contexts.
2017-10-01 21:50:16 +10:30
Lewis Baker b4c78dc409 Remove workaround for Clang bug in when_all_awaitable2.
The bug where Clang was complaining about invalid return-type
of 'auto await_suspend()' when return-type is deduced to bool
should now be fixed.
2017-10-01 21:30:13 +10:30
Lewis Baker 414f3eb245 Tweak and document sync_wait() workaround for bug in MSVC.
Add generic implementation for use under Clang.

Use std::forward<> rather than static_cast<> to avoid warnings
about cast from lvalue to rvalue under MSVC in some cases.
2017-10-01 21:27:09 +10:30
Lewis Baker 03f8027c16 Fix incorrect code documentation for task.
There was a section left over from before lazy_task was renamed
to task and the eager task was removed that was contrasting
lazy_task with the eager task. This comparison is no longer
necessary.

Removed the warnings about stack-overflow as these issues have
been worked around (albeit at cost of an atomic operation).
2017-09-30 22:09:17 +09:30
Lewis Baker 5ea774d1f9 Make more functions work with arbitrary awaitables.
- Change fmap, schedule_on, resume_on, make_shared_task work with
  arbitrary awaitables.
- Add make_task to wrap an arbitrary awaitable in a task<T>.
- Remove specialisation of fmap() for task<T>, shared_task<T> as
  the generalised version obsoletes it.
2017-09-13 08:26:43 +09:30
Lewis Baker a64b0e145d Add detail::remove_rvalue_reference<T> template metafunction. 2017-09-13 07:12:57 +09:30
Lewis Baker f100b25869 Add cppcoro::is_awaitable_v<T> variable template. 2017-09-13 07:10:03 +09:30
Lewis Baker 2f8469bd96 Move is_awaiter<T> into cppcoro::detail namespace.
It is just an implementation detail of is_awaitable<T> and
shouldn't form part of the public API.
2017-09-11 21:16:59 +09:30
Lewis Baker 396d0271d1 Add generic imlementation of lightweight_manual_reset_event.
Uses `std::mutex` and `std::condition_variable` to implement
the manual-rese-event concept in a more heavy-weight way but
in a way that should be portable to all other platforms.

With thanks to @yfinkelstein.
2017-09-11 06:50:21 +09:30
Lewis Baker d0383c1cb3 Add noexcept to when_all_awaitable2<>::await_suspend(). 2017-09-06 21:32:27 +09:30
Lewis Baker 6bde4d56d1 Simplify member type for result pointer in when_all_task_promise. 2017-09-06 21:30:12 +09:30
Lewis Baker e25cb7d38c Fix when_all_awaitable2 move constructor. 2017-09-06 21:21:35 +09:30
Lewis Baker 8c5d063957 Support variadic when_all() with a single void-returning awaitable. 2017-09-06 21:20:04 +09:30
Lewis Baker 7c5dcdba18 Fix when_all() implementation under MSVC.
I was relying on coroutine_handle() default constructor initialising
the handle to nullptr in when_all_awaitable_counter constructor.
But this is not the case with the current MSVC implementation.
Now explicitly initialise handle to nullptr.
2017-09-04 21:52:53 +09:30
Lewis Baker 2080b54c8c Added workaround for issue returning rvalue-references from co_await.
Now return prvalue rather than xvalue when co_awaiting a task<T>
rvalue when T is

This works around an issue with sync_wait() implementation under
MSVC that breaks for task<int>.
2017-09-04 21:51:43 +09:30
Lewis Baker 662f42edd9 Add workaround for Clang bug in when_all_awaitable2.
Clang was complaining about return-type of await_suspend()
when return-type is 'auto' and deduced to be 'bool',
saying that it must be 'bool' or 'void'.
2017-09-04 10:04:14 +09:30
Lewis Baker fb45d02996 Fix member accessibility in when_all_task_promise<void>. 2017-09-04 10:01:45 +09:30
Lewis Baker 86a429aead WIP: generic variadic when_all() implementation. 2017-09-02 10:21:38 +09:30
Lewis Baker d07d48eff0 Experimental implementation of generalised sync_wait().
Causes some test failures which I still need to look into.
2017-09-02 10:08:56 +09:30
Lewis Baker e7870443d7 Add awaitable_traits, is_awaitable, is_awaiter template metafuntions 2017-09-02 09:58:15 +09:30
Lewis Baker 81de379342 Add schedule_on() and resume_on() functions. 2017-08-22 07:14:25 +09:30
Lewis Baker 8e728932be Improvements to fmap() implementation
- Added documentation to README
- Implemented fmap() for generator<T>, recursive_generator<T>,
  shared_task<T>.
- Centralised operator| overloads for fmap() in fmap.hpp.
- Now provide two-argument fmap() overloads as the type-specific
  implementations: fmap(func, value)
  This replaces the need for detail::apply_fmap() functions.
2017-08-19 23:12:34 +09:30
Lewis Baker 316ce6c7dd Modify task<T> to avoid potential for unbounded recursion.
The await_suspend() method of operator co_await() now returns bool
instead of void, to allow it to resume execution without suspending
if the task completes synchronously. However, this unfortunately
requires use of std::atomic operations to decide a potential race
between the awaiter suspending and the coroutine running to
completion.

This avoids a stack-overflow error when a coroutine awaits a
long sequence of task<T> values that complete synchronously.
eg. in a loop.
2017-08-17 22:23:59 +09:30
Lewis Baker bf9eb2c581 Rename lazy_task -> task, shared_lazy_task -> shared_task.
No need to keep the 'lazy' term in the name to distinguish it
from eager tasks as all task are lazy now.
2017-08-17 21:14:34 +09:30
Lewis Baker 64b0a049f9 Remove eager task types task<T> and shared_task<T>.
These types make it difficult to write exception-safe code
when compared with their lazy-task counterparts.
2017-08-17 07:55:58 +09:30
Lewis Baker 3a581e633e Add cppcoro::sync_wait().
Allows synchronously waiting for a task to complete.
2017-08-14 09:14:20 +09:30
Lewis Baker d6f005342d Make lightweight_manual_reset_event methods noexcept.
This is important to guarantee thread safety in some scenarios.
2017-08-10 22:37:11 +09:30
Lewis Baker 278c3181a6 Add detail::lightweight_manual_reset_event class.
Uses futex() on Linux, WaitOnAddress() on Win8+ and falls back to
Win32 events on earlier versions of Windows.
2017-08-10 07:34:09 +09:30
Lewis Baker 83ab6399ec Suppress some Clang warnings about unused return values.
Cast result to (void) where we are intentionally ignoring
the return value.
2017-08-03 00:12:47 +09:30
Lewis Baker 4c7569cb50 Merge branch 'master' of github.com:lewissbaker/cppcoro into clang
# Conflicts:
#	test/build.cake
2017-08-02 21:31:56 +09:30
Lewis Baker 7513d9cf0c Remove hack workaround for co_return <void-expr> under clang.
This bug has been fixed in clang-6.0.
2017-08-02 21:30:17 +09:30
Lewis Baker 67fea7fe53 Add when_all() and when_all_ready().
Add 'get_starter()' methods to all task types.
Add detail::unwrap_reference_t helper.
Add detail::when_all_awaitable helper.
2017-08-02 08:32:10 +09:30
Lewis Baker 671ac0b006 Rename 'resumer' class to 'continuation'.
The name 'continuation' much better matches the concept.
2017-08-02 08:32:10 +09:30
Lewis Baker 954588ccfa Enable make_shared_task(lazy_task<void>) workaround under clang. 2017-08-02 08:32:08 +09:30
Lewis Baker 5f5bfa9649 Add 'value_type' typedefs to each of the task-types.
This typedef just makes available the template parameter of the
task type. This can be useful when writing generic functions that
need to operate on any of the task-types.
2017-08-02 08:32:07 +09:30
Lewis Baker c22bef61a9 Modify task classes to support storing callback and pointer.
This allows registering continuations that are not coroutine
handles which can be useful for building some operators.
This comes at the expense of storage of an extra pointer per
coroutine and/or awaiter.

Adds the cppcoro::detail::resumer to wrap something that can
either be a callback + state or a coroutine_handle.
2017-08-02 08:32:07 +09:30
Lewis Baker 2104e545f4 Merge branch 'master' of github.com:lewissbaker/cppcoro into clang
# Conflicts:
#	tools/cake
2017-07-28 23:07:34 +09:30
Lewis Baker 2af1b18c0f Add async_manual_reset_event. 2017-07-25 07:10:50 +09:30
Lewis Baker 4b20a243b2 Add async_auto_reset_event. 2017-07-21 23:04:56 +09:30
Lewis Baker 49ec4915b0 Add workarounds for broken 'co_return <void-expr>;' in Clang. 2017-07-18 22:21:34 +09:30
Lewis Baker e5bf85c5e9 Fix bug in recursive_generator<T> when building under Clang.
The promise_type::get_return_object() method was returning a reference
to the promise object, expecting that reference to be passed to the
constructor of recursive_generator<T>.

However, under Clang the result of get_return_object() is assigned to
an 'auto' variable, which ends up taking a copy of the promise object
on the stack and passing that copy into the recursive_generator<T>
constructor.

Modified get_return_object() to return the already-constructed
recursive_generator<T> object.
2017-07-18 22:03:27 +09:30
Lewis Baker 1f6c7034c2 Fix get_return_object() to not require explict constructor call.
Clang doesn't allow calling explicit constructor to convert from
get_return_object() return-value to coroutine return-value.
2017-07-17 08:48:44 +09:30
Lewis Baker 528ba691e6 Add missing noexcept declaration to operation_cancelled::what(). 2017-07-17 07:40:35 +09:30
Lewis Baker 773a4be858 Add missing #includes to fmap.hpp
Also delcare fmap_transform constructor explict and add noexcept
declaration.
2017-07-17 07:38:38 +09:30
Lewis Baker a590ac14ca Add missing #include in cancellation_registration.hpp
The definition of cancellation_token is required for inline
constructor when building under Clang.
2017-07-17 07:32:27 +09:30
Lewis Baker 0af7061608 Use std::result_of_t instead of std::invoke_result_t.
This helps building under clang as libc++ doesn't seem to have
std::invoke_result yet.
2017-07-17 07:29:40 +09:30
Lewis Baker fab674f832 Add fmap() support to async_generator<T>. 2017-07-11 08:38:09 +09:30
Lewis Baker 1871e52a7f Add fmap() and implement transform for task<T> and lazy_task<T>. 2017-07-11 08:35:46 +09:30
Lewis Baker f1349291ef Fixes to compile cleanly under MSVC warning-level 4 and /analyze.
- Add [[maybe_unused]] to various parameters/variables.
- Rework a few loops in test-cases to get around some warnings
  about unreachable code.
2017-07-06 22:30:05 +09:30
Lewis Baker 1140628b6e Make interface of async_mutex more explicit.
Provide both lock_async() and scoped_lock_async(), the latter
returning an async_mutex_lock.
2017-07-06 22:06:48 +09:30
Lewis Baker 178dcc3f81 Explicitly declare io_service move constructor/assignment deleted. 2017-07-03 20:42:07 +09:30
Lewis Baker 830c4d1d30 Add io_service::schedule_after() to allow delayed scheduling.
The io_service now launches a background thread on-demand for
keeping track of active timers. Background thread uses a waitable
timer event for performing timed waits and an auto-reset event
for signalling addition of new timers, timer cancellation and
thread shutdown.
2017-07-02 22:02:56 +09:30
Lewis Baker d9cd896d5e Add some documentation to io_service constructors. 2017-07-02 09:35:58 +09:30
Lewis Baker c37d6a4a0c Make io_service::schedule() noexcept.
In the case that a schedule_operation could not be queued to the
I/O completion port using PostQueuedCompletionStatus() it now
pushes the operation onto a lock-free linked-list of overflow
operations.
The event loop will check for these overflow operations and try
to requeue them to the I/O completion port at a later time.

This allows us to declare io_service::schedule_impl() noexcept
and thus the corresponding schedule_operation::await_suspend()
operation noexcept.
2017-07-02 08:56:54 +09:30
Lewis Baker a34527617d Remove io_context and just use io_service& directly.
Added io_work_scope RAII class to help with scoped lifetime of
io_service event loop.

Having io_context always increment the ref-count of active I/O
operations whenever passed by-value to a function seems like
unnecessary atomic operations when compared to selected usages of
io_work_scope which generally only need creation for top-level
operations.
2017-06-25 22:03:46 +09:30
Lewis Baker b46e62553a Avoid nonstandard use of offsetof in file_[read/write]_operation.
Inherit from win32::io_state to make it deterministic how to cast
from io_state* back to the operation.
Fixes a warning when building under Clang.
2017-06-22 22:40:21 +09:30
Lewis Baker b1f8f75960 Add traits and operator-> to recursive_generator<T>::iterator. 2017-06-16 22:41:00 +09:30
Lewis Baker c32cc801b4 Add deleted await_transform() to generator/recursive_generator.
This prevents use of co_await within generator coroutines.
2017-06-16 09:02:28 +09:30
Lewis Baker 6247291b86 Add cppcoro::recursive_generator 2017-06-16 06:42:40 +09:30
Lewis Baker 40c6216266 Add cppcoro::generator<T>. 2017-06-12 23:23:55 +09:30
Lewis Baker 90642dc130 Fix get_return_object() of task/lazy_task promise under clang.
Clang didn't seem to allow conversion from get_return_object()
return value to coroutine return value via explicit constructor.

Now get_return_object() explicitly constructs task/lazy_task object
rather than returning coroutine_handle. This required moving
method definition to below task/lazy_task class definition.
2017-06-11 22:06:40 +09:30
Lewis Baker a270518e27 Use this-> when referencing members of template base-class.
Fixes some compilation errors under Clang.
2017-06-11 22:02:29 +09:30
Lewis Baker 5ea2225efe Use <experimental/filesystem> instead of <filesystem>
Clang's libc++ doesn't yet have a <filesystem> header.
2017-06-11 21:48:45 +09:30
Lewis Baker 2e7a0b6c03 Remove use of reinterpret_cast in constexpr expression. 2017-06-11 21:44:47 +09:30