MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/http/coroutine.hpp
00001 //
00002 // boost/rpc/http/coroutine.hpp
00003 // ~~~~~~~~~~~~~
00004 //
00005 // This file was modified from boost/asio/examples/http/server4 and its original
00006 // copyright notice is below.
00007 //
00008 // Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00009 //
00010 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00011 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00012 //
00013 
00014 #ifndef MACE_RPC_HTTP_COROUTINE_HPP
00015 #define MACE_RPC_HTTP_COROUTINE_HPP
00016 
00017 namespace mace { namespace rpc { namespace http {
00018 
00019 class coroutine
00020 {
00021 public:
00022   coroutine() : value_(0) {}
00023   bool is_child() const { return value_ < 0; }
00024   bool is_parent() const { return !is_child(); }
00025   bool is_complete() const { return value_ == -1; }
00026 private:
00027   friend class coroutine_ref;
00028   int value_;
00029 };
00030 
00031 class coroutine_ref
00032 {
00033 public:
00034   coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}
00035   coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}
00036   ~coroutine_ref() { if (!modified_) value_ = -1; }
00037   operator int() const { return value_; }
00038   int& operator=(int v) { modified_ = true; return value_ = v; }
00039 private:
00040   void operator=(const coroutine_ref&);
00041   int& value_;
00042   bool modified_;
00043 };
00044 
00045 #define CORO_REENTER(c) \
00046   switch (coroutine_ref _coro_value = c) \
00047     case -1: if (_coro_value) \
00048     { \
00049       goto terminate_coroutine; \
00050       terminate_coroutine: \
00051       _coro_value = -1; \
00052       goto bail_out_of_coroutine; \
00053       bail_out_of_coroutine: \
00054       break; \
00055     } \
00056     else case 0:
00057 
00058 #define CORO_YIELD_IMPL(n) \
00059   for (_coro_value = (n);;) \
00060     if (_coro_value == 0) \
00061     { \
00062       case (n): ; \
00063       break; \
00064     } \
00065     else \
00066       switch (_coro_value ? 0 : 1) \
00067         for (;;) \
00068           case -1: if (_coro_value) \
00069             goto terminate_coroutine; \
00070           else for (;;) \
00071             case 1: if (_coro_value) \
00072               goto bail_out_of_coroutine; \
00073             else case 0:
00074 
00075 #define CORO_FORK_IMPL(n) \
00076   for (_coro_value = -(n);; _coro_value = (n)) \
00077     if (_coro_value == (n)) \
00078     { \
00079       case -(n): ; \
00080       break; \
00081     } \
00082     else
00083 
00084 #if defined(_MSC_VER)
00085 # define CORO_YIELD CORO_YIELD_IMPL(__COUNTER__ + 1)
00086 # define CORO_FORK CORO_FORK_IMPL(__COUNTER__ + 1)
00087 #else // defined(_MSC_VER)
00088 # define CORO_YIELD CORO_YIELD_IMPL(__LINE__)
00089 # define CORO_FORK CORO_FORK_IMPL(__LINE__)
00090 #endif // defined(_MSC_VER)
00091 
00092 } } } // boost::rpc::http
00093 
00094 #endif // COROUTINE_HPP