mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-09 09:38:19 +00:00
Improve Windows pipe (FIFO) support
Use `WaitForPipeDrain` to deterministically wait for the pipe to drain instead of using `Start-Sleep`. Use `Dispose` instead of `Close` to properly flush and close the pipe stream. Add error handling for connection timeout and I/O errors. Handle `ERROR_BROKEN_PIPE` separately when peeking at pipe, as this happens when the pipe is disconnected immediately after connecting it or after reading the previous message. Don't ignore `ERROR_BAD_PIPE` anymore, as the pipe should never be in a disconnected (i.e. bad) state at this point of the function.
This commit is contained in:
parent
3ff799770c
commit
1604784669
|
@ -4,7 +4,7 @@
|
|||
# The second argument is the message to send.
|
||||
if ($args.length -lt 2) {
|
||||
Write-Output "Usage: ./send_named_pipe.ps1 <pipename> <message> [message] ... [message]"
|
||||
return
|
||||
exit -1
|
||||
}
|
||||
|
||||
$Wrapper = [pscustomobject]@{
|
||||
|
@ -18,16 +18,24 @@ $Wrapper = [pscustomobject]@{
|
|||
Reader = $null
|
||||
Writer = $null
|
||||
}
|
||||
$Wrapper.Pipe.Connect(5000)
|
||||
if (!$?) {
|
||||
return
|
||||
try {
|
||||
$Wrapper.Pipe.Connect(5000)
|
||||
$Wrapper.Reader = New-Object System.IO.StreamReader($Wrapper.Pipe)
|
||||
$Wrapper.Writer = New-Object System.IO.StreamWriter($Wrapper.Pipe)
|
||||
$Wrapper.Writer.AutoFlush = $true
|
||||
for ($i = 1; $i -lt $args.length; $i++) {
|
||||
$Wrapper.Writer.WriteLine($args[$i])
|
||||
}
|
||||
# Wait for pipe contents to be read.
|
||||
$Wrapper.Pipe.WaitForPipeDrain()
|
||||
# Dispose the pipe, which also calls Flush and Close.
|
||||
$Wrapper.Pipe.Dispose()
|
||||
# Explicity set error level 0 for success, as otherwise the current error level is kept.
|
||||
exit 0
|
||||
} catch [TimeoutException] {
|
||||
Write-Output "Timeout connecting to pipe"
|
||||
exit 1
|
||||
} catch [System.IO.IOException] {
|
||||
Write-Output "Broken pipe"
|
||||
exit 2
|
||||
}
|
||||
$Wrapper.Reader = New-Object System.IO.StreamReader($Wrapper.Pipe)
|
||||
$Wrapper.Writer = New-Object System.IO.StreamWriter($Wrapper.Pipe)
|
||||
$Wrapper.Writer.AutoFlush = $true
|
||||
for ($i = 1; $i -lt $args.length; $i++) {
|
||||
$Wrapper.Writer.WriteLine($args[$i])
|
||||
}
|
||||
# We need to wait because the lines will not be written if we close the pipe immediately
|
||||
Start-Sleep -Seconds 1.5
|
||||
$Wrapper.Pipe.Close()
|
||||
|
|
|
@ -154,7 +154,13 @@ void CFifo::Update()
|
|||
if(!PeekNamedPipe(m_pPipe, NULL, 0, NULL, &BytesAvailable, NULL))
|
||||
{
|
||||
const DWORD LastError = GetLastError();
|
||||
if(LastError != ERROR_BAD_PIPE) // pipe not connected, not an error
|
||||
if(LastError == ERROR_BROKEN_PIPE)
|
||||
{
|
||||
// Pipe was disconnected from the other side, either immediately
|
||||
// after connecting or after reading the previous message.
|
||||
DisconnectNamedPipe(m_pPipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string ErrorMsg = windows_format_system_message(LastError);
|
||||
dbg_msg("fifo", "failed to peek at pipe '%s' (%ld %s)", m_aFilename, LastError, ErrorMsg.c_str());
|
||||
|
|
Loading…
Reference in a new issue