1 /***************************************************************************
2  *  foxxll/io/request.hpp
3  *
4  *  Part of FOXXLL. See http://foxxll.org
5  *
6  *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
7  *  Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
8  *  Copyright (C) 2013-2014 Timo Bingmann <tb@panthema.net>
9  *
10  *  Distributed under the Boost Software License, Version 1.0.
11  *  (See accompanying file LICENSE_1_0.txt or copy at
12  *  http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef FOXXLL_IO_REQUEST_HEADER
16 #define FOXXLL_IO_REQUEST_HEADER
17 
18 #include <cassert>
19 #include <functional>
20 #include <memory>
21 #include <string>
22 
23 #include <tlx/counting_ptr.hpp>
24 #include <tlx/delegate.hpp>
25 
26 #include <foxxll/common/exceptions.hpp>
27 #include <foxxll/io/request_interface.hpp>
28 
29 namespace foxxll {
30 
31 //! \addtogroup foxxll_reqlayer
32 //! \{
33 
34 constexpr size_t BlockAlignment = 4096;
35 
36 class file;
37 class request;
38 
39 //! A reference counting pointer for \c file.
40 using file_ptr = tlx::counting_ptr<file>;
41 
42 //! A reference counting pointer for \c request.
43 using request_ptr = tlx::counting_ptr<request>;
44 
45 //! completion handler
46 using completion_handler = tlx::delegate<void(request* r, bool success)>;
47 
48 //! Request object encapsulating basic properties like file and offset.
49 class request : virtual public request_interface, public tlx::reference_counter
50 {
51     constexpr static bool debug = false;
52     friend class linuxaio_queue;
53 
54 protected:
55     completion_handler on_complete_;
56     std::unique_ptr<io_error> error_;
57 
58 protected:
59     //! \name Base Parameter of an I/O Request
60     //! \{
61 
62     //! file implementation to perform I/O with
63     file* file_;
64     //! data buffer to transfer
65     void* buffer_;
66     //! offset within file
67     offset_type offset_;
68     //! number of bytes at buffer_ to transfer
69     size_type bytes_;
70     //! READ or WRITE
71     read_or_write op_;
72 
73     //! \}
74 
75 public:
76     request(const completion_handler& on_complete,
77             file* file, void* buffer, offset_type offset, size_type bytes,
78             read_or_write op);
79 
80     //! non-copyable: delete copy-constructor
81     request(const request&) = delete;
82     //! non-copyable: delete assignment operator
83     request& operator = (const request&) = delete;
84     //! move-constructor: default
85     request(request&&) = default;
86     //! move-assignment operator: default
87     request& operator = (request&&) = default;
88 
89     virtual ~request();
90 
91 public:
92     //! \name Accessors
93     //! \{
94 
get_file() const95     file * get_file() const { return file_; }
buffer() const96     void * buffer() const { return buffer_; }
offset() const97     offset_type offset() const { return offset_; }
bytes() const98     size_type bytes() const { return bytes_; }
op() const99     read_or_write op() const { return op_; }
100 
101     void check_alignment() const;
102 
103     std::ostream & print(std::ostream& out) const final;
104 
105     //! Inform the request object that an error occurred during the I/O
106     //! execution.
107     void error_occured(const char* msg);
108 
109     //! Inform the request object that an error occurred during the I/O
110     //! execution.
111     void error_occured(const std::string& msg);
112 
113     //! Rises an exception if there were error with the I/O.
check_errors()114     void check_errors()
115     {
116         if (error_.get())
117             throw *(error_.get());
118     }
119 
120     const char * io_type() const override;
121 
122     void release_file_reference();
123 
124     //! \}
125 
126 protected:
check_nref(bool after=false)127     void check_nref(bool after = false)
128     {
129         if (reference_count() < 2)
130             check_nref_failed(after);
131     }
132 
133 private:
134     void check_nref_failed(bool after);
135 };
136 
137 std::ostream& operator << (std::ostream& out, const request& req);
138 
139 //! \}
140 
141 } // namespace foxxll
142 
143 #endif // !FOXXLL_IO_REQUEST_HEADER
144 
145 /**************************************************************************/
146