Advertisement
Guest User

async/await emulation in C++

a guest
Sep 13th, 2015
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.11 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. #define COROUTINE_VERSION 2
  4. #define USE_FIBERS 1 /* only for COROUTINE_VERSION == 2 */
  5.  
  6. #if COROUTINE_VERSION == 1
  7. #include <boost/coroutine/all.hpp>
  8.  
  9. using __Coro = boost::coroutines::coroutine<void>;
  10.  
  11. __Coro::pull_type & get_empty_coroutine()
  12. {
  13.     static __Coro::pull_type empty_coroutine;
  14.     return empty_coroutine;
  15. }
  16.  
  17. #endif
  18.  
  19. #if COROUTINE_VERSION == 2
  20.     #if USE_FIBERS == 1
  21.         #define BOOST_USE_WINFIBERS
  22.     #endif
  23. #include <boost/coroutine2/all.hpp>
  24. #include <boost/system/config.hpp>
  25.  
  26. using __Coro = boost::coroutines2::coroutine<void>;
  27.  
  28. __Coro::pull_type & get_empty_coroutine()
  29. {
  30.     static __Coro::pull_type empty_coroutine
  31.     (
  32.         [](__Coro::push_type & /*yield*/)
  33.         {
  34.             return 42;
  35.         }
  36.     );
  37.  
  38.     __Coro::pull_type tmp(std::move(empty_coroutine));
  39.  
  40.     return empty_coroutine;
  41. }
  42.  
  43. #endif
  44.  
  45. #include <boost/lockfree/queue.hpp>
  46. boost::lockfree::queue<__Coro::pull_type *> coroutine_queue(1024);
  47. __Coro::pull_type * get_coroutine()
  48. {
  49.     __Coro::pull_type * result = nullptr;
  50.     bool got_result = coroutine_queue.pop(result);
  51.     return got_result ? result : nullptr;
  52. }
  53.  
  54. void Post2UI(__Coro::pull_type * coro)
  55. {
  56.     bool result = coroutine_queue.push(coro);
  57.     assert(result);
  58. }
  59.  
  60. /*template<typename L> auto __await_async(__Coro::pull_type * coro, __Coro::push_type & yield, L lambda)->decltype(lambda())
  61. {
  62.     auto f = async(launch::async, [=]() {
  63.         auto r = lambda();
  64.         Post2UI(coro);
  65.         return r;
  66.     });
  67.     yield();
  68.     return f.get();
  69. }*/
  70. void CallFromUI(void* c)
  71. {
  72.     auto coro = static_cast<__Coro::pull_type *>(c);
  73.     (*coro)();
  74.     if (!*coro) delete coro;
  75. }
  76.  
  77. #define async_code(block) { __Coro::pull_type * __coro=new __Coro::pull_type(std::move(get_empty_coroutine())); *__coro=__Coro::pull_type([=](__Coro::push_type & __yield){block});}
  78. //#define await_async(l) __await_async(__coro, __yield, l)
  79.  
  80. template<typename L> auto __await_sync(__Coro::pull_type * coro, __Coro::push_type& yield, L lambda)->decltype(lambda())
  81. {
  82.     Post2UI(coro);
  83.     yield();
  84.     return lambda();
  85. }
  86. #define await(l) __await_sync(__coro, __yield, l)
  87.  
  88. //////////////////////////////////////////////////////////////////////////////
  89.  
  90. int CalcSomething(int params) { return params; }
  91. void ProcessResult(int result) { std::cout << result; }
  92.  
  93. void Handler2();
  94.  
  95. void Handler(int params) async_code
  96. (
  97.     for (int i = 0; i != 10; ++i)
  98.     {
  99.         if (i == 5 && params == 1)
  100.         {
  101.             Handler2();
  102.         }
  103.  
  104.         auto r = await
  105.             (
  106.                 [&]
  107.                 {
  108.                     return CalcSomething(params);
  109.                 }
  110.             );
  111.         ProcessResult(r);
  112.     }
  113.     std::cout << "leaving coroutine " << params << std::endl;
  114. )
  115.  
  116. void Handler2()
  117. {
  118.     Handler(2);
  119. }
  120.  
  121. int main()
  122. {
  123.     Handler(1);
  124.  
  125.     for (;;)
  126.     {
  127.         auto * c = get_coroutine();
  128.         if (c)
  129.         {
  130.             std::cout << "G";
  131.             CallFromUI(c);
  132.             std::cout << "g";
  133.         }
  134.         else
  135.         {
  136.             break;
  137.         }
  138.     }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement