request.hpp 3.51 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;
Matthieu Dorier's avatar
Matthieu Dorier committed
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.
     */
Matthieu Dorier's avatar
Matthieu Dorier committed
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.
     */
Matthieu Dorier's avatar
Matthieu Dorier committed
52
	request(const request& other)
Matthieu Dorier's avatar
Matthieu Dorier committed
53
	: 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);
Matthieu Dorier's avatar
Matthieu Dorier committed
56 57
	}

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

Matthieu Dorier's avatar
Matthieu Dorier committed
66 67 68
    /**
     * @brief Copy-assignment operator.
     */
Matthieu Dorier's avatar
Matthieu Dorier committed
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 75
        m_engine           = other.m_engine;
		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);
Matthieu Dorier's avatar
Matthieu Dorier committed
79 80 81
		return *this;
	}

Matthieu Dorier's avatar
Matthieu Dorier committed
82 83 84
    /**
     * @brief Move-assignment operator.
     */
Matthieu Dorier's avatar
Matthieu Dorier committed
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 89
        m_engine           = other.m_engine;
		m_handle           = other.m_handle;
90
        m_disable_response = other.m_disable_response;
Matthieu Dorier's avatar
Matthieu Dorier committed
91 92 93 94
		other.m_handle = HG_HANDLE_NULL;
		return *this;
	}

Matthieu Dorier's avatar
Matthieu Dorier committed
95 96 97
    /**
     * @brief Destructor.
     */
Rob Latham's avatar
Rob Latham committed
98
	~request() {
99
		hg_return_t ret = margo_destroy(m_handle);
100
        MARGO_ASSERT_TERMINATE(ret, margo_destroy, -1);
Matthieu Dorier's avatar
Matthieu Dorier committed
101 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?
Matthieu Dorier's avatar
Matthieu Dorier committed
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
            serialize_many(arch, std::forward<T>(t)...);
118 119
			hg_return_t ret = margo_respond(m_handle, &b);
            MARGO_ASSERT(ret, margo_respond);
Matthieu Dorier's avatar
Matthieu Dorier committed
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