@@ -273,42 +273,136 @@ TEST_CASE("Exception.SubflowTask.4threads") {
273273}
274274
275275// ----------------------------------------------------------------------------
276- // Exception.ThreadSafety
276+ // Exception.AsyncTask
277277// ----------------------------------------------------------------------------
278278
279- void thread_safety (unsigned W) {
279+ void async_task_exception (unsigned W) {
280280
281+ // executor async
281282 tf::Executor executor (W);
282- tf::Taskflow taskflow;
283283
284- for (int i=0 ; i<100000 ; i++) {
285- taskflow.emplace ([&](){ throw std::runtime_error (" x" ); });
286- }
284+ auto fu1 = executor.async ([](){
285+ return 1 ;
286+ });
287+ REQUIRE (fu1.get () == 1 );
288+
289+ auto fu2 = executor.async ([](){
290+ throw std::runtime_error (" x" );
291+ });
292+ REQUIRE_THROWS_WITH_AS (fu2.get (), " x" , std::runtime_error);
293+
294+ // exception is caught without any action
295+ executor.silent_async ([](){ std::runtime_error (" y" ); });
287296
288- // thread sanitizer should not report any data race
289- auto fu = executor.run (taskflow);
290- try {
291- fu.get ();
292- }catch (const std::exception& e) {
293- REQUIRE (std::strcmp (e.what (), " x" ) == 0 );
294- }
295- // REQUIRE_THROWS_WITH_AS(executor.run(taskflow).get(), "x", std::runtime_error);
297+ executor.wait_for_all ();
296298}
297299
298- TEST_CASE (" Exception.ThreadSafety .1thread" ) {
299- thread_safety (1 );
300+ TEST_CASE (" Exception.AsyncTask .1thread" ) {
301+ async_task_exception (1 );
300302}
301303
302- TEST_CASE (" Exception.ThreadSafety .2threads" ) {
303- thread_safety (2 );
304+ TEST_CASE (" Exception.AsyncTask .2threads" ) {
305+ async_task_exception (2 );
304306}
305307
306- TEST_CASE (" Exception.ThreadSafety .3threads" ) {
307- thread_safety (3 );
308+ TEST_CASE (" Exception.AsyncTask .3threads" ) {
309+ async_task_exception (3 );
308310}
309311
310- TEST_CASE (" Exception.ThreadSafety .4threads" ) {
311- thread_safety (4 );
312+ TEST_CASE (" Exception.AsyncTask .4threads" ) {
313+ async_task_exception (4 );
312314}
313315
316+ // ----------------------------------------------------------------------------
317+ // Runtime Async Task
318+ // ----------------------------------------------------------------------------
319+
320+ void runtime_async_task_exception (unsigned W) {
321+
322+ // executor async
323+ tf::Executor executor (W);
324+ tf::Taskflow taskflow;
325+ int flag = 0 ;
326+
327+ // runtime async
328+ auto A = taskflow.emplace ([](tf::Runtime& rt){
329+ auto fu1 = rt.async ([](){ return 1 ; });
330+ REQUIRE (fu1.get () == 1 );
331+ auto fu2 = rt.async ([](){ throw std::runtime_error (" z" ); });
332+ REQUIRE_THROWS_WITH_AS (fu2.get (), " z" , std::runtime_error);
333+ });
334+ auto B = taskflow.emplace ([&](){
335+ flag = 1 ;
336+ });
337+ executor.run (taskflow).wait ();
338+ REQUIRE (flag == 1 );
339+
340+ // runtime silent async
341+ flag = 0 ;
342+ taskflow.clear ();
343+ A = taskflow.emplace ([&](tf::Runtime& rt){
344+ rt.silent_async ([&](){ throw std::runtime_error (" a" ); });
345+ rt.join (); // must join to propagate the exception to taskflow
346+ // because async is independent of taskflow
347+ flag = 1 ;
348+ });
349+ B = taskflow.emplace ([&](){
350+ flag = 2 ;
351+ });
352+ A.precede (B);
353+ REQUIRE_THROWS_WITH_AS (executor.run (taskflow).get (), " a" , std::runtime_error);
354+ REQUIRE (flag == 1 );
355+ }
356+
357+ TEST_CASE (" Exception.RuntimeAsyncTask.2threads" ) {
358+ runtime_async_task_exception (2 );
359+ }
360+
361+ TEST_CASE (" Exception.RuntimeAsyncTask.3threads" ) {
362+ runtime_async_task_exception (3 );
363+ }
364+
365+ TEST_CASE (" Exception.RuntimeAsyncTask.4threads" ) {
366+ runtime_async_task_exception (4 );
367+ }
368+
369+ // // ----------------------------------------------------------------------------
370+ // // Exception.ThreadSafety
371+ // // ----------------------------------------------------------------------------
372+ //
373+ // void thread_safety(unsigned W) {
374+ //
375+ // tf::Executor executor(W);
376+ // tf::Taskflow taskflow;
377+ //
378+ // for(int i=0; i<100000; i++) {
379+ // taskflow.emplace([&](){ throw std::runtime_error("x"); });
380+ // }
381+ //
382+ // // thread sanitizer should not report any data race
383+ // auto fu = executor.run(taskflow);
384+ // try {
385+ // fu.get();
386+ // }catch(const std::exception& e) {
387+ // REQUIRE(std::strcmp(e.what(), "x") == 0);
388+ // }
389+ // //REQUIRE_THROWS_WITH_AS(executor.run(taskflow).get(), "x", std::runtime_error);
390+ // }
391+ //
392+ // TEST_CASE("Exception.ThreadSafety.1thread") {
393+ // thread_safety(1);
394+ // }
395+ //
396+ // TEST_CASE("Exception.ThreadSafety.2threads") {
397+ // thread_safety(2);
398+ // }
399+ //
400+ // TEST_CASE("Exception.ThreadSafety.3threads") {
401+ // thread_safety(3);
402+ // }
403+ //
404+ // TEST_CASE("Exception.ThreadSafety.4threads") {
405+ // thread_safety(4);
406+ // }
407+
314408
0 commit comments