libfilezilla
Loading...
Searching...
No Matches
writer.hpp
Go to the documentation of this file.
1#ifndef LIBFILEZILLA_AIO_WRITER_HEADER
2#define LIBFILEZILLA_AIO_WRITER_HEADER
3
10#include "aio.hpp"
11#include "../buffer.hpp"
12#include "../file.hpp"
13#include "../thread_pool.hpp"
14
15#include <list>
16
17namespace fz {
18
28{
29public:
30 writer_base(writer_base const&) = delete;
31 writer_base& operator=(writer_base const&) = delete;
32
34 virtual aio_result preallocate(uint64_t /*size*/) { return aio_result::ok; }
35
47
59
61 virtual bool set_mtime(datetime const&) { return false; }
62
63 void close();
64
75 using progress_cb_t = std::function<void(writer_base const*, uint64_t written)>;
76
77protected:
78 virtual aio_result do_add_buffer(scoped_lock & l, buffer_lease && b) = 0;
79 virtual aio_result do_finalize(scoped_lock & l) = 0;
80
82 : buffer_pool_(pool)
83 , name_(name)
84 , progress_cb_(std::move(progress_cb))
85 , max_buffers_(max_buffers ? max_buffers : 1)
86 {}
87
88 writer_base(std::wstring_view name, aio_buffer_pool & pool, progress_cb_t && progress_cb, size_t max_buffers) noexcept
89 : buffer_pool_(pool)
90 , name_(name)
91 , progress_cb_(std::move(progress_cb))
92 , max_buffers_(max_buffers ? max_buffers : 1)
93 {}
94
95 virtual void do_close(scoped_lock &) {}
96
97 mutex mtx_;
98 aio_buffer_pool & buffer_pool_;
99
100 std::wstring const name_;
101
102 progress_cb_t progress_cb_;
103
104 size_t const max_buffers_{};
105 std::list<buffer_lease> buffers_;
106
107 bool error_{};
108 uint8_t finalizing_{};
109};
110
113{
114public:
115 explicit writer_factory(std::wstring const& name)
116 : name_(name)
117 {}
118 explicit writer_factory(std::wstring && name)
119 : name_(std::move(name))
120 {}
121
122 virtual ~writer_factory() noexcept = default;
123
125 virtual std::unique_ptr<writer_factory> clone() const = 0;
126
134 virtual std::unique_ptr<writer_base> open(aio_buffer_pool & pool, uint64_t offset = 0, writer_base::progress_cb_t progress_cb = nullptr, size_t max_buffers = 0) = 0;
135
136 std::wstring const& name() const { return name_; }
137
139 virtual bool offsetable() const { return false; }
140
142 virtual uint64_t size() const { return writer_base::nosize; }
143 virtual datetime mtime() const { return datetime(); }
144
146 virtual size_t min_buffer_usage() const { return 1; }
147
149 virtual bool multiple_buffer_usage() const { return false; }
150
151 virtual size_t preferred_buffer_count() const { return 1; }
152
158 virtual bool set_mtime(datetime const&) { return false; }
159protected:
160 writer_factory() = default;
161 writer_factory(writer_factory const&) = default;
162
163private:
164 std::wstring const name_;
165};
166
168{
169public:
170 writer_factory_holder() = default;
171 writer_factory_holder(std::unique_ptr<writer_factory> && factory);
172 writer_factory_holder(std::unique_ptr<writer_factory> const& factory);
174
177
179 writer_factory_holder& operator=(writer_factory_holder && op) noexcept;
180 writer_factory_holder& operator=(std::unique_ptr<writer_factory> && factory);
181
182 writer_factory const* operator->() const { return impl_.get(); }
183 writer_factory* operator->() { return impl_.get(); }
184 writer_factory const& operator*() const { return *impl_; }
185 writer_factory & operator*() { return *impl_; }
186
187 explicit operator bool() const { return impl_.operator bool(); }
188
189 std::wstring name() const { return impl_ ? impl_->name() : std::wstring(); }
190 datetime mtime() const { return impl_ ? impl_->mtime() : datetime(); }
191 uint64_t size() const { return impl_ ? impl_->size() : aio_base::nosize; }
192
193private:
194 std::unique_ptr<writer_factory> impl_;
195};
196
197
198
199class thread_pool;
200
203{
204public:
205 using writer_base::writer_base;
206
207protected:
208 virtual aio_result do_add_buffer(scoped_lock & l, buffer_lease && b) override;
209 virtual aio_result do_finalize(scoped_lock & l) override;
210 void wakeup(scoped_lock & l) {
211 cond_.signal(l);
212 }
213
214 virtual void do_close(scoped_lock & l) override;
215
216 virtual aio_result continue_finalize(scoped_lock &) {
217 return aio_result::ok;
218 }
219
220 condition cond_;
221 async_task task_;
222
223 bool quit_{};
224};
225
228{
229public:
230 file_writer(std::wstring && name, aio_buffer_pool & pool, file && f, thread_pool & tpool, bool fsync = false, progress_cb_t && progress_cb = nullptr, size_t max_buffers = 4) noexcept;
231 file_writer(std::wstring_view name, aio_buffer_pool & pool, file && f, thread_pool & tpool, bool fsync = false, progress_cb_t && progress_cb = nullptr, size_t max_buffers = 4) noexcept;
232
233 virtual ~file_writer() override;
234
235 virtual aio_result preallocate(uint64_t size) override;
236
237 virtual bool set_mtime(datetime const&) override;
238
239private:
240 virtual void FZ_PRIVATE_SYMBOL do_close(scoped_lock & l) override;
241 virtual aio_result FZ_PRIVATE_SYMBOL continue_finalize(scoped_lock & l) override;
242
243 void FZ_PRIVATE_SYMBOL entry();
244
245 file file_;
246
247 bool fsync_{};
248 bool preallocated_{};
249};
250
251enum class file_writer_flags : unsigned {
252 fsync = 0x01,
253 permissions_current_user_only = 0x02,
254 permissions_current_user_and_admins_only = 0x04
255};
256inline bool operator&(file_writer_flags lhs, file_writer_flags rhs) {
257 return (static_cast<std::underlying_type_t<file_writer_flags>>(lhs) & static_cast<std::underlying_type_t<file_writer_flags>>(rhs)) != 0;
258}
259inline file_writer_flags operator|(file_writer_flags lhs, file_writer_flags rhs) {
260 return static_cast<file_writer_flags>(static_cast<std::underlying_type_t<file_writer_flags>>(lhs) | static_cast<std::underlying_type_t<file_writer_flags>>(rhs));
261}
262
265{
266public:
267 file_writer_factory(std::wstring const& file, thread_pool & tpool, file_writer_flags = {});
268
269 virtual std::unique_ptr<writer_base> open(aio_buffer_pool & pool, uint64_t offset, writer_base::progress_cb_t progress_cb = nullptr, size_t max_buffers = 0) override;
270 virtual std::unique_ptr<writer_factory> clone() const override;
271
272 virtual bool offsetable() const override { return true; }
273
274 virtual uint64_t size() const override;
275 virtual datetime mtime() const override;
276
277 virtual bool set_mtime(datetime const& t) override;
278
279 virtual bool multiple_buffer_usage() const override { return true; }
280
281 virtual size_t preferred_buffer_count() const override { return 4; }
282
283private:
284 thread_pool & thread_pool_;
285 file_writer_flags flags_{};
286};
287
295{
296public:
297 buffer_writer(buffer & buffer, std::wstring const& name, aio_buffer_pool & pool, size_t size_limit, progress_cb_t && progress_cb = nullptr);
298
299 virtual aio_result preallocate(uint64_t size) override;
300
301private:
302 virtual aio_result FZ_PRIVATE_SYMBOL do_add_buffer(scoped_lock & l, buffer_lease && b) override;
303 virtual aio_result FZ_PRIVATE_SYMBOL do_finalize(scoped_lock &) override { return error_ ? aio_result::error : aio_result::ok; }
304
305 buffer & buffer_;
306 size_t size_limit_{};
307};
308
316{
317public:
318 buffer_writer_factory(buffer & b, std::wstring const& name, size_t size_limit);
319
320 virtual std::unique_ptr<writer_base> open(aio_buffer_pool & pool, uint64_t offset, writer_base::progress_cb_t progress_cb = nullptr, size_t max_buffers = 0) override;
321 virtual std::unique_ptr<writer_factory> clone() const override;
322
323private:
324 buffer & buffer_;
325 size_t size_limit_{};
326};
327
328}
329
330#endif
Buffer management and wait machinery for asynchronous I/O.
Declares fz::buffer.
Definition aio.hpp:203
A buffer pool for use with async readers/writers.
Definition aio.hpp:107
Definition aio.hpp:69
Handle for asynchronous tasks.
Definition thread_pool.hpp:24
Definition aio.hpp:26
Definition writer.hpp:316
virtual std::unique_ptr< writer_base > open(aio_buffer_pool &pool, uint64_t offset, writer_base::progress_cb_t progress_cb=nullptr, size_t max_buffers=0) override
Creates a writer.
virtual std::unique_ptr< writer_factory > clone() const override
Clones the factory.
Definition writer.hpp:295
virtual aio_result preallocate(uint64_t size) override
Instructs writer to preallocate storage. May be a noop.
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition buffer.hpp:27
Waitable condition variable.
Definition mutex.hpp:196
Represents a point of time in wallclock, tracking the timestamps accuracy/precision.
Definition time.hpp:41
Simple handler for asynchronous event processing.
Definition event_handler.hpp:55
Factory for.
Definition writer.hpp:265
virtual bool multiple_buffer_usage() const override
Whether the writer can benefit from multiple buffers.
Definition writer.hpp:279
virtual std::unique_ptr< writer_base > open(aio_buffer_pool &pool, uint64_t offset, writer_base::progress_cb_t progress_cb=nullptr, size_t max_buffers=0) override
Creates a writer.
virtual bool set_mtime(datetime const &t) override
Sets the mtime of the target.
virtual bool offsetable() const override
If true, writer can be opened from any position, not just the beginning, such as file_writer.
Definition writer.hpp:272
virtual std::unique_ptr< writer_factory > clone() const override
Clones the factory.
virtual uint64_t size() const override
Some writers, e.g. for files, may have a pre-existing size.
File writer.
Definition writer.hpp:228
virtual aio_result preallocate(uint64_t size) override
Instructs writer to preallocate storage. May be a noop.
virtual bool set_mtime(datetime const &) override
Must be finalized already.
Lean class for file access.
Definition file.hpp:29
A simple scoped lock.
Definition mutex.hpp:93
A dumb thread-pool for asynchronous tasks.
Definition thread_pool.hpp:64
Base class for threaded writer.
Definition writer.hpp:203
Base class for all writers.
Definition writer.hpp:28
aio_result finalize(event_handler &h)
Finalizes the writer.
virtual aio_result preallocate(uint64_t)
Instructs writer to preallocate storage. May be a noop.
Definition writer.hpp:34
aio_result add_buffer(buffer_lease &&b, event_handler &h)
Pass a buffer to be written out.
std::function< void(writer_base const *, uint64_t written)> progress_cb_t
Definition writer.hpp:75
virtual bool set_mtime(datetime const &)
Must be finalized already.
Definition writer.hpp:61
Definition writer.hpp:168
A writer factory.
Definition writer.hpp:113
virtual std::unique_ptr< writer_factory > clone() const =0
Clones the factory.
virtual size_t min_buffer_usage() const
The writer requires at least this many buffers.
Definition writer.hpp:146
virtual uint64_t size() const
Some writers, e.g. for files, may have a pre-existing size.
Definition writer.hpp:142
virtual std::unique_ptr< writer_base > open(aio_buffer_pool &pool, uint64_t offset=0, writer_base::progress_cb_t progress_cb=nullptr, size_t max_buffers=0)=0
Creates a writer.
virtual bool multiple_buffer_usage() const
Whether the writer can benefit from multiple buffers.
Definition writer.hpp:149
virtual bool offsetable() const
If true, writer can be opened from any position, not just the beginning, such as file_writer.
Definition writer.hpp:139
virtual bool set_mtime(datetime const &)
Sets the mtime of the target.
Definition writer.hpp:158
File handling.
The namespace used by libfilezilla.
Definition apply.hpp:17
aio_result
Result of aio operations.
Definition aio.hpp:190
@ ok
Success, proceed.
@ error
Operationf failed.
bool dispatch(event_base const &ev, F &&f)
Dispatch for simple_event<> based events to simple functors.
Definition event_handler.hpp:199
Declares thread_pool and async_task.