Fixed a miniscule odds race condition found by tsan (Thread sanitizer)
in ThreadedIofile. Added loop to handle partial writes in ThreadedIoFile. Change-Id: Ib62855ab849ffbfd00afc5b226dd81d4cd38ff51
This commit is contained in:
parent
3615e0ea47
commit
51a7ff85c2
|
@ -14,6 +14,9 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
|
using base::subtle::NoBarrier_Load;
|
||||||
|
using base::subtle::NoBarrier_Store;
|
||||||
|
|
||||||
ThreadedIoFile::ThreadedIoFile(scoped_ptr<File, FileCloser> internal_file,
|
ThreadedIoFile::ThreadedIoFile(scoped_ptr<File, FileCloser> internal_file,
|
||||||
Mode mode,
|
Mode mode,
|
||||||
uint64_t io_cache_size,
|
uint64_t io_cache_size,
|
||||||
|
@ -70,12 +73,12 @@ int64_t ThreadedIoFile::Read(void* buffer, uint64_t length) {
|
||||||
DCHECK(thread_);
|
DCHECK(thread_);
|
||||||
DCHECK_EQ(kInputMode, mode_);
|
DCHECK_EQ(kInputMode, mode_);
|
||||||
|
|
||||||
if (internal_file_error_)
|
if (NoBarrier_Load(&eof_) && !cache_.BytesCached())
|
||||||
return internal_file_error_;
|
|
||||||
|
|
||||||
if (eof_ && !cache_.BytesCached())
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (NoBarrier_Load(&internal_file_error_))
|
||||||
|
return NoBarrier_Load(&internal_file_error_);
|
||||||
|
|
||||||
return cache_.Read(buffer, length);
|
return cache_.Read(buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +87,8 @@ int64_t ThreadedIoFile::Write(const void* buffer, uint64_t length) {
|
||||||
DCHECK(thread_);
|
DCHECK(thread_);
|
||||||
DCHECK_EQ(kOutputMode, mode_);
|
DCHECK_EQ(kOutputMode, mode_);
|
||||||
|
|
||||||
if (internal_file_error_)
|
if (NoBarrier_Load(&internal_file_error_))
|
||||||
return internal_file_error_;
|
return NoBarrier_Load(&internal_file_error_);
|
||||||
|
|
||||||
size_ += length;
|
size_ += length;
|
||||||
return cache_.Write(buffer, length);
|
return cache_.Write(buffer, length);
|
||||||
|
@ -118,8 +121,8 @@ void ThreadedIoFile::RunInInputMode() {
|
||||||
int64_t read_result = internal_file_->Read(&io_buffer_[0],
|
int64_t read_result = internal_file_->Read(&io_buffer_[0],
|
||||||
io_buffer_.size());
|
io_buffer_.size());
|
||||||
if (read_result <= 0) {
|
if (read_result <= 0) {
|
||||||
eof_ = read_result == 0;
|
NoBarrier_Store(&eof_, read_result == 0);
|
||||||
internal_file_error_ = read_result;
|
NoBarrier_Store(&internal_file_error_, read_result);
|
||||||
cache_.Close();
|
cache_.Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -153,13 +156,17 @@ void ThreadedIoFile::RunInOutputMode() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int64_t write_result = internal_file_->Write(&io_buffer_[0], write_bytes);
|
uint64_t bytes_written(0);
|
||||||
if (write_result < 0) {
|
while (bytes_written < write_bytes) {
|
||||||
internal_file_error_ = write_result;
|
int64_t write_result = internal_file_->Write(
|
||||||
cache_.Close();
|
&io_buffer_[bytes_written], write_bytes - bytes_written);
|
||||||
return;
|
if (write_result < 0) {
|
||||||
|
NoBarrier_Store(&internal_file_error_, write_result);
|
||||||
|
cache_.Close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bytes_written += write_result;
|
||||||
}
|
}
|
||||||
CHECK_EQ(write_result, static_cast<int64_t>(write_bytes));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#ifndef PACKAGER_FILE_THREADED_IO_FILE_H_
|
#ifndef PACKAGER_FILE_THREADED_IO_FILE_H_
|
||||||
#define PACKAGER_FILE_THREADED_IO_FILE_H_
|
#define PACKAGER_FILE_THREADED_IO_FILE_H_
|
||||||
|
|
||||||
|
#include "packager/base/atomicops.h"
|
||||||
#include "packager/base/memory/scoped_ptr.h"
|
#include "packager/base/memory/scoped_ptr.h"
|
||||||
#include "packager/base/synchronization/lock.h"
|
#include "packager/base/synchronization/lock.h"
|
||||||
#include "packager/base/synchronization/waitable_event.h"
|
#include "packager/base/synchronization/waitable_event.h"
|
||||||
|
@ -58,10 +59,10 @@ class ThreadedIoFile : public File {
|
||||||
std::vector<uint8_t> io_buffer_;
|
std::vector<uint8_t> io_buffer_;
|
||||||
scoped_ptr<ClosureThread> thread_;
|
scoped_ptr<ClosureThread> thread_;
|
||||||
uint64_t size_;
|
uint64_t size_;
|
||||||
bool eof_;
|
base::subtle::Atomic32 eof_;
|
||||||
bool flushing_;
|
bool flushing_;
|
||||||
base::WaitableEvent flush_complete_event_;
|
base::WaitableEvent flush_complete_event_;
|
||||||
int64_t internal_file_error_;
|
base::subtle::Atomic32 internal_file_error_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ThreadedIoFile);
|
DISALLOW_COPY_AND_ASSIGN(ThreadedIoFile);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue