request.hpp 3.63 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
#include <thallium/serialization/serialize.hpp>
#include <thallium/serialization/buffer_output_archive.hpp>
Matthieu Dorier's avatar
Matthieu Dorier committed
13 14 15

namespace thallium {

16
class engine;
Matthieu Dorier's avatar
Matthieu Dorier committed
17
class endpoint;
Matthieu Dorier's avatar
Matthieu Dorier committed
18

Matthieu Dorier's avatar
Matthieu Dorier committed
19 20 21 22 23 24 25
/**
 * @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
26 27
class request {

28
    friend class engine;
Matthieu Dorier's avatar
Matthieu Dorier committed
29 30 31

private:

Matthieu Dorier's avatar
Matthieu Dorier committed
32
    engine*     m_engine;
33
    hg_handle_t m_handle;
34
    bool        m_disable_response;
Matthieu Dorier's avatar
Matthieu Dorier committed
35

Matthieu Dorier's avatar
Matthieu Dorier committed
36 37 38 39 40 41 42 43
    /**
     * @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.
     */
44 45
    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
46 47 48

public:

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

Matthieu Dorier's avatar
Matthieu Dorier committed
58 59 60
    /**
     * @brief Move constructor.
     */
61 62 63 64
    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
65

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

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

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

Matthieu Dorier's avatar
Matthieu Dorier committed
103 104 105 106 107 108 109 110
    /**
     * @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.
     */
111 112
    template<typename ... T>
    void respond(T&&... t) const {
113
        if(m_disable_response) return; // XXX throwing an exception?
114
        if(m_handle != HG_HANDLE_NULL) {
115
            buffer b;
Matthieu Dorier's avatar
Matthieu Dorier committed
116
            buffer_output_archive arch(b, *m_engine);
117
            arch(std::forward<T>(t)...);
118
            hg_return_t ret = margo_respond(m_handle, &b);
119
            MARGO_ASSERT(ret, margo_respond);
120 121
        }
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
122

Matthieu Dorier's avatar
Matthieu Dorier committed
123 124 125 126 127
    /**
     * @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
128
    endpoint get_endpoint() const;
Matthieu Dorier's avatar
Matthieu Dorier committed
129 130 131 132 133
};

}

#endif