HRESULT StringDupUsingHeapAlloc( __in PCWSTR pszString, __deref_out PWSTR *ppszNewString ) { HRESULT hr = S_OK; size_t cchString = 0; PWSTR pszNewString = NULL; if ( NULL == pszString || NULL == ppszNewString ) { hr = E_INVALIDARG; } if ( SUCCEEDED(hr) ) { *ppszNewString = NULL; hr = StringCchLength( pszString, STRSAFE_MAX_CCH, &cchString); } if ( SUCCEEDED(hr) ) { cchString++; pszNewString = (PWSTR)MemAllocZ(cchString * sizeof(WCHAR) ); if ( NULL == pszNewString ) { hr = E_OUTOFMEMORY; } } if ( SUCCEEDED(hr) ) { hr = StringCchCopy(pszNewString, cchString, pszString); } if ( SUCCEEDED(hr) ) { *ppszNewString = pszNewString; } else { if ( pszNewString ) { MemFree(pszNewString); pszNewString = NULL; } } return hr; }
/** * Internal implementation of InvokeLater */ TBool CEcmtSdkPlugin::DoInvokeLater(TCallback aCallback, const void* aArg1, const void* aArg2, const void* aArg3) { WorkItem* workItem = (WorkItem*)MemAllocZ(sizeof(WorkItem)); if (workItem) { workItem->iCallback = aCallback; workItem->iArg1 = (void*)aArg1; workItem->iArg2 = (void*)aArg2; workItem->iArg3 = (void*)aArg3; Queue(workItem); return ETrue; } return EFalse; }
/** * Submits internal work item. Must be invoked on a Symbian thread */ TInt CEcmtSdkPlugin::SubmitInternal(TCallback aCallback, const void* aArg1, const void* aArg2, const void* aArg3) { WorkItem* workItem = (WorkItem*)MemAllocZ(sizeof(WorkItem)); if (workItem) { workItem->iCallback = aCallback; workItem->iArg1 = (void*)aArg1; workItem->iArg2 = (void*)aArg2; workItem->iArg3 = (void*)aArg3; QueueInternal(workItem); return KErrNone; } return KErrNoMemory; }
/** * Internal implementation of InvokeAndWait */ TBool CEcmtSdkPlugin::DoInvokeAndWait(TCallback aCallback, const void* aArg1, const void* aArg2, const void* aArg3) { WorkItem* workItem = (WorkItem*)MemAllocZ(sizeof(WorkItem)); if (workItem) { HANDLE hEvent = CreateEvent(NULL, ETrue, EFalse, NULL); if (hEvent) { workItem->iCallback = aCallback; workItem->iArg1 = (void*)aArg1; workItem->iArg2 = (void*)aArg2; workItem->iArg3 = (void*)aArg3; workItem->iEvent = hEvent; Queue(workItem); // Here we assume that the caller is not running in context // of a Symbian thread. If we are being "scheduled" by the // Symbian scheduler, we must call Emulator::Escape() before // supending the current thread, and Emulator::Reenter() after // we are done waiting. If we do that on a non-Symbian thread, // we get a panic. DWORD err; do { // When emulator is shutting down, it terminates the threads // and we may end up waiting forever. Hence this check. err = WaitForSingleObject(hEvent, 5000); } while (err == WAIT_TIMEOUT && IsStarted()); ASSERT(err == NO_ERROR); CloseHandle(hEvent); return (err == NO_ERROR); } MemFree(workItem); } return EFalse; }