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:
Vinnie Falco
2014-03-16 20:32:14 -07:00
parent 6546c30e17
commit d4a5c0353d
45 changed files with 1192 additions and 1469 deletions

View File

@@ -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;
}