request.hpp 3.49 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
100
		hg_return_t ret = margo_destroy(m_handle);
        MARGO_ASSERT(ret, margo_destroy);
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