Я написал класс для обработки соединений с именованными каналами, и если я создаю экземпляр, закрываю его, а затем пытаюсь создать другой экземпляр, вызов CreateFile() возвращает INVALID_HANDLE_VALUE, а GetLastError() возвращает ERROR_PIPE_BUSY. Что тут происходит? Что я могу сделать, чтобы вызов Connect() был успешным?
PipeAsync A, B;
A.Connect("\\\\.\\pipe\\test",5000);
A.Close();
cout << GetLastError(); // some random value
B.Connect("\\\\.\\pipe\\test",5000);
cout << GetLastError(); // 231 (ERROR_PIPE_BUSY)
B.Close();
Вот мои реализации Connect() и Close()
BOOL PipeAsync::Connect(LPCSTR pszPipeName, DWORD dwTimeout)
{
this->pszPipeName = pszPipeName;
this->fExisting = TRUE;
DWORD dwMode = this->fMessageMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE;
hPipe = CreateFile(
this->pszPipeName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if( INVALID_HANDLE_VALUE == hPipe )
return FALSE; /* set break point here ; breaks here on second call to Connect() */
if( GetLastError() == ERROR_PIPE_BUSY )
if(!WaitNamedPipe( this->pszPipeName, dwTimeout ))
return FALSE; /* set break point here */
if( !SetNamedPipeHandleState( hPipe, &dwMode, NULL, NULL ) )
return FALSE; /* set break point here */
return TRUE;
}
VOID PipeAsync::Close()
{
if( fExisting )
DisconnectNamedPipe( hPipe );
CloseHandle( hPipe );
}
РЕДАКТИРОВАТЬ: я забыл рассказать вам, как я пришел к этому выводу... Я установил точки останова, указанные в комментариях. При запуске он останавливается на первой точке останова.
EDIT: Это мой обновленный код
if( INVALID_HANDLE_VALUE == hPipe )
if( GetLastError() == ERROR_PIPE_BUSY )
{
if(!WaitNamedPipe( this->pszPipeName, dwTimeout ))
return FALSE; /* break-point: breaks here on second call */
}
else
return FALSE; /* break-point /*
Теперь WaitNamedPipe() возвращает false при втором вызове Connect(), а GetLastError() возвращает 2 или ERROR_FILE_NOT_FOUND?
\\,\pи\tбудут интерпретироваться как escape-символы. Либо переключитесь на прямую косую черту, либо на двойную обратную косую черту, чтобы избежать экранирования:"\\\\.\\pipe\\test". - person Xeo   schedule 16.12.2011