mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
Kernel: Fix race conditions processing async device requests
This commit is contained in:
parent
8177f2474b
commit
5ccc3637e3
Notes:
sideshowbarker
2024-07-18 21:20:56 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/5ccc3637e34 Pull-request: https://github.com/SerenityOS/serenity/pull/5796
@ -91,15 +91,11 @@ void AsyncDeviceRequest::add_sub_request(NonnullRefPtr<AsyncDeviceRequest> sub_r
|
||||
VERIFY(sub_request->m_parent_request == nullptr);
|
||||
sub_request->m_parent_request = this;
|
||||
|
||||
bool should_start;
|
||||
{
|
||||
ScopedSpinLock lock(m_lock);
|
||||
VERIFY(!is_completed_result(m_result));
|
||||
m_sub_requests_pending.append(sub_request);
|
||||
should_start = (m_result == Started);
|
||||
}
|
||||
if (should_start)
|
||||
sub_request->do_start();
|
||||
ScopedSpinLock lock(m_lock);
|
||||
VERIFY(!is_completed_result(m_result));
|
||||
m_sub_requests_pending.append(sub_request);
|
||||
if (m_result == Started)
|
||||
sub_request->do_start(move(lock));
|
||||
}
|
||||
|
||||
void AsyncDeviceRequest::sub_request_finished(AsyncDeviceRequest& sub_request)
|
||||
|
@ -78,9 +78,14 @@ public:
|
||||
|
||||
[[nodiscard]] RequestWaitResult wait(Time* = nullptr);
|
||||
|
||||
void do_start(Badge<Device>)
|
||||
void do_start(ScopedSpinLock<SpinLock<u8>>&& requests_lock)
|
||||
{
|
||||
do_start();
|
||||
if (is_completed_result(m_result))
|
||||
return;
|
||||
m_result = Started;
|
||||
requests_lock.unlock();
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void complete(RequestResult result);
|
||||
@ -137,17 +142,6 @@ private:
|
||||
void sub_request_finished(AsyncDeviceRequest&);
|
||||
void request_finished();
|
||||
|
||||
void do_start()
|
||||
{
|
||||
{
|
||||
ScopedSpinLock lock(m_lock);
|
||||
if (is_completed_result(m_result))
|
||||
return;
|
||||
m_result = Started;
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
bool in_target_context(const UserOrKernelBuffer& buffer) const
|
||||
{
|
||||
if (buffer.is_kernel_buffer())
|
||||
|
@ -82,20 +82,15 @@ String Device::absolute_path(const FileDescription&) const
|
||||
|
||||
void Device::process_next_queued_request(Badge<AsyncDeviceRequest>, const AsyncDeviceRequest& completed_request)
|
||||
{
|
||||
AsyncDeviceRequest* next_request = nullptr;
|
||||
|
||||
{
|
||||
ScopedSpinLock lock(m_requests_lock);
|
||||
VERIFY(!m_requests.is_empty());
|
||||
VERIFY(m_requests.first().ptr() == &completed_request);
|
||||
m_requests.remove(m_requests.begin());
|
||||
if (!m_requests.is_empty())
|
||||
next_request = m_requests.first().ptr();
|
||||
ScopedSpinLock lock(m_requests_lock);
|
||||
VERIFY(!m_requests.is_empty());
|
||||
VERIFY(m_requests.first().ptr() == &completed_request);
|
||||
m_requests.remove(m_requests.begin());
|
||||
if (!m_requests.is_empty()) {
|
||||
auto* next_request = m_requests.first().ptr();
|
||||
next_request->do_start(move(lock));
|
||||
}
|
||||
|
||||
if (next_request)
|
||||
next_request->start();
|
||||
|
||||
evaluate_block_conditions();
|
||||
}
|
||||
|
||||
|
@ -72,14 +72,11 @@ public:
|
||||
NonnullRefPtr<AsyncRequestType> make_request(Args&&... args)
|
||||
{
|
||||
auto request = adopt(*new AsyncRequestType(*this, forward<Args>(args)...));
|
||||
bool was_empty;
|
||||
{
|
||||
ScopedSpinLock lock(m_requests_lock);
|
||||
was_empty = m_requests.is_empty();
|
||||
m_requests.append(request);
|
||||
}
|
||||
ScopedSpinLock lock(m_requests_lock);
|
||||
bool was_empty = m_requests.is_empty();
|
||||
m_requests.append(request);
|
||||
if (was_empty)
|
||||
request->do_start({});
|
||||
request->do_start(move(lock));
|
||||
return request;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user