📄 macasyncfile.cpp
字号:
m_ulReadPositionInFile = 0;
if(result == HXR_OK)
{
ReadAsyncData(bAtInterrupt);
}
//
// Set it to null.
//
mFilePos = 0;
m_pMutex->Unlock();
return result;
}
HX_RESULT CMacAsyncFile::Close(void)
{
m_pMutex->Lock();
HX_RESULT result = CMacFile::Close();
EmptyAsyncQueue();
mReadQueue->FlushQueue();
m_pMutex->Unlock();
return result;
}
HX_RESULT CMacAsyncFile::Seek(ULONG32 offset, UINT16 fromWhere)
{
return HXR_NOTIMPL;
}
void
CMacAsyncFile::PerformInternalSeek(BOOL ASYNC)
{
m_pMutex->Lock();
mSeekFromWhere = fsFromStart;
mSeekPos = m_ulReadPositionInFile;
UpdateFilePos(ASYNC, TRUE);
m_pMutex->Unlock();
}
HX_RESULT
CMacAsyncFile::SafeSeek(ULONG32 offset, UINT16 fromWhere, BOOL bAtInterrupt)
{
#if defined(_DEBUG) && defined (_LOG_DATA)
char str[255]; /* Flawfinder: ignore */
::sprintf(str, "SafeSeek: %lu %u %d;g", offset, fromWhere, (int) bAtInterrupt); /* Flawfinder: ignore */
DEBUGSTR(c2pstr(str));
#endif
if (m_pMutex) m_pMutex->Lock();
//dfprintf("mem","SafeSeek: %lu, %u, %d\n", offset, fromWhere, (int) bAtInterrupt);
m_bFileDone = FALSE;
m_bReadPending = FALSE;
LISTPOSITION pos = NULL;
/* If we get a read deferred callback while setting the state for buffers in
* async queue, ignore it
*/
m_bSettingSeekState = TRUE;
pos = mAsyncQueue->GetHeadPosition();
while(pos)
{
HXAsyncQueueBuffer *x =(HXAsyncQueueBuffer *) mAsyncQueue->GetAt(pos);
if(x->state == AB_STATE_FULL)
{
DeleteAsyncQueueBuffer(x, pos);
pos = mAsyncQueue->GetHeadPosition();
continue;
//x->state = AB_STATE_IGNORED;
}
/* All other states are pending states and result in AB_STATE_OUTOFCONTEXT */
else if(x->state != AB_STATE_IGNORED)
{
x->state = AB_STATE_OUTOFCONTEXT;
}
mAsyncQueue->GetNext(pos);
}
m_bSettingSeekState = FALSE;
mReadQueue->FlushQueue();
m_bSeekPending = TRUE;
if(BufferedWrite())
{
CMacFile::Seek(offset, fromWhere);
PendingAsyncSeekDone();
}
else
{
UINT32 ulSeekPosition = 0;
BOOL bSeekNeeded = FALSE;
switch(fromWhere)
{
case SEEK_SET:
fromWhere = fsFromStart;
mSeekFromWhere = fromWhere;
mSeekPos = offset;
ulSeekPosition = m_ulReadPositionInFile = offset;
break;
case SEEK_CUR:
fromWhere = fsFromMark;
mSeekFromWhere = fromWhere;
mSeekPos = offset;
ulSeekPosition = m_ulReadPositionInFile = mFilePos+offset;
break;
case SEEK_END:
//HX_ASSERT(!"Need to add support for seek from end -- XXXRA");
fromWhere = fsFromLEOF;
mSeekFromWhere = fromWhere;
mSeekPos = offset;
bSeekNeeded = TRUE;
break;
}
if (!bSeekNeeded)
{
bSeekNeeded = !(FillBufferFromPQ(ulSeekPosition));
}
if (bSeekNeeded)
{
UpdateFilePos(bAtInterrupt);
}
else
{
mFilePos = ulSeekPosition;
mSeekFromWhere = 0;
m_bInternalSeekNeeded = TRUE;
PendingAsyncSeekDone();
}
}
DEBUGSTR("\p EXIT SafeSeek;g");
if (m_pMutex) m_pMutex->Unlock();
return HXR_OK;
}
HX_RESULT
CMacAsyncFile::SafeRead(ULONG32 count, BOOL bAtInterrupt)
{
AddRef();
m_pMutex->Lock();
HX_ASSERT(m_bReadPending == FALSE);
if(!mReadQueue || m_bReadPending)
{
DEBUGSTR("\p SafeRead UNEXPECTED;g");
//dfprintf("mem", "SafeRead UNEXPECTED\n");
m_pMutex->Unlock();
Release();
return HXR_UNEXPECTED;
}
#if defined(_DEBUG) && defined (_LOG_DATA)
char str[255]; /* Flawfinder: ignore */
::sprintf(str, "SafeRead: %lu %d;g", count, (int) bAtInterrupt); /* Flawfinder: ignore */
DEBUGSTR(c2pstr(str));
#endif
//dfprintf("mem","SafeRead: %lu, %d\n", count, (int) bAtInterrupt);
m_bReadPending = TRUE;
m_ulPendingReadCount = count;
EnqueueAsyncBuffers();
ReadAsyncData(bAtInterrupt);
EnqueueAsyncBuffers();
ProcessPendingRead();
DEBUGSTR("\p EXIT SafeRead;g");
m_pMutex->Unlock();
Release();
return HXR_OK;
}
ULONG32
CMacAsyncFile::SafeWrite(IHXBuffer* pBuffer, BOOL bAtInterrupt)
{
m_pMutex->Lock();
HX_ASSERT(m_bReadPending == FALSE);
ULONG32 outWrittenSize = 0;
if(m_bReadPending)
{
DEBUGSTR("\p SafeWrite UNEXPECTED;g");
m_pMutex->Unlock();
return outWrittenSize;
}
#if defined(_DEBUG) && defined (_LOG_DATA)
char str[255]; /* Flawfinder: ignore */
::sprintf(str, "SafeWrite: %d;g", (int) bAtInterrupt); /* Flawfinder: ignore */
DEBUGSTR(c2pstr(str));
#endif
outWrittenSize = WriteAsyncData(pBuffer, bAtInterrupt);
DEBUGSTR("\p EXIT SafeWrite;g");
m_pMutex->Unlock();
return outWrittenSize;
}
ULONG32 CMacAsyncFile::Read(char *buf, ULONG32 count)
{
return HXR_NOTIMPL;
}
//
// Static Initializers
//
#ifdef _CARBON
IOCompletionUPP CMacAsyncFile::zmIOCallbackUPP = NewIOCompletionUPP((IOCompletionProcPtr)CMacAsyncFile::zmIOCallback);
#else
IOCompletionUPP CMacAsyncFile::zmIOCallbackUPP = NewIOCompletionProc(CMacAsyncFile::zmIOCallback);
#endif
//
// Tell
//
ULONG32 CMacAsyncFile::Tell(void)
{
return mFilePos;
}
//
// This is the zmIOCompletion callback.
// When this is done, the data is then pumped into the buffer for this file.
//
pascal void CMacAsyncFile::zmIOCallback(HXParamBlockRec * pb)
{
HXMM_INTERRUPTON();
/*
* Setup and then install a deferred task
*/
if (pb != NULL && pb->param != NULL)
{
CMacAsyncFile* fileobj = (CMacAsyncFile*) pb->param;
fileobj->m_pMutex->Lock();
if (fileobj->m_DeferredTaskStruct.dtAddr != NULL)
{
#if defined(_DEBUG) && defined (_LOG_DATA)
char tmpStr1[255]; /* Flawfinder: ignore */
::sprintf(tmpStr1, "ENTER INterrupt Callback %p ;g", fileobj); /* Flawfinder: ignore */
DEBUGSTR(c2pstr(tmpStr1));
#endif
fileobj->AddToThePendingList((void*) pb);
fileobj->m_uNumDeferredTask++;
#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
/*
if (fileobj->m_uNumDeferredTask > 1)
{
char tmpStr[255];
::sprintf(tmpStr, "More than one pending DeferredTask: %u;g", fileobj->m_uNumDeferredTask);
DebugStr(c2pstr(tmpStr));
}
*/
#endif
if (!fileobj->m_bDeferredTaskPending)
{
if ( !fileobj->m_bIsQuitting )
{
fileobj->m_bDeferredTaskPending = TRUE;
#ifdef _CARBON
DeferredTaskProc(fileobj->m_DeferredTaskStruct.dtParam);
#else
DTInstall(&fileobj->m_DeferredTaskStruct);
#endif
}
}
}
fileobj->m_pMutex->Unlock();
}
HXMM_INTERRUPTOFF();
}
pascal void CMacAsyncFile::DeferredTaskProc(long inParam)
{
HXMM_INTERRUPTON();
DEBUGSTR("\pENTER CMacAsyncFile::DeferredTaskProc;g");
CMacAsyncFile* fileobj = (CMacAsyncFile*) inParam;;
if(fileobj)
{
#if defined(_DEBUG) && defined (_LOG_DATA)
char tmpStr[255]; /* Flawfinder: ignore */
sprintf(tmpStr, " This pointer: %p;g", fileobj); /* Flawfinder: ignore */
DEBUGSTR(c2pstr(tmpStr));
#endif
#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
/*
if (fileobj->m_uNumDeferredTask != 1)
{
char tmpStr[255];
::sprintf(tmpStr, "(In DeferredTaskProc) m_uNumDeferredTask != 1: %u;g", fileobj->m_uNumDeferredTask);
DebugStr(c2pstr(tmpStr));
}
*/
if ( !fileobj->m_bDeferredTaskPending )
{
DebugStr( "\p(In DeferredTaskProc) m_bDeferredTaskPending is false!;g" );
}
#endif
if ( !fileobj->m_bIsQuitting )
{
fileobj->ProcessPendingCallbacks();
}
fileobj->m_bDeferredTaskPending = FALSE;
}
DEBUGSTR("\pLEAVE CMacAsyncFile::DeferredTaskProc;g");
HXMM_INTERRUPTOFF();
}
void CMacAsyncFile::ProcessPendingCallbacks()
{
m_pMutex->Lock();
if (m_bInProcessPendingCallbacks)
{
m_pMutex->Unlock();
return;
}
start:
m_bInProcessPendingCallbacks = TRUE;
while (m_pPendingCallbackList && m_pPendingCallbackList->GetCount() > 0)
{
m_uNumDeferredTask--;
HXParamBlockRec* pb = (HXParamBlockRec*) m_pPendingCallbackList->RemoveHead();
if (pb && pb->param)
{
ProcessBlock(pb);
}
HX_DELETE(pb);
}
EnqueueAsyncBuffers();
if (m_bPendingAsyncSeekCompleted)
{
m_bPendingAsyncSeekCompleted = FALSE;
PendingAsyncSeekDone();
}
if (mOutStandingCallbacks == 0 && m_bAllCallbacksCompleted)
{
m_bAllCallbacksCompleted = FALSE;
AllPendingCallbacksDone();
}
m_bInProcessPendingCallbacks = FALSE;
/* Do we still have more pending callbacks to process? */
if (m_pPendingCallbackList && m_pPendingCallbackList->GetCount() > 0)
{
goto start;
}
m_pMutex->Unlock();
}
void CMacAsyncFile::ProcessBlock(HXParamBlockRec* pb)
{
m_pMutex->Lock();
if (mOutStandingCallbacks > 0)
{
mOutStandingCallbacks--;
}
if(pb->entry->state == AB_STATE_OUTOFCONTEXT ||
m_bSettingSeekState)
{
//
// Don't need to do anything with this data
// just ignore it.
//
pb->entry->state = AB_STATE_IGNORED;
}
else if (pb->entry->state == AB_STATE_ASYNC_INTERNAL_SEEK)
{
m_ulReadPositionInFile = pb->io.ioParam.ioPosOffset;
pb->entry->state = AB_STATE_IGNORED;
}
else if (pb->entry->state == AB_STATE_ASYNC_SEEK)
{
mFilePos = pb->io.ioParam.ioPosOffset;
m_ulReadPositionInFile = mFilePos;
pb->entry->state = AB_STATE_IGNORED;
m_bPendingAsyncSeekCompleted = TRUE;
}
else if (pb->entry->state == AB_STATE_WRITE)
{
HX_VECTOR_DELETE(pb->entry->buffer);
pb->entry->state = AB_STATE_IGNORED;
}
else
{
/* Are we at the end of the file? */
if (pb->io.ioParam.ioActCount < pb->entry->size)
{
m_bFileDone = TRUE;
#if defined(_DEBUG) && defined (_LOG_DATA)
char tmpStr[255]; /* Flawfinder: ignore */
sprintf(tmpStr, "ProcessBlock %d %d;g", pb->io.ioParam.ioActCount, pb->entry->size); /* Flawfinder: ignore */
DEBUGSTR(c2pstr(tmpStr));
#endif
}
pb->entry->size = pb->io.ioParam.ioActCount;
pb->entry->current_size = pb->io.ioParam.ioActCount;
if(pb->io.ioParam.ioBuffer && pb->entry->size > 0)
{
pb->entry->state = AB_STATE_FULL;
m_ulReadPositionInFile += pb->entry->size;
}
else
{
pb->entry->state = AB_STATE_IGNORED;
}
}
if (mOutStandingCallbacks == 0)
{
m_bAllCallbacksCompleted = TRUE;
}
m_pMutex->Unlock();
}
void CMacAsyncFile::AddToThePendingList(void* pNode)
{
m_pMutex->Lock();
/* Atleast one of the list MUST be free to operate on */
HX_ASSERT(m_pPendingCallbackList != NULL);
if (m_pPendingCallbackList)
{
m_pPendingCallbackList->AddTail(pNode);
}
m_pMutex->Unlock();
}
//
//
// Start the Async file IO call which physically reads the data into the buffer.
//
//
void CMacAsyncFile::ReadAsyncData(BOOL ASYNC)
{
m_pMutex->Lock();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -