[ConnectionFileDescriptor] Add shutdown check in ::Write.

The disconnect method sets the shutdown flag to true. This currently
only prevents any reads from happening, but not writes, which is
incorrect. Presumably this was just an oversight when adding
synchronization to the class. This adds the same shutdown check to the
Write method.

Over-the-shoulder reviewed by Jim!

llvm-svn: 370002
This commit is contained in:
Jonas Devlieghere 2019-08-27 01:34:16 +00:00
parent 25abd0ebdd
commit ece176e0f6
1 changed files with 12 additions and 3 deletions

View File

@ -312,9 +312,6 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
// descriptor. If that's the case, then send the "q" char to the command // descriptor. If that's the case, then send the "q" char to the command
// file channel so the read will wake up and the connection will then know to // file channel so the read will wake up and the connection will then know to
// shut down. // shut down.
m_shutting_down = true;
std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock); std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
if (!locker.try_lock()) { if (!locker.try_lock()) {
if (m_pipe.CanWrite()) { if (m_pipe.CanWrite()) {
@ -334,6 +331,9 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
locker.lock(); locker.lock();
} }
// Prevents reads and writes during shutdown.
m_shutting_down = true;
Status error = m_read_sp->Close(); Status error = m_read_sp->Close();
Status error2 = m_write_sp->Close(); Status error2 = m_write_sp->Close();
if (error.Fail() || error2.Fail()) if (error.Fail() || error2.Fail())
@ -369,6 +369,8 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
} }
if (m_shutting_down) { if (m_shutting_down) {
if (error_ptr)
error_ptr->SetErrorString("shutting down");
status = eConnectionStatusError; status = eConnectionStatusError;
return 0; return 0;
} }
@ -473,6 +475,13 @@ size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len,
return 0; return 0;
} }
if (m_shutting_down) {
if (error_ptr)
error_ptr->SetErrorString("shutting down");
status = eConnectionStatusError;
return 0;
}
Status error; Status error;
size_t bytes_sent = src_len; size_t bytes_sent = src_len;