Fix pipe destruction race condition.
This commit is contained in:
parent
12b5044bc7
commit
2727d9fb50
|
@ -59,7 +59,6 @@ public:
|
||||||
~PipeChannel();
|
~PipeChannel();
|
||||||
void CloseReading();
|
void CloseReading();
|
||||||
void CloseWriting();
|
void CloseWriting();
|
||||||
void PerhapsShutdown();
|
|
||||||
bool GetSIGPIPEDelivery();
|
bool GetSIGPIPEDelivery();
|
||||||
void SetSIGPIPEDelivery(bool deliver_sigpipe);
|
void SetSIGPIPEDelivery(bool deliver_sigpipe);
|
||||||
size_t ReadSize();
|
size_t ReadSize();
|
||||||
|
@ -90,6 +89,7 @@ private:
|
||||||
size_t pretended_read_buffer_size;
|
size_t pretended_read_buffer_size;
|
||||||
size_t pledged_read;
|
size_t pledged_read;
|
||||||
size_t pledged_write;
|
size_t pledged_write;
|
||||||
|
unsigned long closers;
|
||||||
bool anyreading;
|
bool anyreading;
|
||||||
bool anywriting;
|
bool anywriting;
|
||||||
bool is_sigpipe_enabled;
|
bool is_sigpipe_enabled;
|
||||||
|
@ -110,6 +110,7 @@ PipeChannel::PipeChannel(uint8_t* buffer, size_t buffersize)
|
||||||
receiver_system_tid = 0;
|
receiver_system_tid = 0;
|
||||||
pledged_read = 0;
|
pledged_read = 0;
|
||||||
pledged_write = 0;
|
pledged_write = 0;
|
||||||
|
closers = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PipeChannel::~PipeChannel()
|
PipeChannel::~PipeChannel()
|
||||||
|
@ -119,26 +120,27 @@ PipeChannel::~PipeChannel()
|
||||||
|
|
||||||
void PipeChannel::CloseReading()
|
void PipeChannel::CloseReading()
|
||||||
{
|
{
|
||||||
|
kthread_mutex_lock(&pipelock);
|
||||||
anyreading = false;
|
anyreading = false;
|
||||||
kthread_cond_broadcast(&writecond);
|
kthread_cond_broadcast(&writecond);
|
||||||
PerhapsShutdown();
|
read_poll_channel.Signal(ReadPollEventStatus());
|
||||||
|
write_poll_channel.Signal(WritePollEventStatus());
|
||||||
|
kthread_mutex_unlock(&pipelock);
|
||||||
|
unsigned long count = InterlockedIncrement(&closers).n;
|
||||||
|
if ( count == 2 )
|
||||||
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipeChannel::CloseWriting()
|
void PipeChannel::CloseWriting()
|
||||||
{
|
{
|
||||||
|
kthread_mutex_lock(&pipelock);
|
||||||
anywriting = false;
|
anywriting = false;
|
||||||
kthread_cond_broadcast(&readcond);
|
kthread_cond_broadcast(&readcond);
|
||||||
PerhapsShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipeChannel::PerhapsShutdown()
|
|
||||||
{
|
|
||||||
kthread_mutex_lock(&pipelock);
|
|
||||||
read_poll_channel.Signal(ReadPollEventStatus());
|
read_poll_channel.Signal(ReadPollEventStatus());
|
||||||
write_poll_channel.Signal(WritePollEventStatus());
|
write_poll_channel.Signal(WritePollEventStatus());
|
||||||
bool deleteme = !anyreading & !anywriting;
|
|
||||||
kthread_mutex_unlock(&pipelock);
|
kthread_mutex_unlock(&pipelock);
|
||||||
if ( deleteme )
|
unsigned long count = InterlockedIncrement(&closers).n;
|
||||||
|
if ( count == 2 )
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,6 +406,7 @@ void PipeEndpoint::Disconnect()
|
||||||
channel->CloseReading();
|
channel->CloseReading();
|
||||||
else
|
else
|
||||||
channel->CloseWriting();
|
channel->CloseWriting();
|
||||||
|
channel = NULL;
|
||||||
reading = false;
|
reading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue