2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
9 * @file http_shared.h Shared functions for implementations of HTTP requests.
12 #ifndef NETWORK_CORE_HTTP_SHARED_H
13 #define NETWORK_CORE_HTTP_SHARED_H
17 #include <condition_variable>
21 /** Converts a HTTPCallback to a Thread-Safe variant. */
22 class HTTPThreadSafeCallback
{
24 /** Entries on the queue for later handling. */
27 Callback(std::unique_ptr
<char[]> data
, size_t length
) : data(std::move(data
)), length(length
), failure(false) {}
28 Callback() : data(nullptr), length(0), failure(true) {}
30 std::unique_ptr
<char[]> data
;
37 * Similar to HTTPCallback::OnFailure, but thread-safe.
41 std::lock_guard
<std::mutex
> lock(this->mutex
);
42 this->queue
.emplace_back();
46 * Similar to HTTPCallback::OnReceiveData, but thread-safe.
48 void OnReceiveData(std::unique_ptr
<char[]> data
, size_t length
)
50 std::lock_guard
<std::mutex
> lock(this->mutex
);
51 this->queue
.emplace_back(std::move(data
), length
);
55 * Process everything on the queue.
57 * Should be called from the Game Thread.
61 this->cancelled
= callback
->IsCancelled();
63 std::lock_guard
<std::mutex
> lock(this->mutex
);
65 for (auto &item
: this->queue
) {
67 this->callback
->OnFailure();
69 this->callback
->OnReceiveData(std::move(item
.data
), item
.length
);
74 this->queue_cv
.notify_all();
78 * Wait till the queue is dequeued, or a condition is met.
79 * @param condition Condition functor.
82 void WaitTillEmptyOrCondition(T condition
)
84 std::unique_lock
<std::mutex
> lock(this->mutex
);
86 while (!(queue
.empty() || condition())) {
87 this->queue_cv
.wait(lock
);
92 * Check if the queue is empty.
96 std::lock_guard
<std::mutex
> lock(this->mutex
);
97 return this->queue
.empty();
100 HTTPThreadSafeCallback(HTTPCallback
*callback
) : callback(callback
) {}
102 ~HTTPThreadSafeCallback()
104 std::lock_guard
<std::mutex
> lock(this->mutex
);
106 /* Clear the list and notify explicitly. */
108 queue_cv
.notify_all();
111 std::atomic
<bool> cancelled
= false;
114 HTTPCallback
*callback
; ///< The callback to send data back on.
115 std::mutex mutex
; ///< Mutex to protect the queue.
116 std::vector
<Callback
> queue
; ///< Queue of data to send back.
117 std::condition_variable queue_cv
; ///< Condition variable to wait for the queue to be empty.
120 #endif /* NETWORK_CORE_HTTP_SHARED_H */