object_call_issue.hpp

Go to the documentation of this file.
00001 /*
00002 This file is part of GraphLab.
00003 
00004 GraphLab is free software: you can redistribute it and/or modify
00005 it under the terms of the GNU Lesser General Public License as 
00006 published by the Free Software Foundation, either version 3 of 
00007 the License, or (at your option) any later version.
00008 
00009 GraphLab is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public 
00015 License along with GraphLab.  If not, see <http://www.gnu.org/licenses/>.
00016 */
00017 
00018 #ifndef OBJECT_CALL_ISSUE_HPP
00019 #define OBJECT_CALL_ISSUE_HPP
00020 #include <iostream>
00021 #include <graphlab/serialization/serialization_includes.hpp>
00022 #include <graphlab/rpc/dc_types.hpp>
00023 #include <graphlab/rpc/dc_internal_types.hpp>
00024 #include <graphlab/rpc/dc_send.hpp>
00025 #include <graphlab/rpc/object_call_dispatch.hpp>
00026 #include <graphlab/rpc/is_rpc_call.hpp>
00027 #include <boost/preprocessor.hpp>
00028 #include <graphlab/rpc/mem_function_arg_types_def.hpp>
00029 
00030 namespace graphlab{
00031 namespace dc_impl {
00032 
00033 /**
00034 \ingroup rpc_internal
00035 \file
00036  This is an internal function and should not be used directly
00037 
00038 Marshalls a object function call to a remote machine. 
00039 This is similar to the regular function call in function_call_issue.hpp
00040 with the only difference that the object id needs to be transmitted as well.
00041 
00042 \code
00043 template<typename T, 
00044         typename F , 
00045         typename T0> class object_call_issue1
00046 {
00047     public: static void exec(dc_send* sender, 
00048                             unsigned char flags, 
00049                             procid_t target, 
00050                             size_t objid, 
00051                             F remote_function , 
00052                             const T0 &i0 )
00053     {
00054         boost::iostreams::stream<resizing_array_sink> strm(128);
00055         oarchive arc(strm);
00056         dispatch_type d = dc_impl::OBJECT_NONINTRUSIVE_DISPATCH1<distributed_control,T,F , T0 >;
00057         arc << reinterpret_cast<size_t>(d);
00058         serialize(arc, (char*)(&remote_function), sizeof(F));
00059         arc << objid;
00060         arc << i0;
00061         strm.flush();
00062         sender->send_data(target,flags , strm->str, strm->len);
00063     }
00064 };
00065 \endcode
00066 */
00067 
00068 #define GENARGS(Z,N,_)  BOOST_PP_CAT(const T, N) BOOST_PP_CAT(&i, N)
00069 #define GENI(Z,N,_) BOOST_PP_CAT(i, N)
00070 #define GENT(Z,N,_) BOOST_PP_CAT(T, N)
00071 #define GENARC(Z,N,_) arc << BOOST_PP_CAT(i, N);
00072 
00073 
00074 /**
00075 The dispatch_selectorN structs are used to pick between the standard dispatcher and the nonintrusive dispatch
00076 by checking if the function is a RPC style call or not.
00077 */
00078 #define REMOTE_CALL_ISSUE_GENERATOR(Z,N,FNAME_AND_CALL) \
00079 template<typename T, typename F BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, typename T)> \
00080 class  BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,FNAME_AND_CALL), N) { \
00081   public: \
00082   static void exec(dc_dist_object_base* rmi, dc_send* sender, unsigned char flags, procid_t target, size_t objid, F remote_function BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N,GENARGS ,_) ) {  \
00083     boost::iostreams::stream<resizing_array_sink_ref> &strm = get_thread_local_stream();    \
00084     oarchive arc(strm);                         \
00085     dispatch_type d = BOOST_PP_CAT(dc_impl::OBJECT_NONINTRUSIVE_DISPATCH,N)<distributed_control,T,F BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM(N, GENT ,_) >;   \
00086     arc << reinterpret_cast<size_t>(d);       \
00087     serialize(arc, (char*)(&remote_function), sizeof(F)); \
00088     arc << objid;       \
00089     BOOST_PP_REPEAT(N, GENARC, _)                \
00090     strm.flush();           \
00091     sender->send_data(target,flags , strm->c_str(), strm->size());    \
00092     if ((flags & CONTROL_PACKET) == 0)                       \
00093       rmi->inc_bytes_sent(target, strm->size());           \
00094   }\
00095 }; 
00096 
00097 
00098 
00099 /**
00100 Generates a function call issue. 3rd argument is a tuple (issue name, dispacther name)
00101 */
00102 BOOST_PP_REPEAT(6, REMOTE_CALL_ISSUE_GENERATOR,  (object_call_issue, _) )
00103 
00104 
00105 
00106 #undef GENARC
00107 #undef GENT
00108 #undef GENI
00109 #undef GENARGS
00110 #undef REMOTE_CALL_ISSUE_GENERATOR
00111 
00112 } // namespace dc_impl
00113 } // namespace graphlab
00114 
00115 #include <graphlab/rpc/mem_function_arg_types_undef.hpp>
00116 
00117 #endif
00118