📄 hxfsmgr.cpp
字号:
m_pRequest = pRequest;
if (m_pRequest)
{
m_pRequest->AddRef();
}
m_State = e_GetFileObjectPending;
#ifdef _MACINTOSH
if (!IsMacInCooperativeThread())
{
if (!m_pScheduler)
{
HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK);
}
if (!m_pCallback)
{
m_pCallback = new RMAFSManagerCallback(this);
m_pCallback->AddRef();
}
HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE);
if (!m_pCallback->m_bIsCallbackPending)
{
m_pCallback->m_bIsCallbackPending = TRUE;
m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0);
}
return HXR_OK;
}
#endif
return (ProcessGetFileObjectPending());
}
HX_RESULT
HXFileSystemManager::ProcessGetFileObjectPending()
{
HX_LOG_BLOCK( "HXFileSystemManager::ProcessGetFileObjectPending" );
HX_RESULT theErr = HXR_OK;
IUnknown* pUnknownFS = NULL;
IUnknown* pUnknownFileObject = NULL;
IHXFileSystemObject* pFileSystem = NULL;
IHXRequestHandler* pRequestHandler = NULL;
IHXPlugin2Handler* pPlugin2Handler = NULL;
if (!m_pContext)
{
return HXR_FAILED;
}
/*
* We might get released (and deleted) in the response object. so
* Addref here and Release after the response function is called
*/
AddRef();
// get the plugin handler
if (HXR_OK != m_pContext->QueryInterface(IID_IHXPlugin2Handler, (void**)&pPlugin2Handler))
{
theErr = HXR_FAILED;
goto exit;
}
const char* pURL;
HX_ASSERT( NULL != m_pRequest );
if ( ( NULL == m_pRequest ) || ( m_pRequest->GetURL(pURL) != HXR_OK ) )
{
theErr = HXR_FAILED;
goto exit;
}
const char* pProtocolEnd;
pProtocolEnd = HXFindChar(pURL,':');
if (!pProtocolEnd)
{
theErr = HXR_FAILED;
}
if (!theErr)
{
int nLength = pProtocolEnd - pURL;
CHXString strProtocol(pURL,nLength);
if (HXR_OK != (theErr = pPlugin2Handler->FindPluginUsingStrings(PLUGIN_CLASS, PLUGIN_FILESYSTEM_TYPE,
PLUGIN_FILESYSTEMPROTOCOL, (char*)(const char*)strProtocol, NULL, NULL, pUnknownFS)))
{
goto exit;
}
IHXPlugin* pPluginInterface = NULL;
if(!theErr)
{
theErr = pUnknownFS->QueryInterface(IID_IHXPlugin,
(void**)&pPluginInterface);
}
if(!theErr)
{
theErr = pPluginInterface->InitPlugin(m_pContext);
pPluginInterface->Release();
}
if(!theErr)
{
theErr = pUnknownFS->QueryInterface(IID_IHXFileSystemObject,
(void**)&pFileSystem);
}
// At this point we should initalize the file system.to do this we must find the
// IHXValues for this mount path in the Options Cache.
IHXValues* pOptions = NULL;
pOptions = GetOptionsGivenURL(pURL);
pFileSystem->InitFileSystem(pOptions);
HX_RELEASE(pOptions);
if(!theErr)
{
theErr = pFileSystem->CreateFile(&pUnknownFileObject);
}
if(!theErr)
{
if(HXR_OK == pUnknownFileObject->QueryInterface(
IID_IHXRequestHandler,
(void**)&pRequestHandler))
{
pRequestHandler->SetRequest(m_pRequest);
}
else
{
theErr = HXR_FAILED;
}
}
}
else
{
theErr = HXR_FAILED;
}
if (!theErr && pUnknownFileObject)
{
m_pFSManagerResponse->FileObjectReady(HXR_OK, pUnknownFileObject);
}
else
{
m_pFSManagerResponse->FileObjectReady(HXR_FAILED, NULL);
}
exit:
HX_RELEASE(pUnknownFS);
HX_RELEASE(pUnknownFileObject);
HX_RELEASE(pRequestHandler);
HX_RELEASE(pFileSystem);
HX_RELEASE(pPlugin2Handler);
#ifndef _MACINTOSH
// Note: This change is necessary for the Macintosh build due to the fact
// that this platform uses a different approach in GetFileObject. The problem
// is that file object processing had generally been done recursively, with
// GetFileObject calling ProcessGetFileObjectPending, which in turn indirectly
// invoked GetFileObject in a pattern of mutual recursion. The recursion had
// always ended with a call to ProcessGetFileObjectPending. With the change
// in GetFileObject:
// #ifdef _MACINTOSH
// if (!IsMacInCooperativeThread())
// the recursion would terminate in a GetFileObject call. This call would
// unwind to the scheduler, which would then process the queued file object
// by calling ProcessGetFileObjectPending. However, since the request object
// was freed during the unwinding of the recursion, this object was no longer
// available and hence the process failed.
//
// The best short term fix appears to be to remove this release. The best long
// term fix is to eliminate the recursion (which would also simplify maintenance).
// -cconover XXX
HX_RELEASE(m_pRequest);
#endif
/*
* Release for extra Addref
*/
Release();
return theErr;
}
/*
* In this implementation of FSManager, GetNewFileObject is wholly
* equivalent to GetFileObject. GetNewFileObject exists for the
* server's FSManager since it would otherwise be impossible to get
* a brand new file object for writing, as the DoesExist checks
* would fail for every file system checked. This implementation has
* ambiguities between URL's and file systems, so there is no
* different functionality needed.
*/
STDMETHODIMP
HXFileSystemManager::GetNewFileObject(IHXRequest* pRequest,
IHXAuthenticator* pAuthenticator)
{
return GetFileObject(pRequest, pAuthenticator);
}
STDMETHODIMP
HXFileSystemManager::GetRelativeFileObject(IUnknown* pOriginalObject,
const char* pRelativePath)
{
HX_RESULT theErr = HXR_OK;
if(!pRelativePath)
{
return HXR_FAIL;
}
HX_RELEASE(m_pOriginalObject);
m_pOriginalObject = pOriginalObject;
if (m_pOriginalObject)
{
m_pOriginalObject->AddRef();
}
HX_VECTOR_DELETE(m_pRelativePath);
m_pRelativePath = new_string(pRelativePath);
m_State = e_GetRelativeFileObjectPending;
#ifdef _MACINTOSH
if (!IsMacInCooperativeThread())
{
if (!m_pScheduler)
{
HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK);
}
if (!m_pCallback)
{
m_pCallback = new RMAFSManagerCallback(this);
m_pCallback->AddRef();
}
HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE);
if (!m_pCallback->m_bIsCallbackPending)
{
m_pCallback->m_bIsCallbackPending = TRUE;
m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0);
}
return HXR_OK;
}
#endif
return (ProcessGetRelativeFileObjectPending());
}
HX_RESULT
HXFileSystemManager::ProcessGetRelativeFileObjectPending()
{
HX_RESULT theErr = HXR_OK;
IHXRequestHandler* pRequestHandlerOrigional = NULL;
IHXRequest* pRequestOld = NULL;
AddRef();
if (!m_pOriginalObject)
goto exit;
if(HXR_OK != m_pOriginalObject->QueryInterface(IID_IHXGetFileFromSamePool,
(void**)&m_pSamePool))
{
theErr = HXR_FAIL;
goto exit;
}
if
(
HXR_OK != m_pOriginalObject->QueryInterface
(
IID_IHXRequestHandler,
(void**)&pRequestHandlerOrigional
)
||
!pRequestHandlerOrigional
||
HXR_OK != pRequestHandlerOrigional->GetRequest(pRequestOld)
||
!pRequestOld
)
{
HX_RELEASE(pRequestHandlerOrigional);
HX_RELEASE(pRequestOld);
theErr = HXR_FAIL;
goto exit;
}
HX_RELEASE(pRequestHandlerOrigional);
/*
* Create an IHXRequest object for the new file
*/
HX_RELEASE(m_pRequest);
CHXRequest::CreateFrom(pRequestOld, &m_pRequest);
HX_RELEASE(pRequestOld);
m_pRequest->SetURL(m_pRelativePath);
if(HXR_OK != m_pSamePool->GetFileObjectFromPool(this))
{
theErr = HXR_FAIL;
goto exit;
}
exit:
HX_RELEASE(m_pSamePool);
HX_RELEASE(m_pOriginalObject);
HX_VECTOR_DELETE(m_pRelativePath);
Release();
return theErr;
}
STDMETHODIMP
HXFileSystemManager::FileObjectReady(HX_RESULT status, IUnknown* pUnknown)
{
IHXRequestHandler* pRequestHandler = NULL;
if(HXR_OK == status)
{
if(HXR_OK == pUnknown->QueryInterface(IID_IHXRequestHandler,
(void**)&pRequestHandler))
{
pRequestHandler->SetRequest(m_pRequest);
}
else
{
pUnknown = 0;
status = HXR_FAILED;
}
pRequestHandler->Release();
}
HX_RELEASE(m_pRequest);
/*
* We might get released (and deleted) in the response object. so
* Addref here and Release after the response function is called
*/
AddRef();
if (m_pFSManagerResponse)
{
m_pFSManagerResponse->FileObjectReady(status, pUnknown);
}
/*
* Release for extra Addref
*/
Release();
return HXR_OK;
}
STDMETHODIMP
HXFileSystemManager::GetDirObjectFromURL(const char* pURL)
{
return HXR_NOTIMPL;
}
void
HXFileSystemManager::ProcessPendingRequest()
{
switch(m_State)
{
case e_GetFileObjectPending:
ProcessGetFileObjectPending();
break;
case e_GetRelativeFileObjectPending:
ProcessGetRelativeFileObjectPending();
break;
default:
HX_ASSERT(FALSE);
break;
}
}
// HXFileSystemManager::RMAFSManagerCallback
HXFileSystemManager::RMAFSManagerCallback::RMAFSManagerCallback(HXFileSystemManager* pFSManager) :
m_lRefCount (0)
,m_pFSManager (pFSManager)
,m_Handle (0)
,m_bIsCallbackPending(FALSE)
{
}
HXFileSystemManager::RMAFSManagerCallback::~RMAFSManagerCallback()
{
}
/*
* IUnknown methods
*/
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
// Purpose:
// Implement this to export the interfaces supported by your
// object.
//
STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this },
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXCallback*)this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/*
* UDPSchedulerCallback methods
*/
STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::Func(void)
{
m_Handle = 0;
m_bIsCallbackPending = FALSE;
if (m_pFSManager)
{
m_pFSManager->ProcessPendingRequest();
}
return HXR_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -