00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef PORTABLE_DISPATCH_HPP
00019 #define PORTABLE_DISPATCH_HPP
00020 #include <string>
00021 #include <boost/unordered_map.hpp>
00022 #include <boost/preprocessor.hpp>
00023 #include <graphlab/rpc/dc_internal_types.hpp>
00024 #include <graphlab/rpc/function_call_dispatch.hpp>
00025 #include <graphlab/rpc/request_dispatch.hpp>
00026 #include <graphlab/util/generics/any.hpp>
00027 #include <graphlab/rpc/portable.hpp>
00028 #include <graphlab/rpc/function_ret_type.hpp>
00029 #include <graphlab/rpc/function_arg_types_def.hpp>
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 namespace graphlab {
00056
00057
00058 namespace dc_impl {
00059
00060 namespace portable_detail {
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 template<typename F, typename Fret, size_t Nargs, F f, typename IsRPCCall>
00071 struct find_dispatcher{
00072 static void* dispatch_call_fn() { return NULL; }
00073 static void* dispatch_request_fn() { return NULL; }
00074 };
00075 };
00076
00077 #define GENFN(N) BOOST_PP_CAT(__GLRPC_F, N)
00078 #define GENFN2(N) BOOST_PP_CAT(f, N)
00079 #define GENARGS(Z,N,_) BOOST_PP_CAT(__GLRPC_F, N)(BOOST_PP_CAT(f, N))
00080 #define GENPARAMS(Z,N,_) BOOST_PP_CAT(T, N) (BOOST_PP_CAT(f, N)) ; iarc >> (BOOST_PP_CAT(f, N)) ;
00081 #define CHARSTRINGFREE(Z,N,_) charstring_free(BOOST_PP_CAT(f, N));
00082
00083
00084 #define GENNIARGS(Z,N,_) BOOST_PP_CAT(__GLRPC_NIF, N)(BOOST_PP_CAT(f, N))
00085
00086
00087 #define PORTABLE_DISPATCH_GENERATOR(Z,N,_) \
00088 template<typename DcType, typename F, F f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
00089 void BOOST_PP_CAT(PORTABLEDISPATCH,N) (DcType& dc, procid_t source, unsigned char packet_type_mask, \
00090 std::istream &strm) { \
00091 iarchive iarc(strm); \
00092 BOOST_PP_REPEAT(N, GENPARAMS, _) \
00093 f(dc, source BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N,GENARGS ,_) ); \
00094 BOOST_PP_REPEAT(N, CHARSTRINGFREE, _) \
00095 } \
00096 \
00097 template<typename DcType, typename F, F f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
00098 void BOOST_PP_CAT(PORTABLE_REQUESTDISPATCH,N) (DcType& dc, procid_t source, unsigned char packet_type_mask, \
00099 std::istream &strm) { \
00100 iarchive iarc(strm); \
00101 size_t id; iarc >> id; \
00102 BOOST_PP_REPEAT(N, GENPARAMS, _) \
00103 typename function_ret_type<__GLRPC_FRESULT>::type ret = function_ret_type<__GLRPC_FRESULT>::BOOST_PP_CAT(fcall, BOOST_PP_ADD(N, 2)) \
00104 (f, dc, source BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N,GENARGS ,_)); \
00105 BOOST_PP_REPEAT(N, CHARSTRINGFREE, _) \
00106 boost::iostreams::stream<resizing_array_sink> retstrm(128); \
00107 oarchive oarc(retstrm); \
00108 oarc << ret; \
00109 retstrm.flush(); \
00110 if (packet_type_mask & CONTROL_PACKET) { \
00111 dc.control_call(source, PORTABLE(reply_increment_counter), id, blob(retstrm->str, retstrm->len));\
00112 } \
00113 else { \
00114 dc.fast_remote_call(source, PORTABLE(reply_increment_counter), id, blob(retstrm->str, retstrm->len));\
00115 } \
00116 } \
00117 \
00118 template<typename DcType, typename F, F f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
00119 void BOOST_PP_CAT(PORTABLE_NONINTRUSIVE_DISPATCH,N) (DcType& dc, procid_t source, unsigned char packet_type_mask, \
00120 std::istream &strm) { \
00121 iarchive iarc(strm); \
00122 BOOST_PP_REPEAT(N, GENPARAMS, _) \
00123 f(BOOST_PP_ENUM(N,GENNIARGS ,_) ); \
00124 BOOST_PP_REPEAT(N, CHARSTRINGFREE, _) \
00125 } \
00126 \
00127 template<typename DcType, typename F, F f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
00128 void BOOST_PP_CAT(PORTABLE_NONINTRUSIVE_REQUESTDISPATCH,N) (DcType& dc, procid_t source, unsigned char packet_type_mask, \
00129 std::istream &strm) { \
00130 iarchive iarc(strm); \
00131 size_t id; iarc >> id; \
00132 BOOST_PP_REPEAT(N, GENPARAMS, _) \
00133 typename function_ret_type<__GLRPC_FRESULT>::type ret = function_ret_type<__GLRPC_FRESULT>::BOOST_PP_CAT(fcall, N) \
00134 (f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N,GENNIARGS ,_)); \
00135 BOOST_PP_REPEAT(N, CHARSTRINGFREE, _) \
00136 boost::iostreams::stream<resizing_array_sink> retstrm(128); \
00137 oarchive oarc(retstrm); \
00138 oarc << ret; \
00139 retstrm.flush(); \
00140 if (packet_type_mask & CONTROL_PACKET) { \
00141 dc.control_call(source, PORTABLE(reply_increment_counter), id, blob(retstrm->str, retstrm->len));\
00142 } \
00143 else { \
00144 dc.fast_remote_call(source, PORTABLE(reply_increment_counter), id, blob(retstrm->str, retstrm->len));\
00145 } \
00146 free(retstrm->str); \
00147 }
00148
00149
00150
00151
00152 BOOST_PP_REPEAT(BOOST_PP_INC(6), PORTABLE_DISPATCH_GENERATOR, _)
00153
00154 #undef GENFN
00155 #undef GENFN2
00156 #undef GENARGS
00157 #undef GENPARAMS
00158 #undef GENNIARGS
00159 #undef DISPATCH_GENERATOR
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 #define GENFN(Z,N,_) BOOST_PP_EXPAND(BOOST_PP_CAT(__GLRPC_F, N))
00178 #define GENNIFN(Z,N,_) BOOST_PP_EXPAND(BOOST_PP_CAT(__GLRPC_NIF, N))
00179
00180 namespace portable_detail {
00181
00182 #define PORTABLE_FIND_DISPATCH_GENERATOR(Z, N, _) \
00183 template<typename F, typename Fret, F f, typename IsRPCCall> \
00184 struct find_dispatcher<F, Fret, N, f, IsRPCCall>{ \
00185 static dispatch_type dispatch_call_fn() { \
00186 return BOOST_PP_CAT(PORTABLE_NONINTRUSIVE_DISPATCH, N)<distributed_control, F, f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N, GENNIFN, _)>; \
00187 } \
00188 static dispatch_type dispatch_request_fn() { \
00189 return BOOST_PP_CAT(PORTABLE_NONINTRUSIVE_REQUESTDISPATCH, N)<distributed_control, F, f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N, GENNIFN, _)>; \
00190 } \
00191 }; \
00192 \
00193 template<typename F, typename Fret, F f> \
00194 struct find_dispatcher<F, Fret, BOOST_PP_ADD(N, 2), f, boost::mpl::bool_<true> >{ \
00195 static dispatch_type dispatch_call_fn() { \
00196 return BOOST_PP_CAT(PORTABLEDISPATCH, N)<distributed_control, F, f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N, GENFN, _)>; \
00197 } \
00198 static dispatch_type dispatch_request_fn() { \
00199 return BOOST_PP_CAT(PORTABLE_REQUESTDISPATCH, N)<distributed_control, F, f BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N, GENFN, _)>; \
00200 } \
00201 };
00202 BOOST_PP_REPEAT(6, PORTABLE_FIND_DISPATCH_GENERATOR, _)
00203 #undef PORTABLE_FIND_DISPATCH_GENERATOR
00204 #undef GENFN
00205
00206 }
00207
00208 }
00209 }
00210
00211 #include <graphlab/rpc/function_arg_types_undef.hpp>
00212 #endif
00213