request.hpp 3.86 KB
Newer Older
Matthieu Dorier's avatar
Matthieu Dorier committed
1 2 3 4 5
/*
 * (C) 2017 The University of Chicago
 * 
 * See COPYRIGHT in top-level directory.
 */
Matthieu Dorier's avatar
Matthieu Dorier committed
6 7 8 9
#ifndef __THALLIUM_REQUEST_HPP
#define __THALLIUM_REQUEST_HPP

#include <margo.h>
10
#include <thallium/margo_exception.hpp>
11 12 13 14 15 16
#ifdef USE_CEREAL
    #include <thallium/serialization/cereal/archives.hpp>
#else
    #include <thallium/serialization/serialize.hpp>
    #include <thallium/serialization/buffer_output_archive.hpp>
#endif
Matthieu Dorier's avatar
Matthieu Dorier committed
17 18 19

namespace thallium {

20
class engine;
Matthieu Dorier's avatar
Matthieu Dorier committed
21
class endpoint;
Matthieu Dorier's avatar
Matthieu Dorier committed
22

Matthieu Dorier's avatar
Matthieu Dorier committed
23 24 25 26 27 28 29
/**
 * @brief A request object is created whenever a server
 * receives an RPC. The object is passed as first argument to
 * the function associated with the RPC. The request allows
 * one to get information from the caller and to respond to
 * the RPC.
 */
Matthieu Dorier's avatar
Matthieu Dorier committed
30 31
class request {

32
    friend class engine;
Matthieu Dorier's avatar
Matthieu Dorier committed
33 34 35

private:

Matthieu Dorier's avatar
Matthieu Dorier committed
36
    engine*     m_engine;
37
    hg_handle_t m_handle;
38
    bool        m_disable_response;
Matthieu Dorier's avatar
Matthieu Dorier committed
39

Matthieu Dorier's avatar
Matthieu Dorier committed
40 41 42 43 44 45 46 47
    /**
     * @brief Constructor. Made private since request are only created
     * by the engine within RPC callbacks.
     *
     * @param e engine object that created the request.
     * @param h handle of the RPC that was received.
     * @param disable_resp whether responses are disabled.
     */
48 49
    request(engine& e, hg_handle_t h, bool disable_resp)
    : m_engine(&e), m_handle(h), m_disable_response(disable_resp) {}
Matthieu Dorier's avatar
Matthieu Dorier committed
50 51 52

public:

Matthieu Dorier's avatar
Matthieu Dorier committed
53 54 55
    /**
     * @brief Copy constructor.
     */
56 57
    request(const request& other)
    : m_engine(other.m_engine), m_handle(other.m_handle), m_disable_response(other.m_disable_response) {
58 59
        hg_return_t ret = margo_ref_incr(m_handle);
        MARGO_ASSERT(ret, margo_ref_incr);
60
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
61

Matthieu Dorier's avatar
Matthieu Dorier committed
62 63 64
    /**
     * @brief Move constructor.
     */
65 66 67 68
    request(request&& other)
    : m_engine(other.m_engine), m_handle(other.m_handle), m_disable_response(other.m_disable_response) {
        other.m_handle = HG_HANDLE_NULL;
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
69

Matthieu Dorier's avatar
Matthieu Dorier committed
70 71 72
    /**
     * @brief Copy-assignment operator.
     */
73 74
    request& operator=(const request& other) {
        if(m_handle == other.m_handle) return *this;
75 76 77
        hg_return_t ret;
        ret = margo_destroy(m_handle);
        MARGO_ASSERT(ret, margo_destroy);
Matthieu Dorier's avatar
Matthieu Dorier committed
78
        m_engine           = other.m_engine;
79
        m_handle           = other.m_handle;
80
        m_disable_response = other.m_disable_response;
81 82
        ret = margo_ref_incr(m_handle);
        MARGO_ASSERT(ret, margo_ref_incr);
83 84
        return *this;
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
85

Matthieu Dorier's avatar
Matthieu Dorier committed
86 87 88
    /**
     * @brief Move-assignment operator.
     */
89 90 91
    request& operator=(request&& other) {
        if(m_handle == other.m_handle) return *this;
        margo_destroy(m_handle);
Matthieu Dorier's avatar
Matthieu Dorier committed
92
        m_engine           = other.m_engine;
93
        m_handle           = other.m_handle;
94
        m_disable_response = other.m_disable_response;
95 96 97
        other.m_handle = HG_HANDLE_NULL;
        return *this;
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
98

Matthieu Dorier's avatar
Matthieu Dorier committed
99 100 101
    /**
     * @brief Destructor.
     */
102 103
    ~request() {
        hg_return_t ret = margo_destroy(m_handle);
104
        MARGO_ASSERT_TERMINATE(ret, margo_destroy, -1);
105
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
106

Matthieu Dorier's avatar
Matthieu Dorier committed
107 108 109 110 111 112 113 114
    /**
     * @brief Responds to the sender of the RPC.
     * Serializes the series of arguments provided and
     * send the resulting buffer to the sender.
     *
     * @tparam T Types of parameters to serialize.
     * @param t Parameters to serialize.
     */
115 116
    template<typename ... T>
    void respond(T&&... t) const {
117
        if(m_disable_response) return; // XXX throwing an exception?
118
        if(m_handle != HG_HANDLE_NULL) {
119
            buffer b;
120 121 122 123
#ifdef USE_CEREAL
            cereal_output_archive arch(b, *m_engine);
            arch(std::forward<T>(t)...);
#else
Matthieu Dorier's avatar
Matthieu Dorier committed
124
            buffer_output_archive arch(b, *m_engine);
125
            serialize_many(arch, std::forward<T>(t)...);
126
#endif
127
            hg_return_t ret = margo_respond(m_handle, &b);
128
            MARGO_ASSERT(ret, margo_respond);
129 130
        }
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
131

Matthieu Dorier's avatar
Matthieu Dorier committed
132 133 134 135 136
    /**
     * @brief Get the endpoint corresponding to the sender of the RPC.
     *
     * @return endpoint corresponding to the sender of the RPC.
     */
Matthieu Dorier's avatar
Matthieu Dorier committed
137
    endpoint get_endpoint() const;
Matthieu Dorier's avatar
Matthieu Dorier committed
138 139 140 141 142
};

}

#endif