/* void cancelAndForgetObserver (in nsresult aStatus); */ NS_IMETHODIMP imgRequestProxy::CancelAndForgetObserver(nsresult aStatus) { if (mCanceled || !mOwner) return NS_ERROR_FAILURE; LOG_SCOPE(gImgLog, "imgRequestProxy::CancelAndForgetObserver"); mCanceled = PR_TRUE; // Now cheat and make sure our removal from loadgroup happens async PRBool oldIsInLoadGroup = mIsInLoadGroup; mIsInLoadGroup = PR_FALSE; // Passing false to aNotify means that mListener will still get // OnStopRequest, if needed. mOwner->RemoveProxy(this, aStatus, PR_FALSE); mIsInLoadGroup = oldIsInLoadGroup; if (mIsInLoadGroup) { nsCOMPtr<nsIRunnable> ev = NS_NEW_RUNNABLE_METHOD(imgRequestProxy, this, DoRemoveFromLoadGroup); NS_DispatchToCurrentThread(ev); } NullOutListener(); return NS_OK; }
nsresult sbCDDeviceMarshall::DiscoverDevices() { // Iterate over the available CD devices and check to see if they have // media currently inserted. nsresult rv; NS_ENSURE_STATE(mCDDeviceService); nsCOMPtr<nsIThreadPool> threadPoolService = do_GetService("@songbirdnest.com/Songbird/ThreadPoolService;1", &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIThreadManager> threadMgr = do_GetService("@mozilla.org/thread-manager;1", &rv); NS_ENSURE_SUCCESS(rv, rv); // Save the threading context for notifying the listeners on the current // thread once the scan has ended. rv = threadMgr->GetCurrentThread(getter_AddRefs(mOwnerContextThread)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIRunnable> runnable = NS_NEW_RUNNABLE_METHOD(sbCDDeviceMarshall, this, RunDiscoverDevices); NS_ENSURE_TRUE(runnable, NS_ERROR_FAILURE); rv = threadPoolService->Dispatch(runnable, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
NS_IMETHODIMP sbWin32FileSystemWatcher::OnTreeReady(const nsAString & aTreeRootPath, sbStringArray & aDirPathArray) { TRACE("%s: root path %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aTreeRootPath).get()); if (mWatchPath.Equals(EmptyString())) { // If the watch path is empty here, this means that the tree was loaded // from a previous session. Set the watch path now. mWatchPath.Assign(aTreeRootPath); } // Setup the timer callback nsresult rv; NS_ENSURE_STATE(!mRebuildThread); // Setup the timer callback, on a background thread nsCOMPtr<nsIRunnable> initRebuildEvent = NS_NEW_RUNNABLE_METHOD(sbWin32FileSystemWatcher, this, InitRebuildThread); NS_ENSURE_TRUE(initRebuildEvent, NS_ERROR_OUT_OF_MEMORY); rv = NS_NewThread(getter_AddRefs(mRebuildThread), initRebuildEvent); NS_ENSURE_SUCCESS(rv, rv); // Get a handle to the root directory. mRootDirHandle = CreateFileW(mWatchPath.get(), // path GENERIC_READ, // desired access FILE_SHARE_READ | // shared mode FILE_SHARE_WRITE, NULL, // security attributes OPEN_EXISTING, // creation disposition FILE_FLAG_BACKUP_SEMANTICS | // flags and attributes FILE_FLAG_OVERLAPPED, NULL); // template file NS_ENSURE_TRUE(mRootDirHandle != INVALID_HANDLE_VALUE, NS_ERROR_UNEXPECTED); memset(&mOverlapped, 0, sizeof(mOverlapped)); mOverlapped.hEvent = (HANDLE)this; if (!mBuffer) { mBuffer = nsMemory::Alloc(BUFFER_LEN); } // Start the watcher thread. if (!mIsThreadRunning) { mShouldRunThread = PR_TRUE; mWatcherThread = CreateThread(NULL, 0, BackgroundThreadProc, this, 0, NULL); NS_ENSURE_TRUE(mWatcherThread != INVALID_HANDLE_VALUE, NS_ERROR_OUT_OF_MEMORY); } mIsWatching = PR_TRUE; rv = mListener->OnWatcherStarted(); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
void sbCDDeviceMarshall::RunDiscoverDevices() { // Since the GW stuff is a little jacked, use the index getter PRInt32 deviceCount = 0; nsresult rv = mCDDeviceService->GetNbDevices(&deviceCount); NS_ENSURE_SUCCESS(rv, /* void */); // Notify of scan start. nsCOMPtr<nsIRunnable> runnable = NS_NEW_RUNNABLE_METHOD(sbCDDeviceMarshall, this, RunNotifyDeviceStartScan); NS_ENSURE_TRUE(runnable, /* void */); rv = mOwnerContextThread->Dispatch(runnable, NS_DISPATCH_SYNC); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "WARNING: Could not notify of device start scan!"); for (PRInt32 i = 0; i < deviceCount; i++) { nsCOMPtr<sbICDDevice> curDevice; rv = mCDDeviceService->GetDevice(i, getter_AddRefs(curDevice)); if (NS_FAILED(rv) || !curDevice) { NS_WARNING("Could not get the current device!"); continue; } // Add the device on the main thread. rv = sbInvokeOnThread1(*this, &sbCDDeviceMarshall::AddDevice, NS_ERROR_FAILURE, curDevice.get(), mOwnerContextThread); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Could not add a CD Device!"); } // Notify of scan end. runnable = NS_NEW_RUNNABLE_METHOD(sbCDDeviceMarshall, this, RunNotifyDeviceStopScan); NS_ENSURE_TRUE(runnable, /* void */); rv = mOwnerContextThread->Dispatch(runnable, NS_DISPATCH_SYNC); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "WARNING: Could not notify of device start scan!"); }
NS_IMETHODIMP nsFileUploadContentStream::AsyncWait(nsIInputStreamCallback *callback, PRUint32 flags, PRUint32 count, nsIEventTarget *target) { nsresult rv = nsBaseContentStream::AsyncWait(callback, flags, count, target); if (NS_FAILED(rv) || IsClosed()) return rv; if (IsNonBlocking()) { nsCOMPtr<nsIRunnable> callback = NS_NEW_RUNNABLE_METHOD(nsFileUploadContentStream, this, OnCopyComplete); mCopyEvent->Dispatch(callback, mSink, target); } return NS_OK; }
nsresult sbFileMetadataService::ProxiedRestartProcessors(PRUint16 aProcessorsToRestart) { TRACE(("%s[%.8x]", __FUNCTION__, this)); nsresult rv = NS_OK; if (!NS_IsMainThread()) { LOG(("%s[%.8x] proxying main thread RestartProcessors()", __FUNCTION__, this)); nsCOMPtr<nsIThread> target; rv = NS_GetMainThread(getter_AddRefs(target)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<sbIFileMetadataService> proxy; rv = do_GetProxyForObject(target, NS_GET_IID(sbIFileMetadataService), static_cast<sbIFileMetadataService*>(this), NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(proxy)); NS_ENSURE_SUCCESS(rv, rv); // Can't call ProxiedRestartProcessors via proxy, since it is not // an interface method. rv = proxy->RestartProcessors(aProcessorsToRestart); NS_ENSURE_SUCCESS(rv, rv); } else { NS_ENSURE_STATE(mMainThreadProcessor); NS_ENSURE_STATE(mBackgroundThreadProcessor); if (aProcessorsToRestart & sbIFileMetadataService::MAIN_THREAD_PROCESSOR) { rv = mMainThreadProcessor->Start(); NS_ENSURE_SUCCESS(rv, rv); } if (aProcessorsToRestart & sbIFileMetadataService::BACKGROUND_THREAD_PROCESSOR) { nsCOMPtr<nsIRunnable> event = NS_NEW_RUNNABLE_METHOD(sbBackgroundThreadMetadataProcessor, mBackgroundThreadProcessor.get(), Start); NS_DispatchToCurrentThread(event); } } return NS_OK; }
nsresult nsPACMan::LoadPACFromURI(nsIURI *pacURI) { NS_ENSURE_STATE(!mShutdown); NS_ENSURE_ARG(pacURI || mPACURI); nsCOMPtr<nsIStreamLoader> loader = do_CreateInstance(NS_STREAMLOADER_CONTRACTID); NS_ENSURE_STATE(loader); // Since we might get called from nsProtocolProxyService::Init, we need to // post an event back to the main thread before we try to use the IO service. // // But, we need to flag ourselves as loading, so that we queue up any PAC // queries the enter between now and when we actually load the PAC file. if (!mLoadPending) { nsCOMPtr<nsIRunnable> event = NS_NEW_RUNNABLE_METHOD(nsPACMan, this, StartLoading); nsresult rv; if (NS_FAILED(rv = NS_DispatchToCurrentThread(event))) return rv; mLoadPending = PR_TRUE; } CancelExistingLoad(); mLoader = loader; if (pacURI) { mPACURI = pacURI; mLoadFailureCount = 0; // reset } mScheduledReload = LL_MAXINT; mPAC = nsnull; return NS_OK; }
/* void run (); */ NS_IMETHODIMP sbTestMediacoreStressThreads::Run() { NS_ENSURE_FALSE(mMonitor, NS_ERROR_ALREADY_INITIALIZED); mMonitor = nsAutoMonitor::NewMonitor(__FILE__); NS_ENSURE_TRUE(mMonitor, NS_ERROR_OUT_OF_MEMORY); nsresult rv; mBaseEventTarget = new sbBaseMediacoreEventTarget(this); rv = mBaseEventTarget->AddListener(static_cast<sbIMediacoreEventListener*>(this)); NS_ENSURE_SUCCESS(rv, rv); // spin up a *ton* of threads... mCounter = 0; for (int i = 0; i < 100; ++i) { nsAutoMonitor mon(mMonitor); nsCOMPtr<nsIRunnable> event = NS_NEW_RUNNABLE_METHOD(sbTestMediacoreStressThreads, this, OnEvent); NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY); nsCOMPtr<nsIThread> thread; ++mCounter; rv = NS_NewThread(getter_AddRefs(thread), event); NS_ENSURE_SUCCESS(rv, rv); mThreads.AppendObject(thread); } // and wait for them to receive their messages... spin event loop until that // happens. We need to wait explicitly as the OnEvent method does not directly // queue all the events needed to complete the test - some get queued later, // so calling thread->Shutdown() at this point will not allow the test to // complete correctly. nsCOMPtr<nsIThread> target; rv = NS_GetMainThread(getter_AddRefs(target)); NS_ENSURE_SUCCESS(rv, rv); PRBool processed = PR_FALSE; while(mCounter > 0) { rv = target->ProcessNextEvent(PR_FALSE, &processed); NS_ENSURE_SUCCESS(rv, rv); } // Now shutdown all the threads while (mThreads.Count()) { nsCOMPtr<nsIThread> thread = mThreads[0]; PRBool succeeded = mThreads.RemoveObjectAt(0); NS_ENSURE_TRUE(succeeded, NS_ERROR_FAILURE); rv = thread->Shutdown(); NS_ENSURE_SUCCESS(rv, rv); } rv = mBaseEventTarget->RemoveListener(static_cast<sbIMediacoreEventListener*>(this)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(mCounter == 0, NS_ERROR_FAILURE); mBaseEventTarget = nsnull; return NS_OK; }
nsresult sbProcess::Run() { PRStatus status; nsresult rv; // Set up to auto-kill process. sbAutoKillProcess autoSelf(this); // Operate under the process lock. { NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED); nsAutoLock autoProcessLock(mProcessLock); // Get the number of arguments. PRUint32 argCount = mArgList.Length(); NS_ENSURE_TRUE(argCount > 0, NS_ERROR_ILLEGAL_VALUE); // Convert the UTF-16 argument list to a UTF-8 argument list. nsTArray<nsCString> argListUTF8; for (PRUint32 i = 0; i < argCount; i++) { NS_ENSURE_TRUE(argListUTF8.AppendElement (NS_ConvertUTF16toUTF8(mArgList[i])), NS_ERROR_OUT_OF_MEMORY); } // Allocate a null-terminated char* argument list and set it up for // auto-disposal. char** argList = reinterpret_cast<char**> (NS_Alloc((argCount + 1) * sizeof(char*))); NS_ENSURE_TRUE(argList, NS_ERROR_OUT_OF_MEMORY); sbAutoNSTypePtr<char*> autoArgList(argList); // Convert the argument list to a null-terminated char* argument list. for (PRUint32 i = 0; i < argCount; i++) { argList[i] = const_cast<char*>(argListUTF8[i].get()); } argList[argCount] = NULL; // Set up the process attributes and set them up for auto-disposal. PRProcessAttr* processAttr = PR_NewProcessAttr(); NS_ENSURE_TRUE(processAttr, NS_ERROR_FAILURE); sbAutoPRProcessAttr autoProcessAttr(processAttr); // Set up process stdin. if (mPipeStdinString) { // Create a process stdin pipe and set it up for auto-disposal. PRFileDesc* stdinReadFD; PRFileDesc* stdinWriteFD; status = PR_CreatePipe(&stdinReadFD, &stdinWriteFD); NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE); sbAutoPRFileDesc autoStdinReadFD(stdinReadFD); sbAutoPRFileDesc autoStdinWriteFD(stdinWriteFD); // Set up stdin pipe file descriptors. status = PR_SetFDInheritable(stdinReadFD, PR_TRUE); NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE); status = PR_SetFDInheritable(stdinWriteFD, PR_FALSE); NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE); // Fill pipe. nsCAutoString writeData = NS_ConvertUTF16toUTF8(mStdinString); PRInt32 bytesWritten; bytesWritten = PR_Write(stdinWriteFD, writeData.get(), writeData.Length()); NS_ENSURE_TRUE(bytesWritten == writeData.Length(), NS_ERROR_FAILURE); // Redirect process stdin. PR_ProcessAttrSetStdioRedirect(processAttr, PR_StandardInput, stdinReadFD); // Keep stdin read descriptor open for the process to read. Close the // stdin write descriptor so that the process gets EOF when all of the // data is read. mStdinReadFD = autoStdinReadFD.forget(); PR_Close(autoStdinWriteFD.forget()); } // Set up process stdout. if (mPipeStdoutString) { // Create a process stdout pipe and set it up for auto-disposal. PRFileDesc* stdoutReadFD; PRFileDesc* stdoutWriteFD; status = PR_CreatePipe(&stdoutReadFD, &stdoutWriteFD); NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE); sbAutoPRFileDesc autoStdoutReadFD(stdoutReadFD); sbAutoPRFileDesc autoStdoutWriteFD(stdoutWriteFD); // Set up stdout pipe file descriptors. status = PR_SetFDInheritable(stdoutReadFD, PR_FALSE); NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE); status = PR_SetFDInheritable(stdoutWriteFD, PR_TRUE); NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE); // Redirect process stdout. PR_ProcessAttrSetStdioRedirect(processAttr, PR_StandardOutput, stdoutWriteFD); // Keep descriptors. mStdoutReadFD = autoStdoutReadFD.forget(); mStdoutWriteFD = autoStdoutWriteFD.forget(); } // Create and start running the process. mBaseProcess = PR_CreateProcess(argList[0], argList, NULL, processAttr); NS_ENSURE_TRUE(mBaseProcess, NS_ERROR_FAILURE); // Wait for process done on another thread. nsCOMPtr<nsIRunnable> runnable = NS_NEW_RUNNABLE_METHOD(sbProcess, this, WaitForDone); NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY); rv = NS_NewThread(getter_AddRefs(mWaitForDoneThread), runnable); NS_ENSURE_SUCCESS(rv, rv); } // Clear process auto-kill. autoSelf.forget(); return NS_OK; }