mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
beast, beast::asio improvements and fixes:
* New maybe_const_t alias for maybe_const * New asio::enable_wait_for_async for safe cleanup * New asio::memory_buffer, a managed boost::asio compatible buffer * shared_handler improvements: - Can be 'empty' (no stored handler). - Default constructible as 'empty'. - Safe evaluation in bool contexts, false==empty * Fix is_call_possible metafunction: - Works on empty argument lists - Works with reference types * Replace SafeBool idiom with C++11 explicit operator bool * Move IPAddress function definitions to the header * Move cyclic_iterator to container/ * Remove unused BufferType * Remove obsolete classes: - NamedPipe - ReadWriteLock - ScopedReadLock - ScopedWriteLock - LockGuard
This commit is contained in:
@@ -883,226 +883,3 @@ void File::revealToUser() const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class NamedPipe::Pimpl : LeakChecked <NamedPipe::Pimpl>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
Pimpl (const String& pipeName, const bool createPipe)
|
||||
: filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)),
|
||||
pipeH (INVALID_HANDLE_VALUE),
|
||||
cancelEvent (CreateEvent (0, FALSE, FALSE, 0)),
|
||||
connected (false), ownsPipe (createPipe), shouldStop (false)
|
||||
{
|
||||
if (createPipe)
|
||||
pipeH = CreateNamedPipe (filename.toWideCharPointer(),
|
||||
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,
|
||||
PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0);
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
disconnectPipe();
|
||||
|
||||
if (pipeH != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (pipeH);
|
||||
|
||||
CloseHandle (cancelEvent);
|
||||
}
|
||||
|
||||
bool connect (const int timeOutMs)
|
||||
{
|
||||
if (! ownsPipe)
|
||||
{
|
||||
if (pipeH != INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
|
||||
const Time timeOutEnd (Time::getCurrentTime() + RelativeTime::milliseconds (timeOutMs));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
{
|
||||
const ScopedLock sl (createFileLock);
|
||||
|
||||
if (pipeH == INVALID_HANDLE_VALUE)
|
||||
pipeH = CreateFile (filename.toWideCharPointer(),
|
||||
GENERIC_READ | GENERIC_WRITE, 0, 0,
|
||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
||||
}
|
||||
|
||||
if (pipeH != INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
|
||||
if (shouldStop || (timeOutMs >= 0 && Time::getCurrentTime() > timeOutEnd))
|
||||
return false;
|
||||
|
||||
Thread::sleep (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (! connected)
|
||||
{
|
||||
OverlappedEvent over;
|
||||
|
||||
if (ConnectNamedPipe (pipeH, &over.over) == 0)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_PIPE_CONNECTED: connected = true; break;
|
||||
case ERROR_IO_PENDING:
|
||||
case ERROR_PIPE_LISTENING: connected = waitForIO (over, timeOutMs); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return connected;
|
||||
}
|
||||
|
||||
void disconnectPipe()
|
||||
{
|
||||
if (ownsPipe && connected)
|
||||
{
|
||||
DisconnectNamedPipe (pipeH);
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
int read (void* destBuffer, const int maxBytesToRead, const int timeOutMilliseconds)
|
||||
{
|
||||
while (connect (timeOutMilliseconds))
|
||||
{
|
||||
if (maxBytesToRead <= 0)
|
||||
return 0;
|
||||
|
||||
OverlappedEvent over;
|
||||
unsigned long numRead;
|
||||
|
||||
if (ReadFile (pipeH, destBuffer, (DWORD) maxBytesToRead, &numRead, &over.over))
|
||||
return (int) numRead;
|
||||
|
||||
const DWORD lastError = GetLastError();
|
||||
|
||||
if (lastError == ERROR_IO_PENDING)
|
||||
{
|
||||
if (! waitForIO (over, timeOutMilliseconds))
|
||||
return -1;
|
||||
|
||||
if (GetOverlappedResult (pipeH, &over.over, &numRead, FALSE))
|
||||
return (int) numRead;
|
||||
}
|
||||
|
||||
if (ownsPipe && (GetLastError() == ERROR_BROKEN_PIPE || GetLastError() == ERROR_PIPE_NOT_CONNECTED))
|
||||
disconnectPipe();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
||||
{
|
||||
if (connect (timeOutMilliseconds))
|
||||
{
|
||||
if (numBytesToWrite <= 0)
|
||||
return 0;
|
||||
|
||||
OverlappedEvent over;
|
||||
unsigned long numWritten;
|
||||
|
||||
if (WriteFile (pipeH, sourceBuffer, (DWORD) numBytesToWrite, &numWritten, &over.over))
|
||||
return (int) numWritten;
|
||||
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
if (! waitForIO (over, timeOutMilliseconds))
|
||||
return -1;
|
||||
|
||||
if (GetOverlappedResult (pipeH, &over.over, &numWritten, FALSE))
|
||||
return (int) numWritten;
|
||||
|
||||
if (GetLastError() == ERROR_BROKEN_PIPE && ownsPipe)
|
||||
disconnectPipe();
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const String filename;
|
||||
HANDLE pipeH, cancelEvent;
|
||||
bool connected, ownsPipe, shouldStop;
|
||||
CriticalSection createFileLock;
|
||||
|
||||
private:
|
||||
struct OverlappedEvent
|
||||
{
|
||||
OverlappedEvent()
|
||||
{
|
||||
zerostruct (over);
|
||||
over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
|
||||
}
|
||||
|
||||
~OverlappedEvent()
|
||||
{
|
||||
CloseHandle (over.hEvent);
|
||||
}
|
||||
|
||||
OVERLAPPED over;
|
||||
};
|
||||
|
||||
bool waitForIO (OverlappedEvent& over, int timeOutMilliseconds)
|
||||
{
|
||||
if (shouldStop)
|
||||
return false;
|
||||
|
||||
HANDLE handles[] = { over.over.hEvent, cancelEvent };
|
||||
DWORD waitResult = WaitForMultipleObjects (2, handles, FALSE,
|
||||
timeOutMilliseconds >= 0 ? timeOutMilliseconds
|
||||
: INFINITE);
|
||||
|
||||
if (waitResult == WAIT_OBJECT_0)
|
||||
return true;
|
||||
|
||||
CancelIo (pipeH);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void NamedPipe::close()
|
||||
{
|
||||
if (pimpl != nullptr)
|
||||
{
|
||||
pimpl->shouldStop = true;
|
||||
SetEvent (pimpl->cancelEvent);
|
||||
|
||||
ScopedWriteLock sl (lock);
|
||||
pimpl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
|
||||
{
|
||||
pimpl = new Pimpl (pipeName, createPipe);
|
||||
|
||||
if (createPipe && pimpl->pipeH == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pimpl = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
|
||||
{
|
||||
ScopedReadLock sl (lock);
|
||||
return pimpl != nullptr ? pimpl->read (destBuffer, maxBytesToRead, timeOutMilliseconds) : -1;
|
||||
}
|
||||
|
||||
int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
||||
{
|
||||
ScopedReadLock sl (lock);
|
||||
return pimpl != nullptr ? pimpl->write (sourceBuffer, numBytesToWrite, timeOutMilliseconds) : -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user