1 // (C) Copyright 2006
2 // Douglas Gregor <doug.gregor -at- gmail.com>
3 // Andreas Kloeckner <inform -at- tiker.net>
4 
5 // Use, modification and distribution is subject to the Boost Software
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 //  Authors: Douglas Gregor, Andreas Kloeckner
10 
11 #ifndef BOOST_MPI_PYTHON_REQUEST_WITH_VALUE_HPP
12 #define BOOST_MPI_PYTHON_REQUEST_WITH_VALUE_HPP
13 
14 #include <boost/python.hpp>
15 #include <boost/mpi.hpp>
16 
17 namespace boost { namespace mpi { namespace python {
18 
19   /** This wrapper adds a @c boost::python::object value to the @c
20    * boost::mpi::request structure, for the benefit of @c irecv() requests.
21    *
22    * In order to be able to return the value of his requests to the user, we
23    * need a handle that we can update to contain the transmitted value once the
24    * request completes. Since we're passing the address on to irecv to fill at
25    * any time in the future, this address may not change over time.
26    *
27    * There are two possible cases:
28    * - plain irecv()
29    * - skeleton-content irecv()
30    *
31    * In the first case, we need to own the storage from this object, the
32    * m_internal_value is used for this. In the second case, the updated
33    * python::object is part of a boost::mpi::python::content object: the
34    * m_external_value field handles this case. Furthermore, in the latter case,
35    * we now have a lifetime dependency on that content object; this can be
36    * handled with the BPL's with_custodian_and_ward facility.
37    *
38    * Since requests and request_with_value are supposed to be copyconstructible,
39    * we can't put the handle immediately inside this instance. Moreover, since
40    * we need to be able to put request_with_value inside request_vectors, any
41    * values we own must be held in a shared_ptr instance.
42    */
43 
44   class request_with_value : public request
45   {
46     private:
47       boost::shared_ptr<boost::python::object> m_internal_value;
48       boost::python::object *m_external_value;
49 
50     public:
request_with_value()51       request_with_value()
52         : m_external_value(0)
53       { }
request_with_value(const request & req)54       request_with_value(const request &req)
55         : request(req), m_external_value(0)
56       { }
57 
58       const boost::python::object get_value() const;
59       const boost::python::object get_value_or_none() const;
60 
61       const boost::python::object wrap_wait();
62       const boost::python::object wrap_test();
63 
64       friend request_with_value communicator_irecv(const communicator &, int, int);
65       friend request_with_value communicator_irecv_content(
66           const communicator&, int, int, content&);
67   };
68 
69 } } }
70 
71 #endif
72