You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/27 08:08:39 UTC

svn commit: r1140024 [13/15] - in /incubator/mesos/trunk: ./ ec2/ ec2/deploy.karmic64/ ec2/deploy.solaris/ frameworks/torque/nexus-hpl/ include/mesos/ src/ src/common/ src/configurator/ src/detector/ src/examples/ src/examples/java/ src/examples/python...

Added: incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_generators.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_generators.hpp?rev=1140024&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_generators.hpp (added)
+++ incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_generators.hpp Mon Jun 27 06:08:33 2011
@@ -0,0 +1,19 @@
+// Boost uuid_generators.hpp header file  ----------------------------------------------//
+
+// Copyright 2006 Andy Tompkins.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Revision History
+//  06 Feb 2006 - Initial Revision
+
+#ifndef BOOST_UUID_GENERATORS_HPP
+#define BOOST_UUID_GENERATORS_HPP
+
+#include <boost/uuid/nil_generator.hpp>
+#include <boost/uuid/string_generator.hpp>
+#include <boost/uuid/name_generator.hpp>
+#include <boost/uuid/random_generator.hpp>
+
+#endif //BOOST_UUID_GENERATORS_HPP

Added: incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_io.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_io.hpp?rev=1140024&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_io.hpp (added)
+++ incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_io.hpp Mon Jun 27 06:08:33 2011
@@ -0,0 +1,198 @@
+// Boost uuid_io.hpp header file  ----------------------------------------------//
+
+// Copyright 2009 Andy Tompkins.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Revision History
+//  20 Mar 2009 - Initial Revision
+//  28 Nov 2009 - disabled deprecated warnings for MSVC
+
+#ifndef BOOST_UUID_IO_HPP
+#define BOOST_UUID_IO_HPP
+
+#include <boost/uuid/uuid.hpp>
+#include <ios>
+#include <ostream>
+#include <istream>
+#include <boost/io/ios_state.hpp>
+#include <locale>
+#include <algorithm>
+
+#if defined(_MSC_VER)
+#pragma warning(push) // Save warning settings.
+#pragma warning(disable : 4996) // Disable deprecated std::ctype<char>::widen, std::copy
+#endif
+
+namespace boost {
+namespace uuids {
+
+template <typename ch, typename char_traits>
+    std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch, char_traits> &os, uuid const& u)
+{
+    io::ios_flags_saver flags_saver(os);
+    io::basic_ios_fill_saver<ch, char_traits> fill_saver(os);
+
+    const typename std::basic_ostream<ch, char_traits>::sentry ok(os);
+    if (ok) {
+        const std::streamsize width = os.width(0);
+        const std::streamsize uuid_width = 36;
+        const std::ios_base::fmtflags flags = os.flags();
+        const typename std::basic_ios<ch, char_traits>::char_type fill = os.fill();
+        if (flags & (std::ios_base::right | std::ios_base::internal)) {
+            for (std::streamsize i=uuid_width; i<width; i++) {
+                os << fill;
+            }
+        }
+
+        os << std::hex;
+        os.fill(os.widen('0'));
+
+        std::size_t i=0;
+        for (uuid::const_iterator i_data = u.begin(); i_data!=u.end(); ++i_data, ++i) {
+            os.width(2);
+            os << static_cast<unsigned int>(*i_data);
+            if (i == 3 || i == 5 || i == 7 || i == 9) {
+                os << os.widen('-');
+            }
+        }
+        
+        if (flags & std::ios_base::left) {
+            for (std::streamsize i=uuid_width; i<width; i++) {
+                os << fill;
+            }
+        }
+        
+        os.width(0); //used the width so reset it
+    }
+    return os;
+}
+
+template <typename ch, typename char_traits>
+    std::basic_istream<ch, char_traits>& operator>>(std::basic_istream<ch, char_traits> &is, uuid &u)
+{
+    const typename std::basic_istream<ch, char_traits>::sentry ok(is);
+    if (ok) {
+        unsigned char data[16];
+
+        typedef std::ctype<ch> ctype_t;
+        ctype_t const& ctype = std::use_facet<ctype_t>(is.getloc());
+
+        ch xdigits[16];
+        {
+            char szdigits[] = "0123456789ABCDEF";
+            ctype.widen(szdigits, szdigits+16, xdigits);
+        }
+        ch*const xdigits_end = xdigits+16;
+
+        ch c;
+        for (std::size_t i=0; i<u.size() && is; ++i) {
+            is >> c;
+            c = ctype.toupper(c);
+
+            ch* f = std::find(xdigits, xdigits_end, c);
+            if (f == xdigits_end) {
+                is.setstate(std::ios_base::failbit);
+                break;
+            }
+
+            unsigned char byte = static_cast<unsigned char>(std::distance(&xdigits[0], f));
+
+            is >> c;
+            c = ctype.toupper(c);
+            f = std::find(xdigits, xdigits_end, c);
+            if (f == xdigits_end) {
+                is.setstate(std::ios_base::failbit);
+                break;
+            }
+
+            byte <<= 4;
+            byte |= static_cast<unsigned char>(std::distance(&xdigits[0], f));
+
+            data[i] = byte;
+
+            if (is) {
+                if (i == 3 || i == 5 || i == 7 || i == 9) {
+                    is >> c;
+                    if (c != is.widen('-')) is.setstate(std::ios_base::failbit);
+                }
+            }
+        }
+
+        if (is) {
+            std::copy(data, data+16, u.begin());
+        }
+    }
+    return is;
+}
+
+namespace detail {
+inline char to_char(size_t i) {
+    if (i <= 9) {
+        return static_cast<char>('0' + i);
+    } else {
+        return static_cast<char>('a' + (i-10));
+    }
+}
+
+inline wchar_t to_wchar(size_t i) {
+    if (i <= 9) {
+        return static_cast<wchar_t>(L'0' + i);
+    } else {
+        return static_cast<wchar_t>(L'a' + (i-10));
+    }
+}
+
+} // namespace detail
+
+inline std::string to_string(uuid const& u)
+{
+    std::string result;
+    result.reserve(36);
+
+    std::size_t i=0;
+    for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
+        const size_t hi = ((*it_data) >> 4) & 0x0F;
+        result += detail::to_char(hi);
+
+        const size_t lo = (*it_data) & 0x0F;
+        result += detail::to_char(lo);
+
+        if (i == 3 || i == 5 || i == 7 || i == 9) {
+            result += '-';
+        }
+    }
+    return result;
+}
+
+#ifndef BOOST_NO_STD_WSTRING
+inline std::wstring to_wstring(uuid const& u)
+{
+    std::wstring result;
+    result.reserve(36);
+
+    std::size_t i=0;
+    for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
+        const size_t hi = ((*it_data) >> 4) & 0x0F;
+        result += detail::to_wchar(hi);
+
+        const size_t lo = (*it_data) & 0x0F;
+        result += detail::to_wchar(lo);
+
+        if (i == 3 || i == 5 || i == 7 || i == 9) {
+            result += L'-';
+        }
+    }
+    return result;
+}
+
+#endif
+
+}} //namespace boost::uuids
+
+#if defined(_MSC_VER)
+#pragma warning(pop) // Restore warnings to previous state.
+#endif
+
+#endif // BOOST_UUID_IO_HPP

Added: incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_serialize.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_serialize.hpp?rev=1140024&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_serialize.hpp (added)
+++ incubator/mesos/trunk/third_party/boost-1.37.0/boost/uuid/uuid_serialize.hpp Mon Jun 27 06:08:33 2011
@@ -0,0 +1,20 @@
+// Boost uuid_serialize.hpp header file  ----------------------------------------------//
+
+// Copyright 2007 Andy Tompkins.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Revision History
+//  12 Nov 2007 - Initial Revision
+//  25 Feb 2008 - moved to namespace boost::uuids::detail
+
+#ifndef BOOST_UUID_SERIALIZE_HPP
+#define BOOST_UUID_SERIALIZE_HPP
+
+#include <boost/uuid/uuid.hpp>
+#include <boost/serialization/level.hpp>
+
+BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)
+
+#endif // BOOST_UUID_SERIALIZE_HPP

Modified: incubator/mesos/trunk/third_party/libprocess/Makefile.in
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/Makefile.in?rev=1140024&r1=1140023&r2=1140024&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/Makefile.in (original)
+++ incubator/mesos/trunk/third_party/libprocess/Makefile.in Mon Jun 27 06:08:33 2011
@@ -46,7 +46,9 @@ CXXFLAGS += -MMD -MP
 LDFLAGS += -L. -L$(LIBEV)/.libs
 LIBS += -lprocess -lglog -lev -lpthread
 
-LIBPROCESS_OBJ = src/process.o src/pid.o src/fatal.o src/tokenize.o src/latch.o
+LIBPROCESS_OBJ = src/process.o src/pid.o src/fatal.o src/tokenize.o	\
+                 src/latch.o src/timer.o
+
 LIBPROCESS_LIB = libprocess.a
 
 # Create some testing specific flags.

Added: incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp?rev=1140024&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp (added)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp Mon Jun 27 06:08:33 2011
@@ -0,0 +1,2087 @@
+#ifndef __PROCESS_DISPATCH_HPP__
+#define __PROCESS_DISPATCH_HPP__
+
+#include <process/process.hpp>
+
+// Provides "dispatch" abiltiies for a process. That is, given a local
+// (i.e., typed) pid, one can dispatch a method to it more naturally
+// then sending a string and some bytes of data. This provides better
+// type safety.
+
+namespace process {
+
+/**
+ * Dispatches a void method on a process.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on receiver
+ */
+template <typename T>
+void dispatch(const PID<T>& pid,
+              void (T::*method)());
+
+template <typename T>
+void dispatch(const Process<T>& process,
+              void (T::*method)());
+
+template <typename T>
+void dispatch(const Process<T>* process,
+              void (T::*method)());
+
+
+/**
+ * Dispatches a void method on a process.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 argument to pass to method
+ */
+template <typename T, typename P1, typename A1>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1),
+              A1 a1);
+
+template <typename T, typename P1, typename A1>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1),
+              A1 a1);
+
+template <typename T, typename P1, typename A1>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1),
+              A1 a1);
+
+
+/**
+ * Dispatches a void method on a process.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ */
+template <typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2),
+              A1 a1, A2 a2);
+
+template <typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2),
+              A1 a1, A2 a2);
+
+template <typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2),
+              A1 a1, A2 a2);
+
+
+/**
+ * Dispatches a void method on a process.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 second argument to pass to method
+ */
+template <typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2, P3),
+              A1 a1, A2 a2, A3 a3);
+
+template <typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2, P3),
+              A1 a1, A2 a2, A3 a3);
+
+template <typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2, P3),
+              A1 a1, A2 a2, A3 a3);
+
+
+/**
+ * Dispatches a void method on a process.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ */
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2, P3, P4),
+              A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2, P3, P4),
+              A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2, P3, P4),
+              A1 a1, A2 a2, A3 a3, A4 a4);
+
+
+/**
+ * Dispatches a void method on a process.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @param a5 fifth argument to pass to method
+ */
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2, P3, P4, P5),
+              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2, P3, P4, P5),
+              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2, P3, P4, P5),
+              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)());
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)());
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)());
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1),
+                   A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1),
+                   A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1),
+                   A1 a1);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2),
+                   A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2),
+                   A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2),
+                   A1 a1, A2 a2);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 second argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @param a5 fifth argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on receiver
+ */
+template <typename R, typename T>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)());
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)());
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)());
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on receiver
+ * @param a1 first argument to pass to method
+ */
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1),
+                   A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1),
+                   A1 a1);
+
+template <typename R, typename T, typename P1, typename A1>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1),
+                   A1 a1);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2),
+                   A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2),
+                   A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2),
+                   A1 a1, A2 a2);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 second argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4);
+
+
+/**
+ * Dispatches a method on a process and returns the future that
+ * corresponds to the result of executing the method.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @param a5 fifth argument to pass to method
+ * @return future corresponding to the result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @return result of executing the method
+ */
+template <typename R, typename T>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)());
+
+template <typename R, typename T>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)());
+
+template <typename R, typename T>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)());
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1),
+       A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1),
+       A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1),
+       A1 a1);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2),
+       A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2),
+       A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2),
+       A1 a1, A2 a2);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 second argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @param a5 fifth argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @return result of executing the method
+ */
+template <typename R, typename T>
+R call(const PID<T>& pid,
+       R (T::*method)());
+
+template <typename R, typename T>
+R call(const Process<T>& process,
+       R (T::*method)());
+
+template <typename R, typename T>
+R call(const Process<T>* process,
+       R (T::*method)());
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const PID<T>& pid,
+       R (T::*method)(P1),
+       A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>& process,
+       R (T::*method)(P1),
+       A1 a1);
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>* process,
+       R (T::*method)(P1),
+       A1 a1);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2),
+       A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2),
+       A1 a1, A2 a2);
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2),
+       A1 a1, A2 a2);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 second argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4);
+
+
+/**
+ * Dispatches a method on a process and waits (on the underlying
+ * future) for the result.
+ *
+ * @param pid receiver of message
+ * @param method method to invoke on instance
+ * @param a1 first argument to pass to method
+ * @param a2 second argument to pass to method
+ * @param a3 third argument to pass to method
+ * @param a4 fourth argument to pass to method
+ * @param a5 fifth argument to pass to method
+ * @return result of executing the method
+ */
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
+
+
+namespace internal {
+
+template <typename T>
+void __associate(const Future<T>& future, Promise<T> promise)
+{
+  if (future.ready()) {
+    promise.set(future.get());
+  } else if (future.discarded()) {
+    promise.future().discard();
+  }
+}
+
+
+template <typename T>
+void associate(const Promise<T>& from, const Promise<T>& to)
+{
+  std::tr1::function<void(const Future<T>&)> callback =
+    std::tr1::bind(__associate<T>, std::tr1::placeholders::_1, to);
+  Future<T> future = from.future();
+  future.onReady(callback);
+  future.onDiscarded(callback);
+}
+
+
+template <typename T>
+void vdispatcher(ProcessBase* process,
+                 std::tr1::function<void(T*)> thunk)
+{
+  assert(process != NULL);
+  T* t = dynamic_cast<T*>(process);
+  assert(t != NULL);
+  thunk(t);
+}
+
+
+template <typename R, typename T>
+void pdispatcher(ProcessBase* process,
+                 std::tr1::function<Promise<R>(T*)> thunk,
+                 Promise<R> promise)
+{
+  assert(process != NULL);
+  T* t = dynamic_cast<T*>(process);
+  assert(t != NULL);
+  associate(thunk(t), promise);
+}
+
+
+template <typename R, typename T>
+void dispatcher(ProcessBase* process,
+                std::tr1::function<R(T*)> thunk,
+                Promise<R> promise)
+{
+  assert(process != NULL);
+  T* t = dynamic_cast<T*>(process);
+  assert(t != NULL);
+  promise.set(thunk(t));
+}
+
+
+typedef std::tr1::function<void(ProcessBase*)> Dispatcher;
+
+// Dispatches a call on the specified process.
+void dispatch(const UPID& pid, Dispatcher* dispatcher);
+
+
+// Dispatches a call returning void on the specified process.
+template <typename T>
+void vdispatch(const UPID& pid,
+               const std::tr1::function<void(T*)>& thunk)
+{
+  Dispatcher* dispatcher = new Dispatcher(
+      std::tr1::bind(&internal::vdispatcher<T>,
+                     std::tr1::placeholders::_1,
+                     thunk));
+
+  dispatch(pid, dispatcher);
+}
+
+
+// Dispatches a call returning a Promise on the specified process.
+template <typename R, typename T>
+Future<R> pdispatch(const UPID& pid,
+                    const std::tr1::function<Promise<R>(T*)>& thunk)
+{
+  Promise<R> promise;
+
+  Dispatcher* dispatcher = new Dispatcher(
+      std::tr1::bind(&internal::pdispatcher<R, T>,
+                     std::tr1::placeholders::_1,
+                     thunk, promise));
+
+  dispatch(pid, dispatcher);
+
+  return promise.future();
+}
+
+
+// Dispatches a call for the specified process.
+template <typename R, typename T>
+Future<R> dispatch(const UPID& pid,
+                   const std::tr1::function<R(T*)>& thunk)
+{
+  Promise<R> promise;
+
+  Dispatcher* dispatcher = new Dispatcher(
+      std::tr1::bind(&internal::dispatcher<R, T>,
+                     std::tr1::placeholders::_1,
+                     thunk, promise));
+
+  dispatch(pid, dispatcher);
+
+  return promise.future();
+}
+
+} // namespace internal {
+
+
+/////////////////////////////////
+// Returning void with 0 args. //
+/////////////////////////////////
+
+template <typename T>
+void dispatch(const PID<T>& pid,
+              void (T::*method)())
+{
+  std::tr1::function<void(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1);
+
+  internal::vdispatch(pid, thunk);
+}
+
+
+template <typename T>
+void dispatch(const Process<T>& process,
+              void (T::*method)())
+{
+  dispatch(process.self(), method);
+}
+
+
+template <typename T>
+void dispatch(const Process<T>* process,
+              void (T::*method)())
+{
+  dispatch(process->self(), method);
+}
+
+
+/////////////////////////////////
+// Returning void with 1 args. //
+/////////////////////////////////
+
+template <typename T, typename P1, typename A1>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1),
+              A1 a1)
+{
+  std::tr1::function<void(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1);
+
+  internal::vdispatch(pid, thunk);
+}
+
+
+template <typename T, typename P1, typename A1>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1),
+              A1 a1)
+{
+  dispatch(process.self(), method, a1);
+}
+
+
+template <typename T, typename P1, typename A1>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1),
+              A1 a1)
+{
+  dispatch(process->self(), method, a1);
+}
+
+
+/////////////////////////////////
+// Returning void with 2 args. //
+/////////////////////////////////
+
+template <typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2),
+              A1 a1, A2 a2)
+{
+  std::tr1::function<void(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2);
+
+  internal::vdispatch(pid, thunk);
+}
+
+
+template <typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2),
+              A1 a1, A2 a2)
+{
+  dispatch(process.self(), method, a1, a2);
+}
+
+
+template <typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2),
+              A1 a1, A2 a2)
+{
+  dispatch(process->self(), method, a1, a2);
+}
+
+
+/////////////////////////////////
+// Returning void with 3 args. //
+/////////////////////////////////
+
+template <typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2, P3),
+              A1 a1, A2 a2, A3 a3)
+{
+  std::tr1::function<void(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3);
+
+  internal::vdispatch(pid, thunk);
+}
+
+
+template <typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2, P3),
+              A1 a1, A2 a2, A3 a3)
+{
+  dispatch(process.self(), method, a1, a2, a3);
+}
+
+
+template <typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2, P3),
+              A1 a1, A2 a2, A3 a3)
+{
+  dispatch(process->self(), method, a1, a2, a3);
+}
+
+
+/////////////////////////////////
+// Returning void with 4 args. //
+/////////////////////////////////
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2, P3, P4),
+              A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  std::tr1::function<void(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4);
+
+  internal::vdispatch(pid, thunk);
+}
+
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2, P3, P4),
+              A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  dispatch(process.self(), method, a1, a2, a3, a4);
+}
+
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2, P3, P4),
+              A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  dispatch(process->self(), method, a1, a2, a3, a4);
+}
+
+
+/////////////////////////////////
+// Returning void with 5 args. //
+/////////////////////////////////
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+void dispatch(const PID<T>& pid,
+              void (T::*method)(P1, P2, P3, P4, P5),
+              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  std::tr1::function<void(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4, a5);
+
+  internal::vdispatch(pid, thunk);
+}
+
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+void dispatch(const Process<T>& process,
+              void (T::*method)(P1, P2, P3, P4, P5),
+              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  dispatch(process.self(), method, a1, a2, a3, a4, a5);
+}
+
+
+template <typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+void dispatch(const Process<T>* process,
+              void (T::*method)(P1, P2, P3, P4, P5),
+              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  dispatch(process->self(), method, a1, a2, a3, a4, a5);
+}
+
+
+///////////////////////////////////////
+// Returning Promise<R> with 0 args. //
+///////////////////////////////////////
+
+template <typename R, typename T>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)())
+{
+  std::tr1::function<Promise<R>(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1);
+
+  return internal::pdispatch(pid, thunk);
+}
+
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)())
+{
+  return dispatch(process.self(), method);
+}
+
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)())
+{
+  return dispatch(process->self(), method);
+}
+
+
+///////////////////////////////////////
+// Returning Promise<R> with 1 args. //
+///////////////////////////////////////
+
+template <typename R, typename T, typename P1, typename A1>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1),
+                   A1 a1)
+{
+  std::tr1::function<Promise<R>(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1);
+
+  return internal::pdispatch(pid, thunk);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1),
+                   A1 a1)
+{
+  return dispatch(process.self(), method, a1);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1),
+                   A1 a1)
+{
+  return dispatch(process->self(), method, a1);
+}
+
+
+///////////////////////////////////////
+// Returning Promise<R> with 2 args. //
+///////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2),
+                   A1 a1, A2 a2)
+{
+  std::tr1::function<Promise<R>(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2);
+
+  return internal::pdispatch(pid, thunk);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2),
+                   A1 a1, A2 a2)
+{
+  return dispatch(process.self(), method, a1, a2);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2),
+                   A1 a1, A2 a2)
+{
+  return dispatch(process->self(), method, a1, a2);
+}
+
+
+///////////////////////////////////////
+// Returning Promise<R> with 3 args. //
+///////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3)
+{
+  std::tr1::function<Promise<R>(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3);
+
+  return internal::pdispatch(pid, thunk);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3)
+{
+  return dispatch(process.self(), method, a1, a2, a3);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3)
+{
+  return dispatch(process->self(), method, a1, a2, a3);
+}
+
+
+///////////////////////////////////////
+// Returning Promise<R> with 4 args. //
+///////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  std::tr1::function<Promise<R>(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4);
+
+  return internal::pdispatch(pid, thunk);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return dispatch(process.self(), method, a1, a2, a3, a4);
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return dispatch(process->self(), method, a1, a2, a3, a4);
+}
+
+
+///////////////////////////////////////
+// Returning Promise<R> with 5 args. //
+///////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const PID<T>& pid,
+                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  std::tr1::function<Promise<R>(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4, a5);
+
+  return internal::pdispatch(pid, thunk);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>& process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return dispatch(process.self(), method, a1, a2, a3, a4, a5);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>* process,
+                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return dispatch(process->self(), method, a1, a2, a3, a4, a5);
+}
+
+
+//////////////////////////////
+// Returning R with 0 args. //
+//////////////////////////////
+
+template <typename R, typename T>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)())
+{
+  std::tr1::function<R(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1);
+
+  return internal::dispatch(pid, thunk);
+}
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)())
+{
+  return dispatch(process.self(), method);
+}
+
+template <typename R, typename T>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)())
+{
+  return dispatch(process->self(), method);
+}
+
+
+//////////////////////////////
+// Returning R with 1 args. //
+//////////////////////////////
+
+template <typename R, typename T, typename P1, typename A1>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1),
+                   A1 a1)
+{
+  std::tr1::function<R(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1);
+
+  return internal::dispatch(pid, thunk);
+}
+
+template <typename R, typename T,
+          typename P1, typename A1>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1),
+                   A1 a1)
+{
+  return dispatch(process.self(), method, a1);
+}
+
+template <typename R, typename T, typename P1, typename A1>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1),
+                   A1 a1)
+{
+  return dispatch(process->self(), method, a1);
+}
+
+
+//////////////////////////////
+// Returning R with 2 args. //
+//////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2),
+                   A1 a1, A2 a2)
+{
+  std::tr1::function<R(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2);
+
+  return internal::dispatch(pid, thunk);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2),
+                   A1 a1, A2 a2)
+{
+  return dispatch(process.self(), method, a1, a2);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2),
+                   A1 a1, A2 a2)
+{
+  return dispatch(process->self(), method, a1, a2);
+}
+
+
+//////////////////////////////
+// Returning R with 3 args. //
+//////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3)
+{
+  std::tr1::function<R(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3);
+
+  return internal::dispatch(pid, thunk);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3)
+{
+  return dispatch(process.self(), method, a1, a2, a3);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2, P3),
+                   A1 a1, A2 a2, A3 a3)
+{
+  return dispatch(process->self(), method, a1, a2, a3);
+}
+
+
+//////////////////////////////
+// Returning R with 4 args. //
+//////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  std::tr1::function<R(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4);
+
+  return internal::dispatch(pid, thunk);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return dispatch(process.self(), method, a2, a2, a3, a4);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2, P3, P4),
+                   A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return dispatch(process->self(), method, a2, a2, a3, a4);
+}
+
+
+//////////////////////////////
+// Returning R with 5 args. //
+//////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const PID<T>& pid,
+                   R (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  std::tr1::function<R(T*)> thunk =
+    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4, a5);
+
+  return internal::dispatch(pid, thunk);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>& process,
+                   R (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return dispatch(process.self(), method, a1, a2, a3, a4, a5);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+Future<R> dispatch(const Process<T>* process,
+                   R (T::*method)(P1, P2, P3, P4, P5),
+                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return dispatch(process->self(), method, a1, a2, a3, a4, a5);
+}
+
+
+/////////////////////////////////////////////
+// Returning R via Promise<R> with 0 args. //
+/////////////////////////////////////////////
+
+template <typename R, typename T>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)())
+{
+  return dispatch(pid, method).get();
+}
+
+template <typename R, typename T>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)())
+{
+  return call(process.self(), method);
+}
+
+
+template <typename R, typename T>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)())
+{
+  return call(process->self(), method);
+}
+
+
+/////////////////////////////////////////////
+// Returning R via Promise<R> with 1 args. //
+/////////////////////////////////////////////
+
+template <typename R, typename T, typename P1, typename A1>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1), A1 a1)
+{
+  return dispatch(pid, method, a1).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1),
+       A1 a1)
+{
+  return call(process.self(), method, a1);
+}
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1),
+       A1 a1)
+{
+  return call(process->self(), method, a1);
+}
+
+
+/////////////////////////////////////////////
+// Returning R via Promise<R> with 2 args. //
+/////////////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2), A1 a1, A2 a2)
+{
+  return dispatch(pid, method, a1, a2).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2),
+       A1 a1, A2 a2)
+{
+  return call(process.self(), method, a1, a2);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2),
+       A1 a1, A2 a2)
+{
+  return call(process->self(), method, a1, a2);
+}
+
+
+
+/////////////////////////////////////////////
+// Returning R via Promise<R> with 3 args. //
+/////////////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3)
+{
+  return dispatch(pid, method, a1, a2, a3).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3)
+{
+  return call(process.self(), method, a1, a2, a3);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3)
+{
+  return call(process->self(), method, a1, a2, a3);
+}
+
+
+/////////////////////////////////////////////
+// Returning R via Promise<R> with 4 args. //
+/////////////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return dispatch(pid, method, a1, a2, a3, a4).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return call(process.self(), method, a1, a2, a3, a4);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return call(process->self(), method, a1, a2, a3, a4);
+}
+
+
+/////////////////////////////////////////////
+// Returning R via Promise<R> with 5 args. //
+/////////////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const PID<T>& pid,
+       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return dispatch(pid, method, a1, a2, a3, a4, a5).get();
+}
+
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>& process,
+       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return call(process.self(), method, a1, a2, a3, a4, a5);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>* process,
+       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return call(process->self(), method, a1, a2, a3, a4, a5);
+}
+
+
+////////////////////////////////////
+// Returning R via R with 0 args. //
+////////////////////////////////////
+
+template <typename R, typename T>
+R call(const PID<T>& pid,
+       R (T::*method)())
+{
+  return dispatch(pid, method).get();
+}
+
+template <typename R, typename T>
+R call(const Process<T>& process,
+       R (T::*method)())
+{
+  return call(process.self(), method);
+}
+
+template <typename R, typename T>
+R call(const Process<T>* process,
+       R (T::*method)())
+{
+  return call(process->self(), method);
+}
+
+
+////////////////////////////////////
+// Returning R via R with 1 args. //
+////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const PID<T>& pid,
+       R (T::*method)(P1),
+       A1 a1)
+{
+  return dispatch(pid, method, a1).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>& process,
+       R (T::*method)(P1),
+       A1 a1)
+{
+  return call(process.self(), method, a1);
+}
+
+template <typename R, typename T,
+          typename P1, typename A1>
+R call(const Process<T>* process,
+       R (T::*method)(P1),
+       A1 a1)
+{
+  return call(process->self(), method, a1);
+}
+
+
+////////////////////////////////////
+// Returning R via R with 2 args. //
+////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2),
+       A1 a1, A2 a2)
+{
+  return dispatch(pid, method, a1, a2).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2),
+       A1 a1, A2 a2)
+{
+  return call(process.self(), method, a1, a2);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2,
+          typename A1, typename A2>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2),
+       A1 a1, A2 a2)
+{
+  return call(process->self(), method, a1, a2);
+}
+
+
+////////////////////////////////////
+// Returning R via R with 3 args. //
+////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3)
+{
+  return dispatch(pid, method, a1, a2, a3).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3)
+{
+  return call (process.self(), method, a1, a2, a3);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3,
+          typename A1, typename A2, typename A3>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2, P3),
+       A1 a1, A2 a2, A3 a3)
+{
+  return call (process->self(), method, a1, a2, a3);
+}
+
+
+////////////////////////////////////
+// Returning R via R with 4 args. //
+////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return dispatch(pid, method, a1, a2, a3, a4).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return call(process.self(), method, a1, a2, a3, a4);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4,
+          typename A1, typename A2, typename A3, typename A4>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2, P3, P4),
+       A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return call(process->self(), method, a1, a2, a3, a4);
+}
+
+
+////////////////////////////////////
+// Returning R via R with 5 args. //
+////////////////////////////////////
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const PID<T>& pid,
+       R (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return dispatch(pid, method, a1, a2, a3, a4, a5).get();
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>& process,
+       R (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return call(process.self(), method, a1, a2, a3, a4, a5);
+}
+
+template <typename R, typename T,
+          typename P1, typename P2, typename P3, typename P4, typename P5,
+          typename A1, typename A2, typename A3, typename A4, typename A5>
+R call(const Process<T>* process,
+       R (T::*method)(P1, P2, P3, P4, P5),
+       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+  return call(process->self(), method, a1, a2, a3, a4, a5);
+}
+
+} // namespace process {
+
+#endif // __PROCESS_DISPATCH_HPP__

Modified: incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp?rev=1140024&r1=1140023&r2=1140024&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp Mon Jun 27 06:08:33 2011
@@ -1,73 +1,179 @@
-#ifndef __FUTURE_HPP__
-#define __FUTURE_HPP__
+#ifndef __PROCESS_FUTURE_HPP__
+#define __PROCESS_FUTURE_HPP__
+
+#include <queue>
+#include <set>
+
+#include <tr1/functional>
 
 #include <process/latch.hpp>
+#include <process/option.hpp>
 
 
 namespace process {
 
+// Forward declaration of Promise.
 template <typename T>
 class Promise;
 
 
+// Definition of a "shared" future. A future can hold any
+// copy-constructible value. A future is considered "shared" because
+// by default a future can be accessed concurrently.
 template <typename T>
 class Future
 {
 public:
   Future();
-  Future(Promise<T>* promise);
   Future(const T& _t);
   Future(const Future<T>& that);
-  virtual ~Future();
+  ~Future();
+
+  // Futures are assignable. This results in the reference to the
+  // previous future data being decremented and a reference to 'that'
+  // being incremented.
   Future<T>& operator = (const Future<T>& that);
+
+  // Comparision operators useful for using futures in collections.
+  bool operator == (const Future<T>& that) const;
+  bool operator < (const Future<T>& that) const;
+
+  // Helpers to get the current state of this future.
+  bool pending() const;
   bool ready() const;
+  bool discarded() const;
+
+  // Discards this future. This is similar to cancelling a future,
+  // however it also occurs when the last reference to this future
+  // gets cleaned up. Returns false if the future could not be
+  // discarded (for example, because it is ready).
+  bool discard();
+
+  // Waits for this future to either become ready or discarded.
   bool await(double secs = 0) const;
+
+  // Return the value associated with this future, waits indefinitely
+  // until a value gets associated or until the future is discarded.
   T get() const;
-  operator T () const;
+
+  // Type of the callback function that can get invoked when the
+  // future gets set or discarded.
+  typedef std::tr1::function<void(const Future<T>&)> Callback;
+
+  // Installs callbacks for the specified events.
+  void onReady(const Callback& callback) const;
+  void onDiscarded(const Callback& callback) const;
 
 private:
   friend class Promise<T>;
 
-  void set(const T& _t);
+  bool set(const T& _t);
+  void copy(const Future<T>& that);
+  void cleanup();
+
+  enum State {
+    PENDING,
+    READY,
+    DISCARDED,
+  };
 
   int* refs;
+  int* lock;
+  State* state;
   T** t;
+  std::queue<Callback>* ready_callbacks;
+  std::queue<Callback>* discarded_callbacks;
   Latch* latch;
 };
 
 
 template <typename T>
-Future<T>::Future()
+void __select(const Future<T>& future, Promise<Future<T> > done);
+
+
+template <typename T>
+Option<Future<T> > select(const std::set<Future<T> >& futures, double secs)
 {
-  refs = new int;
-  *refs = 1;
-  t = new T*;
-  *t = NULL;
-  latch = new Latch();
+  Promise<Future<T> > promise;
+
+  std::tr1::function<void(const Future<T>&)> callback =
+    std::tr1::bind(__select<T>, std::tr1::placeholders::_1, promise);
+
+  typename std::set<Future<T> >::iterator iterator;
+  for (iterator = futures.begin(); iterator != futures.end(); ++iterator) {
+    const Future<T>& future = *iterator;
+    future.onReady(callback);
+    future.onDiscarded(callback);
+  }
+
+  Future<Future<T> > future = promise.future();
+
+  future.await(secs);
+
+  if (future.ready()) {
+    return Option<Future<T> >::some(future.get());
+  } else {
+    future.discard();
+    return Option<Future<T> >::none();
+  }
+}
+
+
+template <typename T>
+void __select(const Future<T>& future, Promise<Future<T> > done)
+{
+  done.set(future);
+}
+
+
+namespace internal {
+
+inline void acquire(int* lock)
+{
+  while (!__sync_bool_compare_and_swap(lock, 0, 1))
+    asm volatile ("pause");
+}
+
+inline void release(int* lock)
+{
+  // Unlock via a compare-and-swap so we get a memory barrier too.
+  __sync_bool_compare_and_swap(lock, 1, 0);
 }
 
+} // namespace internal {
+
 
 template <typename T>
-Future<T>::Future(Promise<T>* promise)
+Future<T>::Future()
+  : refs(new int),
+    lock(new int),
+    state(new State),
+    t(new T*),
+    ready_callbacks(new std::queue<Callback>),
+    discarded_callbacks(new std::queue<Callback>),
+    latch(new Latch)
 {
-  refs = new int;
   *refs = 1;
-  t = new T*;
+  *lock = 0;
+  *state = PENDING;
   *t = NULL;
-  latch = new Latch();
-  assert(promise != NULL);
-  promise->associate(*this);
 }
 
 
 template <typename T>
 Future<T>::Future(const T& _t)
+  : refs(new int),
+    lock(new int),
+    state(new State),
+    t(new T*),
+    ready_callbacks(new std::queue<Callback>),
+    discarded_callbacks(new std::queue<Callback>),
+    latch(new Latch)
 {
-  refs = new int;
   *refs = 1;
-  t = new T*;
+  *lock = 0;
+  *state = PENDING;
   *t = NULL;
-  latch = new Latch();
   set(_t);
 }
 
@@ -75,26 +181,14 @@ Future<T>::Future(const T& _t)
 template <typename T>
 Future<T>::Future(const Future<T>& that)
 {
-  assert(that.refs > 0);
-  __sync_fetch_and_add(that.refs, 1);
-  refs = that.refs;
-  t = that.t;
-  latch = that.latch;
+  copy(that);
 }
 
 
 template <typename T>
 Future<T>::~Future()
 {
-  assert(refs != NULL);
-  if (__sync_sub_and_fetch(refs, 1) == 0) {
-    delete refs;
-    assert(t != NULL);
-    if (*t != NULL)
-      delete *t;
-    assert(latch != NULL);
-    delete latch;
-  }
+  cleanup();
 }
 
 
@@ -102,44 +196,94 @@ template <typename T>
 Future<T>& Future<T>::operator = (const Future<T>& that)
 {
   if (this != &that) {
-    // Destructor ...
-    assert(refs != NULL);
-    if (__sync_sub_and_fetch(refs, 1) == 0) {
-      delete refs;
-      assert(t != NULL);
-      if (*t != NULL)
-        delete *t;
-      assert(latch != NULL);
-      delete latch;
+    cleanup();
+    copy(that);
+  }
+  return *this;
+}
+
+
+template <typename T>
+bool Future<T>::operator == (const Future<T>& that) const
+{
+  assert(latch != NULL);
+  assert(that.latch != NULL);
+  return latch == that.latch;
+}
+
+
+template <typename T>
+bool Future<T>::operator < (const Future<T>& that) const
+{
+  assert(latch != NULL);
+  assert(that.latch != NULL);
+  return latch < that.latch;
+}
+
+
+template <typename T>
+bool Future<T>::discard()
+{
+  bool result = false;
+
+  assert(lock != NULL);
+  internal::acquire(lock);
+  {
+    assert(state != NULL);
+    if (*state == PENDING) {
+      *state = DISCARDED;
+      latch->trigger();
+      result = true;
     }
+  }
+  internal::release(lock);
 
-    // Copy constructor ...
-    assert(that.refs > 0);
-    __sync_fetch_and_add(that.refs, 1);
-    refs = that.refs;
-    t = that.t;
-    latch = that.latch;
+  // Invoke all callbacks associated with this future being
+  // DISCARDED. We don't need a lock because the state is now in
+  // DISCARDED so there should not be any concurrent modications.
+  while (!discarded_callbacks->empty()) {
+    const Callback& callback = discarded_callbacks->front();
+    // TODO(*): Invoke callbacks in another execution context.
+    callback(*this);
+    discarded_callbacks->pop();
   }
+
+  return result;
+}
+
+
+template <typename T>
+bool Future<T>::pending() const
+{
+  assert(state != NULL);
+  return *state == PENDING;
 }
 
 
 template <typename T>
 bool Future<T>::ready() const
 {
-  assert(t != NULL);
-  if (*t != NULL)
-    return true;
-  return false;
+  assert(state != NULL);
+  return *state == READY;
+}
+
+
+template <typename T>
+bool Future<T>::discarded() const
+{
+  assert(state != NULL);
+  return *state == DISCARDED;
 }
 
 
 template <typename T>
 bool Future<T>::await(double secs) const
 {
-  if (ready())
-    return true;
-  assert(latch != NULL);
-  return latch->await(secs);
+  if (!ready()) {
+    assert(latch != NULL);
+    return latch->await(secs);
+  }
+  return true;
 }
 
 
@@ -148,27 +292,141 @@ T Future<T>::get() const
 {
   if (ready())
     return **t;
+  assert(latch != NULL);
   await();
-  assert(t != NULL && *t != NULL);
+  assert(t != NULL);
+  assert(*t != NULL);
   return **t;
 }
 
 
 template <typename T>
-Future<T>::operator T () const
+void Future<T>::onReady(const Callback& callback) const
+{
+  bool run = false;
+
+  assert(lock != NULL);
+  internal::acquire(lock);
+  {
+    assert(state != NULL);
+    if (*state == READY) {
+      run = true;
+    } else {
+      ready_callbacks->push(callback);
+    }
+  }
+  internal::release(lock);
+
+  // TODO(*): Invoke callback in another execution context.
+  if (run) {
+    callback(*this);
+  }
+}
+
+
+template <typename T>
+void Future<T>::onDiscarded(const Callback& callback) const
+{
+  bool run = false;
+
+  assert(lock != NULL);
+  internal::acquire(lock);
+  {
+    assert(state != NULL);
+    if (*state == DISCARDED) {
+      run = true;
+    } else {
+      discarded_callbacks->push(callback);
+    }
+  }
+  internal::release(lock);
+
+  // TODO(*): Invoke callback in another execution context.
+  if (run) {
+    callback(*this);
+  }
+}
+
+template <typename T>
+bool Future<T>::set(const T& _t)
+{
+  bool result = false;
+
+  assert(lock != NULL);
+  internal::acquire(lock);
+  {
+    assert(state != NULL);
+    if (*state == PENDING) {
+      *state = READY;
+      *t = new T(_t);
+      latch->trigger();
+      result = true;
+    }
+  }
+  internal::release(lock);
+
+  // Invoke all callbacks associated with this future being READY. We
+  // don't need a lock because the state is now in READY so there
+  // should not be any concurrent modications.
+  while (!ready_callbacks->empty()) {
+    const Callback& callback = ready_callbacks->front();
+    // TODO(*): Invoke callbacks in another execution context.
+    callback(*this);
+    ready_callbacks->pop();
+  }
+
+  return result;
+}
+
+
+template <typename T>
+void Future<T>::copy(const Future<T>& that)
 {
-  return get();
+  assert(that.refs > 0);
+  __sync_fetch_and_add(that.refs, 1);
+  refs = that.refs;
+  lock = that.lock;
+  state = that.state;
+  t = that.t;
+  ready_callbacks = that.ready_callbacks;
+  discarded_callbacks = that.discarded_callbacks;
+  latch = that.latch;
 }
 
 
 template <typename T>
-void Future<T>::set(const T& _t)
+void Future<T>::cleanup()
 {
-  assert(t != NULL && *t == NULL);
-  *t = new T(_t);
-  latch->trigger();
+  assert(refs != NULL);
+  if (__sync_sub_and_fetch(refs, 1) == 0) {
+    // Increment the reference count and try and discard the future if
+    // it's still in pending (invokes any discarded callbacks that
+    // have been setup).
+    *refs = 1;
+    discard();
+
+    // Now try and cleanup again (this time we know the future has
+    // either been discarded or was not pending).
+    assert(refs != NULL);
+    if (__sync_sub_and_fetch(refs, 1) == 0) {
+      delete refs;
+      assert(lock != NULL);
+      delete lock;
+      assert(state != NULL);
+      delete state;
+      assert(t != NULL);
+      if (*t != NULL)
+        delete *t;
+      assert(ready_callbacks != NULL);
+      delete ready_callbacks;
+      assert(discarded_callbacks != NULL);
+      delete discarded_callbacks;
+      assert(latch != NULL);
+      delete latch;
+    }
+  }
 }
 
 }  // namespace process {
 
-#endif // __FUTURE_HPP__
+#endif // __PROCESS_FUTURE_HPP__

Modified: incubator/mesos/trunk/third_party/libprocess/include/process/gc.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/gc.hpp?rev=1140024&r1=1140023&r2=1140024&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/gc.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/gc.hpp Mon Jun 27 06:08:33 2011
@@ -1,5 +1,5 @@
-#ifndef __GC_HPP__
-#define __GC_HPP__
+#ifndef __PROCESS_GC_HPP__
+#define __PROCESS_GC_HPP__
 
 #include <map>
 
@@ -46,4 +46,4 @@ extern PID<GarbageCollector> gc;
 
 } // namespace process {
 
-#endif // __GC_HPP__
+#endif // __PROCESS_GC_HPP__

Modified: incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp?rev=1140024&r1=1140023&r2=1140024&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp Mon Jun 27 06:08:33 2011
@@ -1,5 +1,5 @@
-#ifndef __HTTP_HPP__
-#define __HTTP_HPP__
+#ifndef __PROCESS_HTTP_HPP__
+#define __PROCESS_HTTP_HPP__
 
 #include <string>
 
@@ -78,4 +78,4 @@ struct HttpServiceUnavailableResponse : 
 
 } // namespace process {
 
-#endif // __HTTP_HPP
+#endif // __PROCESS_HTTP_HPP

Modified: incubator/mesos/trunk/third_party/libprocess/include/process/latch.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/latch.hpp?rev=1140024&r1=1140023&r2=1140024&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/latch.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/latch.hpp Mon Jun 27 06:08:33 2011
@@ -1,5 +1,5 @@
-#ifndef __LATCH_HPP__
-#define __LATCH_HPP__
+#ifndef __PROCESS_LATCH_HPP__
+#define __PROCESS_LATCH_HPP__
 
 
 namespace process {
@@ -26,4 +26,4 @@ private:
 
 }  // namespace process {
 
-#endif // __LATCH_HPP__
+#endif // __PROCESS_LATCH_HPP__