|
@@ -692,23 +692,34 @@ struct BfOverlappedReleaser
|
|
{
|
|
{
|
|
BfpAsyncData* mAsyncData;
|
|
BfpAsyncData* mAsyncData;
|
|
OverlappedReadResult* mOverlapped;
|
|
OverlappedReadResult* mOverlapped;
|
|
|
|
+ bool mProducerFree;
|
|
|
|
+ bool mConsumerFree;
|
|
|
|
|
|
BfOverlappedReleaser()
|
|
BfOverlappedReleaser()
|
|
{
|
|
{
|
|
mAsyncData = NULL;
|
|
mAsyncData = NULL;
|
|
mOverlapped = NULL;
|
|
mOverlapped = NULL;
|
|
|
|
+ mProducerFree = true;
|
|
|
|
+ mConsumerFree = true;
|
|
}
|
|
}
|
|
|
|
|
|
BfOverlappedReleaser(BfpAsyncData* asyncData, OverlappedReadResult* overlapped)
|
|
BfOverlappedReleaser(BfpAsyncData* asyncData, OverlappedReadResult* overlapped)
|
|
{
|
|
{
|
|
mAsyncData = asyncData;
|
|
mAsyncData = asyncData;
|
|
mOverlapped = overlapped;
|
|
mOverlapped = overlapped;
|
|
|
|
+ mProducerFree = true;
|
|
|
|
+ mConsumerFree = true;
|
|
}
|
|
}
|
|
|
|
|
|
~BfOverlappedReleaser()
|
|
~BfOverlappedReleaser()
|
|
{
|
|
{
|
|
if (mOverlapped != NULL)
|
|
if (mOverlapped != NULL)
|
|
- mAsyncData->Release(mOverlapped);
|
|
|
|
|
|
+ {
|
|
|
|
+ if (mProducerFree)
|
|
|
|
+ mAsyncData->Release(mOverlapped);
|
|
|
|
+ if (mConsumerFree)
|
|
|
|
+ mAsyncData->Release(mOverlapped);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -742,7 +753,7 @@ struct BfpFile
|
|
};
|
|
};
|
|
|
|
|
|
static void WINAPI OverlappedReadComplete(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
|
|
static void WINAPI OverlappedReadComplete(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
|
|
-{
|
|
|
|
|
|
+{
|
|
OverlappedReadResult* readResult = (OverlappedReadResult*)lpOverlapped;
|
|
OverlappedReadResult* readResult = (OverlappedReadResult*)lpOverlapped;
|
|
readResult->mFile->mAsyncData->HandleResult(readResult, dwErrorCode, dwNumberOfBytesTransfered);
|
|
readResult->mFile->mAsyncData->HandleResult(readResult, dwErrorCode, dwNumberOfBytesTransfered);
|
|
}
|
|
}
|
|
@@ -3322,6 +3333,16 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (file->mAsyncData != NULL)
|
|
|
|
+ {
|
|
|
|
+ int readSize = file->mAsyncData->ReadQueued(buffer, (int)size);
|
|
|
|
+ if (readSize > 0)
|
|
|
|
+ {
|
|
|
|
+ OUTRESULT(BfpFileResult_Ok);
|
|
|
|
+ return readSize;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if ((timeoutMS != -1) && (!forceNormalRead))
|
|
if ((timeoutMS != -1) && (!forceNormalRead))
|
|
{
|
|
{
|
|
if (file->mAsyncData == NULL)
|
|
if (file->mAsyncData == NULL)
|
|
@@ -3331,27 +3352,21 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
|
|
}
|
|
}
|
|
|
|
|
|
while (true)
|
|
while (true)
|
|
- {
|
|
|
|
- int readSize = file->mAsyncData->ReadQueued(buffer, (int)size);
|
|
|
|
- if (readSize > 0)
|
|
|
|
- {
|
|
|
|
- OUTRESULT(BfpFileResult_Ok);
|
|
|
|
- return readSize;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ {
|
|
OverlappedReadResult* overlapped = file->mAsyncData->AllocBuffer((int)size);
|
|
OverlappedReadResult* overlapped = file->mAsyncData->AllocBuffer((int)size);
|
|
- overlapped->mFile = file;
|
|
|
|
|
|
+ overlapped->mFile = file;
|
|
|
|
|
|
BfOverlappedReleaser overlappedReleaser(file->mAsyncData, overlapped);
|
|
BfOverlappedReleaser overlappedReleaser(file->mAsyncData, overlapped);
|
|
|
|
|
|
//TODO: this doesn't set file stream location. It only works for streams like pipes, sockets, etc
|
|
//TODO: this doesn't set file stream location. It only works for streams like pipes, sockets, etc
|
|
if (::ReadFileEx(file->mHandle, overlapped->GetPtr(), (uint32)size, overlapped, OverlappedReadComplete))
|
|
if (::ReadFileEx(file->mHandle, overlapped->GetPtr(), (uint32)size, overlapped, OverlappedReadComplete))
|
|
{
|
|
{
|
|
|
|
+ overlappedReleaser.mProducerFree = false;
|
|
file->mAsyncData->WaitAndResetEvent(timeoutMS);
|
|
file->mAsyncData->WaitAndResetEvent(timeoutMS);
|
|
|
|
|
|
DWORD errorCode = 0;
|
|
DWORD errorCode = 0;
|
|
int readResult = file->mAsyncData->FinishRead(overlapped, buffer, (int)size, errorCode);
|
|
int readResult = file->mAsyncData->FinishRead(overlapped, buffer, (int)size, errorCode);
|
|
- overlappedReleaser.mOverlapped = NULL;
|
|
|
|
|
|
+ overlappedReleaser.mConsumerFree = false;
|
|
if (readResult != -2)
|
|
if (readResult != -2)
|
|
{
|
|
{
|
|
if (errorCode == 0)
|
|
if (errorCode == 0)
|
|
@@ -3382,6 +3397,8 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
|
|
+ overlapped->mData.Clear();
|
|
|
|
+
|
|
int lastError = ::GetLastError();
|
|
int lastError = ::GetLastError();
|
|
if (lastError == ERROR_PIPE_LISTENING)
|
|
if (lastError == ERROR_PIPE_LISTENING)
|
|
{
|
|
{
|