Skip to content

Commit

Permalink
Merge branch 'hotfix/macos-crash-on-exit-asio-destructor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rsjaffe committed Nov 12, 2021
2 parents 43e041a + 31cc445 commit 620affd
Show file tree
Hide file tree
Showing 20 changed files with 262 additions and 34 deletions.
2 changes: 1 addition & 1 deletion MIDI2LR.jucer
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="jqaeel" name="MIDI2LR" projectType="guiapp" version="5.1.0.0"
<JUCERPROJECT id="jqaeel" name="MIDI2LR" projectType="guiapp" version="5.1.1.0"
bundleIdentifier="com.rsjaffe.MIDI2LR" includeBinaryInAppConfig="1"
companyWebsite="http://rsjaffe.github.io/MIDI2LR/" companyEmail="rsjaffe@gmail.com"
displaySplashScreen="0" reportAppUsage="0" splashScreenColour="Dark"
Expand Down
4 changes: 2 additions & 2 deletions build/MacOS/Info-App.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>5.1.0.0</string>
<string>5.1.1.0</string>
<key>CFBundleVersion</key>
<string>5.1.0.0</string>
<string>5.1.1.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (C) 2015 by Rory Jaffe.</string>
<key>NSHighResolutionCapable</key>
Expand Down
8 changes: 4 additions & 4 deletions build/MacOS/MIDI2LR.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -515,8 +515,8 @@
"JUCE_STANDALONE_APPLICATION=1",
"JUCE_MODAL_LOOPS_PERMITTED=1",
"JUCER_XCODE_MAC_46BB2872=1",
"JUCE_APP_VERSION=5.1.0.0",
"JUCE_APP_VERSION_HEX=0x5010000",
"JUCE_APP_VERSION=5.1.1.0",
"JUCE_APP_VERSION_HEX=0x5010100",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
Expand Down Expand Up @@ -645,8 +645,8 @@
"JUCE_STANDALONE_APPLICATION=1",
"JUCE_MODAL_LOOPS_PERMITTED=1",
"JUCER_XCODE_MAC_46BB2872=1",
"JUCE_APP_VERSION=5.1.0.0",
"JUCE_APP_VERSION_HEX=0x5010000",
"JUCE_APP_VERSION=5.1.1.0",
"JUCE_APP_VERSION_HEX=0x5010100",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
Expand Down
4 changes: 2 additions & 2 deletions build/Windows/MIDI2LR_App.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<Optimization>Disabled</Optimization>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\..\external\JuceLibraryCode;..\..\external\JuceLibraryCode\modules;../../external/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60102;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_WINRT_MIDI=0;JUCE_ASIO=0;JUCE_WASAPI=0;JUCE_DIRECTSOUND=0;JUCE_ALSA=0;JUCE_JACK=0;JUCE_BELA=0;JUCE_USE_ANDROID_OBOE=0;JUCE_USE_ANDROID_OPENSLES=0;JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS=0;JUCE_FORCE_DEBUG=0;JUCE_LOG_ASSERTIONS=0;JUCE_CATCH_UNHANDLED_EXCEPTIONS=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;_WIN32_WINNT=0x0A000007;WINVER=0x0A000007;NOMINMAX;WIN32_LEAN_AND_MEAN;JUCE_MODAL_LOOPS_PERMITTED=1;JUCER_VS2019_A3DCEFC2=1;JUCE_APP_VERSION=5.1.0.0;JUCE_APP_VERSION_HEX=0x5010000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60102;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_WINRT_MIDI=0;JUCE_ASIO=0;JUCE_WASAPI=0;JUCE_DIRECTSOUND=0;JUCE_ALSA=0;JUCE_JACK=0;JUCE_BELA=0;JUCE_USE_ANDROID_OBOE=0;JUCE_USE_ANDROID_OPENSLES=0;JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS=0;JUCE_FORCE_DEBUG=0;JUCE_LOG_ASSERTIONS=0;JUCE_CATCH_UNHANDLED_EXCEPTIONS=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;_WIN32_WINNT=0x0A000007;WINVER=0x0A000007;NOMINMAX;WIN32_LEAN_AND_MEAN;JUCE_MODAL_LOOPS_PERMITTED=1;JUCER_VS2019_A3DCEFC2=1;JUCE_APP_VERSION=5.1.1.0;JUCE_APP_VERSION_HEX=0x5010100;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
Expand Down Expand Up @@ -105,7 +105,7 @@
<ClCompile>
<Optimization>Full</Optimization>
<AdditionalIncludeDirectories>..\..\external\JuceLibraryCode;..\..\external\JuceLibraryCode\modules;../../external/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60102;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_WINRT_MIDI=0;JUCE_ASIO=0;JUCE_WASAPI=0;JUCE_DIRECTSOUND=0;JUCE_ALSA=0;JUCE_JACK=0;JUCE_BELA=0;JUCE_USE_ANDROID_OBOE=0;JUCE_USE_ANDROID_OPENSLES=0;JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS=0;JUCE_FORCE_DEBUG=0;JUCE_LOG_ASSERTIONS=0;JUCE_CATCH_UNHANDLED_EXCEPTIONS=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;_WIN32_WINNT=0x0A000007;WINVER=0x0A000007;NOMINMAX;WIN32_LEAN_AND_MEAN;JUCE_MODAL_LOOPS_PERMITTED=1;JUCER_VS2019_A3DCEFC2=1;JUCE_APP_VERSION=5.1.0.0;JUCE_APP_VERSION_HEX=0x5010000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60102;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_WINRT_MIDI=0;JUCE_ASIO=0;JUCE_WASAPI=0;JUCE_DIRECTSOUND=0;JUCE_ALSA=0;JUCE_JACK=0;JUCE_BELA=0;JUCE_USE_ANDROID_OBOE=0;JUCE_USE_ANDROID_OPENSLES=0;JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS=0;JUCE_FORCE_DEBUG=0;JUCE_LOG_ASSERTIONS=0;JUCE_CATCH_UNHANDLED_EXCEPTIONS=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;_WIN32_WINNT=0x0A000007;WINVER=0x0A000007;NOMINMAX;WIN32_LEAN_AND_MEAN;JUCE_MODAL_LOOPS_PERMITTED=1;JUCER_VS2019_A3DCEFC2=1;JUCE_APP_VERSION=5.1.1.0;JUCE_APP_VERSION_HEX=0x5010100;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
Expand Down
6 changes: 3 additions & 3 deletions build/Windows/resources.rc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <windows.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION 5,1,0,0
FILEVERSION 5,1,1,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
Expand All @@ -18,9 +18,9 @@ BEGIN
VALUE "CompanyName", "Rory Jaffe\0"
VALUE "LegalCopyright", "Copyright (C) 2015 by Rory Jaffe.\0"
VALUE "FileDescription", "MIDI2LR\0"
VALUE "FileVersion", "5.1.0.0\0"
VALUE "FileVersion", "5.1.1.0\0"
VALUE "ProductName", "MIDI2LR\0"
VALUE "ProductVersion", "5.1.0.0\0"
VALUE "ProductVersion", "5.1.1.0\0"
END
END

Expand Down
4 changes: 2 additions & 2 deletions external/JuceLibraryCode/JuceHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace ProjectInfo
{
const char* const projectName = "MIDI2LR";
const char* const companyName = "Rory Jaffe";
const char* const versionString = "5.1.0.0";
const int versionNumber = 0x5010000;
const char* const versionString = "5.1.1.0";
const int versionNumber = 0x5010100;
}
#endif
2 changes: 1 addition & 1 deletion external/asio/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ asio

latest version downloaded https://github.com/chriskohlhoff/asio/releases

1.19.2 August 25 2021
1.20.0 November 12 2021
50 changes: 49 additions & 1 deletion external/asio/asio/cancellation_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,38 @@ class cancellation_state
}

/// Construct and attach to a parent slot to create a new child slot.
/**
* Initialises the cancellation state so that it allows terminal cancellation
* only. Equivalent to <tt>cancellation_state(slot,
* enable_terminal_cancellation())</tt>.
*
* @param slot The parent cancellation slot to which the state will be
* attached.
*/
template <typename CancellationSlot>
ASIO_CONSTEXPR explicit cancellation_state(CancellationSlot slot)
: impl_(slot.is_connected() ? &slot.template emplace<impl<> >() : 0)
{
}

/// Construct and attach to a parent slot to create a new child slot.
/**
* @param slot The parent cancellation slot to which the state will be
* attached.
*
* @param filter A function object that is used to transform incoming
* cancellation signals as they are received from the parent slot. This
* function object must have the signature:
* @code asio::cancellation_type_t filter(
* asio::cancellation_type_t); @endcode
*
* The library provides the following pre-defined cancellation filters:
*
* @li asio::disable_cancellation
* @li asio::enable_terminal_cancellation
* @li asio::enable_partial_cancellation
* @li asio::enable_total_cancellation
*/
template <typename CancellationSlot, typename Filter>
ASIO_CONSTEXPR cancellation_state(CancellationSlot slot, Filter filter)
: impl_(slot.is_connected()
Expand All @@ -102,6 +127,29 @@ class cancellation_state
}

/// Construct and attach to a parent slot to create a new child slot.
/**
* @param slot The parent cancellation slot to which the state will be
* attached.
*
* @param in_filter A function object that is used to transform incoming
* cancellation signals as they are received from the parent slot. This
* function object must have the signature:
* @code asio::cancellation_type_t in_filter(
* asio::cancellation_type_t); @endcode
*
* @param out_filter A function object that is used to transform outcoming
* cancellation signals as they are relayed to the child slot. This function
* object must have the signature:
* @code asio::cancellation_type_t out_filter(
* asio::cancellation_type_t); @endcode
*
* The library provides the following pre-defined cancellation filters:
*
* @li asio::disable_cancellation
* @li asio::enable_terminal_cancellation
* @li asio::enable_partial_cancellation
* @li asio::enable_total_cancellation
*/
template <typename CancellationSlot, typename InFilter, typename OutFilter>
ASIO_CONSTEXPR cancellation_state(CancellationSlot slot,
InFilter in_filter, OutFilter out_filter)
Expand All @@ -122,7 +170,7 @@ class cancellation_state
return impl_ ? impl_->signal_.slot() : cancellation_slot();
}

/// Returns specified cancellation types have been triggered.
/// Returns the cancellation types that have been triggered.
cancellation_type_t cancelled() const ASIO_NOEXCEPT
{
return impl_ ? impl_->cancelled_ : cancellation_type_t();
Expand Down
32 changes: 30 additions & 2 deletions external/asio/asio/co_spawn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ struct awaitable_signature<awaitable<void, Executor>>
* std::cout << "transferred " << n << "\n";
* });
* @endcode
*
* @par Per-Operation Cancellation
* The new thread of execution is created with a cancellation state that
* supports @c cancellation_type::terminal values only. To change the
* cancellation state, call asio::this_coro::reset_cancellation_state.
*/
template <typename Executor, typename T, typename AwaitableExecutor,
ASIO_COMPLETION_TOKEN_FOR(
Expand Down Expand Up @@ -151,6 +156,11 @@ co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a,
* echo(std::move(my_tcp_socket)),
* asio::detached);
* @endcode
*
* @par Per-Operation Cancellation
* The new thread of execution is created with a cancellation state that
* supports @c cancellation_type::terminal values only. To change the
* cancellation state, call asio::this_coro::reset_cancellation_state.
*/
template <typename Executor, typename AwaitableExecutor,
ASIO_COMPLETION_TOKEN_FOR(
Expand Down Expand Up @@ -215,6 +225,11 @@ co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a,
* std::cout << "transferred " << n << "\n";
* });
* @endcode
*
* @par Per-Operation Cancellation
* The new thread of execution is created with a cancellation state that
* supports @c cancellation_type::terminal values only. To change the
* cancellation state, call asio::this_coro::reset_cancellation_state.
*/
template <typename ExecutionContext, typename T, typename AwaitableExecutor,
ASIO_COMPLETION_TOKEN_FOR(
Expand Down Expand Up @@ -274,6 +289,11 @@ co_spawn(ExecutionContext& ctx, awaitable<T, AwaitableExecutor> a,
* echo(std::move(my_tcp_socket)),
* asio::detached);
* @endcode
*
* @par Per-Operation Cancellation
* The new thread of execution is created with a cancellation state that
* supports @c cancellation_type::terminal values only. To change the
* cancellation state, call asio::this_coro::reset_cancellation_state.
*/
template <typename ExecutionContext, typename AwaitableExecutor,
ASIO_COMPLETION_TOKEN_FOR(
Expand Down Expand Up @@ -309,7 +329,6 @@ co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a,
* Otherwise, the function signature of the completion handler must be:
* @code void handler(std::exception_ptr, R); @endcode
*
*
* @par Example
* @code
* asio::awaitable<std::size_t> echo(tcp::socket socket)
Expand Down Expand Up @@ -361,6 +380,11 @@ co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a,
* }
* }, asio::detached);
* @endcode
*
* @par Per-Operation Cancellation
* The new thread of execution is created with a cancellation state that
* supports @c cancellation_type::terminal values only. To change the
* cancellation state, call asio::this_coro::reset_cancellation_state.
*/
template <typename Executor, typename F,
ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
Expand Down Expand Up @@ -392,7 +416,6 @@ co_spawn(const Executor& ex, F&& f,
* Otherwise, the function signature of the completion handler must be:
* @code void handler(std::exception_ptr, R); @endcode
*
*
* @par Example
* @code
* asio::awaitable<std::size_t> echo(tcp::socket socket)
Expand Down Expand Up @@ -444,6 +467,11 @@ co_spawn(const Executor& ex, F&& f,
* }
* }, asio::detached);
* @endcode
*
* @par Per-Operation Cancellation
* The new thread of execution is created with a cancellation state that
* supports @c cancellation_type::terminal values only. To change the
* cancellation state, call asio::this_coro::reset_cancellation_state.
*/
template <typename ExecutionContext, typename F,
ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
Expand Down
2 changes: 1 addition & 1 deletion external/asio/asio/experimental/coro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ struct coro_promise final :
}

template <execution_context Context, typename... Args>
coro_promise(Context& ctx, Args &&...) noexcept
coro_promise(Context&& ctx, Args&&...) noexcept
: executor_(ctx.get_executor())
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct coro_promise_allocator
}

template <execution_context Context, typename... Args>
void* operator new(const std::size_t size, Context& ctx, Args&&... args)
void* operator new(const std::size_t size, Context&& ctx, Args&&... args)
{
return coro_promise_allocator::operator new(size,
ctx.get_executor(), std::forward<Args>(args)...);
Expand Down Expand Up @@ -89,7 +89,7 @@ struct coro_promise_allocator<Coroutine, Executor, Allocator, true>

template <execution_context Context, typename... Args>
void* operator new(const std::size_t size,
Context& ctx, Args&&... args) noexcept
Context&& ctx, Args&&... args) noexcept
{
return coro_promise_allocator::operator new(size,
ctx.get_executor(), std::forward<Args>(args)...);
Expand Down
5 changes: 3 additions & 2 deletions external/asio/asio/experimental/detail/partial_promise.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ namespace std {

template<typename ... Args>
struct coroutine_traits<
std::experimental::coroutine_handle<coro::partial_promise>, Args...>
coroutine_handle<asio::experimental::detail::partial_promise>,
Args...>
{
using promise_type = coro::partial_promise;
using promise_type = asio::experimental::detail::partial_promise;
};

} // namespace std
Expand Down
61 changes: 61 additions & 0 deletions external/asio/asio/experimental/parallel_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ void parallel_group_launch(Condition cancellation_condition, Handler handler,
} // namespace detail

/// A group of asynchronous operations that may be launched in parallel.
/**
* See the documentation for asio::experimental::make_parallel_group for
* a usage example.
*/
template <typename... Ops>
class parallel_group
{
Expand All @@ -113,6 +117,27 @@ class parallel_group
typename detail::parallel_op_signature<Ops>::type...>::type signature;

/// Initiate an asynchronous wait for the group of operations.
/**
* Launches the group and asynchronously waits for completion.
*
* @param cancellation_condition A function object, called on completion of
* an operation within the group, that is used to determine whether to cancel
* the remaining operations. The function object is passed the arguments of
* the completed operation's handler. To trigger cancellation of the remaining
* operations, it must return a asio::cancellation_type value other
* than <tt>asio::cancellation_type::none</tt>.
*
* @param token A completion token whose signature is comprised of
* a @c std::array<std::size_t, N> indicating the completion order of the
* operations, followed by all operations' completion handler arguments.
*
* The library provides the following @c cancellation_condition types:
*
* @li asio::experimental::wait_for_all
* @li asio::experimental::wait_for_one
* @li asio::experimental::wait_for_one_error
* @li asio::experimental::wait_for_one_success
*/
template <typename CancellationCondition,
ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>
auto async_wait(CancellationCondition cancellation_condition,
Expand All @@ -138,6 +163,42 @@ class parallel_group
};

/// Create a group of operations that may be launched in parallel.
/**
* For example:
* @code asio::experimental::make_parallel_group(
* [&](auto token)
* {
* return in.async_read_some(asio::buffer(data), token);
* },
* [&](auto token)
* {
* return timer.async_wait(token);
* }
* ).async_wait(
* asio::experimental::wait_for_all(),
* [](
* std::array<std::size_t, 2> completion_order,
* std::error_code ec1, std::size_t n1,
* std::error_code ec2
* )
* {
* switch (completion_order[0])
* {
* case 0:
* {
* std::cout << "descriptor finished: " << ec1 << ", " << n1 << "\n";
* }
* break;
* case 1:
* {
* std::cout << "timer finished: " << ec2 << "\n";
* }
* break;
* }
* }
* );
* @endcode
*/
template <typename... Ops>
inline parallel_group<Ops...> make_parallel_group(Ops... ops)
{
Expand Down
Loading

0 comments on commit 620affd

Please sign in to comment.