RefPtr<MediaDataDecoder::InitPromise> GMPAudioDecoder::Init() { MOZ_ASSERT(IsOnGMPThread()); mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1"); MOZ_ASSERT(mMPS); nsCOMPtr<nsIThread> gmpThread = NS_GetCurrentThread(); RefPtr<GMPInitDoneRunnable> initDone(new GMPInitDoneRunnable()); gmpThread->Dispatch( NS_NewRunnableMethodWithArg<GMPInitDoneRunnable*>(this, &GMPAudioDecoder::GetGMPAPI, initDone), NS_DISPATCH_NORMAL); while (!initDone->IsDone()) { NS_ProcessNextEvent(gmpThread, true); } return mGMP ? InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__) : InitPromise::CreateAndReject(MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__); }
bool ProxyAutoConfig::ResolveAddress(const nsCString &aHostName, NetAddr *aNetAddr, unsigned int aTimeout) { nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID); if (!dns) return false; nsRefPtr<PACResolver> helper = new PACResolver(); if (NS_FAILED(dns->AsyncResolve(aHostName, 0, helper, NS_GetCurrentThread(), getter_AddRefs(helper->mRequest)))) return false; if (aTimeout && helper->mRequest) { if (!mTimer) mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); if (mTimer) { mTimer->InitWithCallback(helper, aTimeout, nsITimer::TYPE_ONE_SHOT); helper->mTimer = mTimer; } } // Spin the event loop of the pac thread until lookup is complete. // nsPACman is responsible for keeping a queue and only allowing // one PAC execution at a time even when it is called re-entrantly. while (helper->mRequest) NS_ProcessNextEvent(NS_GetCurrentThread()); if (NS_FAILED(helper->mStatus) || NS_FAILED(helper->mResponse->GetNextAddr(0, aNetAddr))) return false; return true; }
int main(int argc, char* argv[]) { nsresult rv; { XRE_AddStaticComponent(&kTestModule); nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return -1; nsCString previous; nsCOMPtr<nsIStreamConverterService> StreamConvService = do_GetService(kStreamConverterServiceCID, &rv); if (NS_FAILED(rv)) return -1; // Define the *from* content type and *to* content-type for conversion. static const char fromStr[] = "a/foo"; static const char toStr[] = "c/foo"; #ifdef ASYNC_TEST // ASYNCHRONOUS conversion // Build up a channel that represents the content we're // starting the transaction with. // // sample multipart mixed content-type string: // "multipart/x-mixed-replacE;boundary=thisrandomstring" #if 0 nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIURI> dummyURI; rv = NS_NewURI(getter_AddRefs(dummyURI), "http://meaningless"); if (NS_FAILED(rv)) return -1; rv = NS_NewInputStreamChannel(getter_AddRefs(channel), dummyURI, nullptr, // inStr "text/plain", // content-type -1); // XXX fix contentLength if (NS_FAILED(rv)) return -1; nsCOMPtr<nsIRequest> request(do_QueryInterface(channel)); #endif nsCOMPtr<nsIRequest> request; // setup a listener to receive the converted data. This guy is the end // listener in the chain, he wants the fully converted (toType) data. // An example of this listener in mozilla would be the DocLoader. nsIStreamListener *dataReceiver = new EndListener(); NS_ADDREF(dataReceiver); // setup a listener to push the data into. This listener sits inbetween the // unconverted data of fromType, and the final listener in the chain (in this case // the dataReceiver. nsIStreamListener *converterListener = nullptr; rv = StreamConvService->AsyncConvertData(fromStr, toStr, dataReceiver, nullptr, &converterListener); if (NS_FAILED(rv)) return -1; NS_RELEASE(dataReceiver); // at this point we have a stream listener to push data to, and the one // that will receive the converted data. Let's mimic On*() calls and get the conversion // going. Typically these On*() calls would be made inside their respective wrappers On*() // methods. rv = converterListener->OnStartRequest(request, nullptr); if (NS_FAILED(rv)) return -1; rv = SEND_DATA("aaa"); if (NS_FAILED(rv)) return -1; rv = SEND_DATA("aaa"); if (NS_FAILED(rv)) return -1; // Finish the request. rv = converterListener->OnStopRequest(request, nullptr, rv); if (NS_FAILED(rv)) return -1; NS_RELEASE(converterListener); #else // SYNCHRONOUS conversion nsCOMPtr<nsIInputStream> convertedData; rv = StreamConvService->Convert(inputData, fromStr, toStr, nullptr, getter_AddRefs(convertedData)); if (NS_FAILED(rv)) return -1; #endif // Enter the message pump to allow the URL load to proceed. while ( gKeepRunning ) { if (!NS_ProcessNextEvent(thread)) break; } } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM NS_ShutdownXPCOM(nullptr); return 0; }
/** * Delete the profile directory being reset after a backup and delete the local profile directory. */ nsresult ProfileResetCleanup(nsIToolkitProfile* aOldProfile) { nsresult rv; nsCOMPtr<nsIFile> profileDir; rv = aOldProfile->GetRootDir(getter_AddRefs(profileDir)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIFile> profileLocalDir; rv = aOldProfile->GetLocalDir(getter_AddRefs(profileLocalDir)); if (NS_FAILED(rv)) return rv; // Get the friendly name for the backup directory. nsCOMPtr<nsIStringBundleService> sbs = mozilla::services::GetStringBundleService(); if (!sbs) return NS_ERROR_FAILURE; nsCOMPtr<nsIStringBundle> sb; rv = sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb)); if (!sb) return NS_ERROR_FAILURE; NS_ConvertUTF8toUTF16 appName(gAppData->name); const PRUnichar* params[] = {appName.get(), appName.get()}; nsXPIDLString resetBackupDirectoryName; static const PRUnichar* kResetBackupDirectory = NS_LITERAL_STRING("resetBackupDirectory").get(); rv = sb->FormatStringFromName(kResetBackupDirectory, params, 2, getter_Copies(resetBackupDirectoryName)); // Get info to copy the old root profile dir to the desktop as a backup. nsCOMPtr<nsIFile> backupDest, uniqueDest; rv = NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(backupDest)); if (NS_FAILED(rv)) { // Fall back to the home directory if the desktop is not available. rv = NS_GetSpecialDirectory(NS_OS_HOME_DIR, getter_AddRefs(backupDest)); if (NS_FAILED(rv)) return rv; } // Try to get a unique backup directory name. backupDest->Clone(getter_AddRefs(uniqueDest)); uniqueDest->Append(resetBackupDirectoryName); rv = uniqueDest->CreateUnique(nsIFile::DIRECTORY_TYPE, 0700); if (NS_FAILED(rv)) return rv; nsAutoString leafName; rv = uniqueDest->GetLeafName(leafName); if (NS_FAILED(rv)) return rv; // Delete the empty directory that CreateUnique just created. rv = uniqueDest->Remove(false); if (NS_FAILED(rv)) return rv; // Show a progress window while the cleanup happens since the disk I/O can take time. nsCOMPtr<nsIWindowWatcher> windowWatcher(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); if (!windowWatcher) return NS_ERROR_FAILURE; nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID)); if (!appStartup) return NS_ERROR_FAILURE; nsCOMPtr<nsIDOMWindow> progressWindow; rv = windowWatcher->OpenWindow(nullptr, kResetProgressURL, "_blank", "centerscreen,chrome,titlebar", NULL, getter_AddRefs(progressWindow)); if (NS_FAILED(rv)) return rv; // Create a new thread to do the bulk of profile cleanup to stay responsive. nsCOMPtr<nsIThreadManager> tm = do_GetService(NS_THREADMANAGER_CONTRACTID); nsCOMPtr<nsIThread> cleanupThread; rv = tm->NewThread(0, 0, getter_AddRefs(cleanupThread)); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIRunnable> runnable = new ProfileResetCleanupAsyncTask(profileDir, profileLocalDir, backupDest, leafName); cleanupThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL); // The result callback will shut down the worker thread. nsIThread *thread = NS_GetCurrentThread(); // Wait for the cleanup thread to complete. while(!gProfileResetCleanupCompleted) { NS_ProcessNextEvent(thread); } } else { gProfileResetCleanupCompleted = true; NS_WARNING("Cleanup thread creation failed"); return rv; } // Close the progress window now that the cleanup thread is done. progressWindow->Close(); // Delete the old profile from profiles.ini. The folder was already deleted above. rv = aOldProfile->Remove(false); if (NS_FAILED(rv)) NS_WARNING("Could not remove the profile"); return rv; }
int main(int argc, char **argv) { nsresult rv; { nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); if (registrar) registrar->AutoRegister(nsnull); printf("*** getting ipc service\n"); nsCOMPtr<ipcIService> ipcServ(do_GetService(IPC_SERVICE_CONTRACTID, &rv)); RETURN_IF_FAILED(rv, "do_GetService(ipcServ)"); NS_ADDREF(gIpcServ = ipcServ); if (argc > 1) { printf("*** using client name [%s]\n", argv[1]); gIpcServ->AddName(argv[1]); } ipcServ->DefineTarget(kTestTargetID, new myIpcMessageObserver(), PR_TRUE); const char data[] = "01 this is a really long message.\n" "02 this is a really long message.\n" "03 this is a really long message.\n" "04 this is a really long message.\n" "05 this is a really long message.\n" "06 this is a really long message.\n" "07 this is a really long message.\n" "08 this is a really long message.\n" "09 this is a really long message.\n" "10 this is a really long message.\n" "11 this is a really long message.\n" "12 this is a really long message.\n" "13 this is a really long message.\n" "14 this is a really long message.\n" "15 this is a really long message.\n" "16 this is a really long message.\n" "17 this is a really long message.\n" "18 this is a really long message.\n" "19 this is a really long message.\n" "20 this is a really long message.\n" "21 this is a really long message.\n" "22 this is a really long message.\n" "23 this is a really long message.\n" "24 this is a really long message.\n" "25 this is a really long message.\n" "26 this is a really long message.\n" "27 this is a really long message.\n" "28 this is a really long message.\n" "29 this is a really long message.\n" "30 this is a really long message.\n" "31 this is a really long message.\n" "32 this is a really long message.\n" "33 this is a really long message.\n" "34 this is a really long message.\n" "35 this is a really long message.\n" "36 this is a really long message.\n" "37 this is a really long message.\n" "38 this is a really long message.\n" "39 this is a really long message.\n" "40 this is a really long message.\n" "41 this is a really long message.\n" "42 this is a really long message.\n" "43 this is a really long message.\n" "44 this is a really long message.\n" "45 this is a really long message.\n" "46 this is a really long message.\n" "47 this is a really long message.\n" "48 this is a really long message.\n" "49 this is a really long message.\n" "50 this is a really long message.\n" "51 this is a really long message.\n" "52 this is a really long message.\n" "53 this is a really long message.\n" "54 this is a really long message.\n" "55 this is a really long message.\n" "56 this is a really long message.\n" "57 this is a really long message.\n" "58 this is a really long message.\n" "59 this is a really long message.\n" "60 this is a really long message.\n"; SendMsg(ipcServ, 0, kTestTargetID, data, sizeof(data), PR_TRUE); // PRUint32 queryID; // nsCOMPtr<ipcIClientQueryHandler> handler(new myIpcClientQueryHandler()); // ipcServ->QueryClientByName("foopy", handler, PR_FALSE, &queryID); PRUint32 foopyID; nsresult foopyRv = ipcServ->ResolveClientName("foopy", &foopyID); printf("*** query for 'foopy' returned [rv=%x id=%u]\n", foopyRv, foopyID); if (NS_SUCCEEDED(foopyRv)) { const char hello[] = "hello friend!"; SendMsg(ipcServ, foopyID, kTestTargetID, hello, sizeof(hello)); } // // test lock service // nsCOMPtr<ipcILockService> lockService = do_GetService(IPC_LOCKSERVICE_CONTRACTID, &rv); RETURN_IF_FAILED(rv, "do_GetService(ipcLockServ)"); NS_ADDREF(gIpcLockServ = lockService); //nsCOMPtr<ipcILockNotify> notify(new myIpcLockNotify()); gIpcLockServ->AcquireLock("blah", PR_TRUE); rv = gIpcLockServ->AcquireLock("foo", PR_TRUE); printf("*** sync AcquireLock returned [rv=%x]\n", rv); nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); while (gKeepRunning) NS_ProcessNextEvent(thread); NS_RELEASE(gIpcServ); printf("*** processing remaining events\n"); // process any remaining events NS_ProcessPendingEvents(thread); printf("*** done\n"); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM rv = NS_ShutdownXPCOM(nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); return 0; }
int main(int argc, char* argv[]) { nsresult rv; { nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); if (registrar) registrar->AutoRegister(nsnull); nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsCString previous; /////////////////////////////////////////// // BEGIN - Stream converter registration // All stream converters must register with the ComponentManager /////////////////////////////////////////// // these stream converters are just for testing. running this harness // from the dist/bin dir will also pickup converters registered // in other modules (necko converters for example). PRUint32 converterListSize = 7; const char *const converterList[] = { "?from=a/foo&to=b/foo", "?from=b/foo&to=c/foo", "?from=b/foo&to=d/foo", "?from=c/foo&to=d/foo", "?from=d/foo&to=e/foo", "?from=d/foo&to=f/foo", "?from=t/foo&to=k/foo", }; TestConverterFactory *convFactory = new TestConverterFactory(kTestConverterCID, "TestConverter", NS_ISTREAMCONVERTER_KEY); nsCOMPtr<nsIFactory> convFactSup(do_QueryInterface(convFactory, &rv)); if (NS_FAILED(rv)) return rv; for (PRUint32 count = 0; count < converterListSize; ++count) { // register the TestConverter with the component manager. One contractid registration // per conversion pair (from - to pair). nsCString contractID(NS_ISTREAMCONVERTER_KEY); contractID.Append(converterList[count]); rv = registrar->RegisterFactory(kTestConverterCID, "TestConverter", contractID.get(), convFactSup); if (NS_FAILED(rv)) return rv; rv = catman->AddCategoryEntry(NS_ISTREAMCONVERTER_KEY, converterList[count], "x", PR_TRUE, PR_TRUE, getter_Copies(previous)); if (NS_FAILED(rv)) return rv; } nsCOMPtr<nsIStreamConverterService> StreamConvService = do_GetService(kStreamConverterServiceCID, &rv); if (NS_FAILED(rv)) return rv; // Define the *from* content type and *to* content-type for conversion. static const char fromStr[] = "a/foo"; static const char toStr[] = "c/foo"; #ifdef ASYNC_TEST // ASYNCHRONOUS conversion // Build up a channel that represents the content we're // starting the transaction with. // // sample multipart mixed content-type string: // "multipart/x-mixed-replacE;boundary=thisrandomstring" #if 0 nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIURI> dummyURI; rv = NS_NewURI(getter_AddRefs(dummyURI), "http://meaningless"); if (NS_FAILED(rv)) return rv; rv = NS_NewInputStreamChannel(getter_AddRefs(channel), dummyURI, nsnull, // inStr "text/plain", // content-type -1); // XXX fix contentLength if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIRequest> request(do_QueryInterface(channel)); #endif nsCOMPtr<nsIRequest> request; // setup a listener to receive the converted data. This guy is the end // listener in the chain, he wants the fully converted (toType) data. // An example of this listener in mozilla would be the DocLoader. nsIStreamListener *dataReceiver = new EndListener(); NS_ADDREF(dataReceiver); // setup a listener to push the data into. This listener sits inbetween the // unconverted data of fromType, and the final listener in the chain (in this case // the dataReceiver. nsIStreamListener *converterListener = nsnull; rv = StreamConvService->AsyncConvertData(fromStr, toStr, dataReceiver, nsnull, &converterListener); if (NS_FAILED(rv)) return rv; NS_RELEASE(dataReceiver); // at this point we have a stream listener to push data to, and the one // that will receive the converted data. Let's mimic On*() calls and get the conversion // going. Typically these On*() calls would be made inside their respective wrappers On*() // methods. rv = converterListener->OnStartRequest(request, nsnull); if (NS_FAILED(rv)) return rv; rv = SEND_DATA("aaa"); if (NS_FAILED(rv)) return rv; rv = SEND_DATA("aaa"); if (NS_FAILED(rv)) return rv; // Finish the request. rv = converterListener->OnStopRequest(request, nsnull, rv); if (NS_FAILED(rv)) return rv; NS_RELEASE(converterListener); #else // SYNCHRONOUS conversion nsCOMPtr<nsIInputStream> convertedData; rv = StreamConvService->Convert(inputData, fromStr, toStr, nsnull, getter_AddRefs(convertedData)); if (NS_FAILED(rv)) return rv; #endif // Enter the message pump to allow the URL load to proceed. while ( gKeepRunning ) { if (!NS_ProcessNextEvent(thread)) break; } } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM NS_ShutdownXPCOM(nsnull); return rv; }
NS_IMETHODIMP nsSocketTransportService::Run() { SOCKET_LOG(("STS thread init %d sockets\n", gMaxCount)); psm::InitializeSSLServerCertVerificationThreads(); gSocketThread = PR_GetCurrentThread(); { MutexAutoLock lock(mLock); mPollableEvent.reset(new PollableEvent()); // // NOTE: per bug 190000, this failure could be caused by Zone-Alarm // or similar software. // // NOTE: per bug 191739, this failure could also be caused by lack // of a loopback device on Windows and OS/2 platforms (it creates // a loopback socket pair on these platforms to implement a pollable // event object). if we can't create a pollable event, then we'll // have to "busy wait" to implement the socket event queue :-( // if (!mPollableEvent->Valid()) { mPollableEvent = nullptr; NS_WARNING("running socket transport thread without a pollable event"); SOCKET_LOG(("running socket transport thread without a pollable event")); } mPollList[0].fd = mPollableEvent ? mPollableEvent->PollableFD() : nullptr; mPollList[0].in_flags = PR_POLL_READ | PR_POLL_EXCEPT; mPollList[0].out_flags = 0; } mRawThread = NS_GetCurrentThread(); // hook ourselves up to observe event processing for this thread nsCOMPtr<nsIThreadInternal> threadInt = do_QueryInterface(mRawThread); threadInt->SetObserver(this); // make sure the pseudo random number generator is seeded on this thread srand(static_cast<unsigned>(PR_Now())); // For the calculation of the duration of the last cycle (i.e. the last for-loop // iteration before shutdown). TimeStamp startOfCycleForLastCycleCalc; int numberOfPendingEventsLastCycle; // For measuring of the poll iteration duration without time spent blocked // in poll(). TimeStamp pollCycleStart; // Time blocked in poll(). TimeDuration singlePollDuration; // For calculating the time needed for a new element to run. TimeStamp startOfIteration; TimeStamp startOfNextIteration; int numberOfPendingEvents; // If there is too many pending events queued, we will run some poll() // between them and the following variable is cumulative time spent // blocking in poll(). TimeDuration pollDuration; for (;;) { bool pendingEvents = false; numberOfPendingEvents = 0; numberOfPendingEventsLastCycle = 0; if (mTelemetryEnabledPref) { startOfCycleForLastCycleCalc = TimeStamp::NowLoRes(); startOfNextIteration = TimeStamp::NowLoRes(); } pollDuration = 0; do { if (mTelemetryEnabledPref) { pollCycleStart = TimeStamp::NowLoRes(); } DoPollIteration(&singlePollDuration); if (mTelemetryEnabledPref && !pollCycleStart.IsNull()) { Telemetry::Accumulate(Telemetry::STS_POLL_BLOCK_TIME, singlePollDuration.ToMilliseconds()); Telemetry::AccumulateTimeDelta( Telemetry::STS_POLL_CYCLE, pollCycleStart + singlePollDuration, TimeStamp::NowLoRes()); pollDuration += singlePollDuration; } mRawThread->HasPendingEvents(&pendingEvents); if (pendingEvents) { if (!mServingPendingQueue) { nsresult rv = Dispatch(NewRunnableMethod(this, &nsSocketTransportService::MarkTheLastElementOfPendingQueue), nsIEventTarget::DISPATCH_NORMAL); if (NS_FAILED(rv)) { NS_WARNING("Could not dispatch a new event on the " "socket thread."); } else { mServingPendingQueue = true; } if (mTelemetryEnabledPref) { startOfIteration = startOfNextIteration; // Everything that comes after this point will // be served in the next iteration. If no even // arrives, startOfNextIteration will be reset at the // beginning of each for-loop. startOfNextIteration = TimeStamp::NowLoRes(); } } TimeStamp eventQueueStart = TimeStamp::NowLoRes(); do { NS_ProcessNextEvent(mRawThread); numberOfPendingEvents++; pendingEvents = false; mRawThread->HasPendingEvents(&pendingEvents); } while (pendingEvents && mServingPendingQueue && ((TimeStamp::NowLoRes() - eventQueueStart).ToMilliseconds() < mMaxTimePerPollIter)); if (mTelemetryEnabledPref && !mServingPendingQueue && !startOfIteration.IsNull()) { Telemetry::AccumulateTimeDelta( Telemetry::STS_POLL_AND_EVENTS_CYCLE, startOfIteration + pollDuration, TimeStamp::NowLoRes()); Telemetry::Accumulate( Telemetry::STS_NUMBER_OF_PENDING_EVENTS, numberOfPendingEvents); numberOfPendingEventsLastCycle += numberOfPendingEvents; numberOfPendingEvents = 0; pollDuration = 0; } } } while (pendingEvents); bool goingOffline = false; // now that our event queue is empty, check to see if we should exit { MutexAutoLock lock(mLock); if (mShuttingDown) { if (mTelemetryEnabledPref && !startOfCycleForLastCycleCalc.IsNull()) { Telemetry::Accumulate( Telemetry::STS_NUMBER_OF_PENDING_EVENTS_IN_THE_LAST_CYCLE, numberOfPendingEventsLastCycle); Telemetry::AccumulateTimeDelta( Telemetry::STS_POLL_AND_EVENT_THE_LAST_CYCLE, startOfCycleForLastCycleCalc, TimeStamp::NowLoRes()); } break; } if (mGoingOffline) { mGoingOffline = false; goingOffline = true; } } // Avoid potential deadlock if (goingOffline) Reset(true); } SOCKET_LOG(("STS shutting down thread\n")); // detach all sockets, including locals Reset(false); // Final pass over the event queue. This makes sure that events posted by // socket detach handlers get processed. NS_ProcessPendingEvents(mRawThread); gSocketThread = nullptr; psm::StopSSLServerCertVerificationThreads(); SOCKET_LOG(("STS thread exit\n")); return NS_OK; }
nsresult nsAutoConfig::downloadAutoConfig() { nsresult rv; nsCAutoString emailAddr; nsXPIDLCString urlName; static bool firstTime = true; if (mConfigURL.IsEmpty()) { PR_LOG(MCD, PR_LOG_DEBUG, ("global config url is empty - did you set autoadmin.global_config_url?\n")); NS_WARNING("AutoConfig called without global_config_url"); return NS_OK; } // If there is an email address appended as an argument to the ConfigURL // in the previous read, we need to remove it when timer kicks in and // downloads the autoconfig file again. // If necessary, the email address will be added again as an argument. PRInt32 index = mConfigURL.RFindChar((PRUnichar)'?'); if (index != -1) mConfigURL.Truncate(index); // Clean up the previous read, the new read is going to use the same buffer if (!mBuf.IsEmpty()) mBuf.Truncate(0); // Get the preferences branch and save it to the member variable if (!mPrefBranch) { nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; rv = prefs->GetBranch(nsnull,getter_AddRefs(mPrefBranch)); if (NS_FAILED(rv)) return rv; } // Check to see if the network is online/offline nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; bool offline; rv = ios->GetOffline(&offline); if (NS_FAILED(rv)) return rv; if (offline) { bool offlineFailover; rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover", &offlineFailover); // Read the failover.jsc if the network is offline and the pref says so if (NS_SUCCEEDED(rv) && offlineFailover) return readOfflineFile(); } /* Append user's identity at the end of the URL if the pref says so. First we are checking for the user's email address but if it is not available in the case where the client is used without messenger, user's profile name will be used as an unique identifier */ bool appendMail; rv = mPrefBranch->GetBoolPref("autoadmin.append_emailaddr", &appendMail); if (NS_SUCCEEDED(rv) && appendMail) { rv = getEmailAddr(emailAddr); if (NS_SUCCEEDED(rv) && emailAddr.get()) { /* Adding the unique identifier at the end of autoconfig URL. In this case the autoconfig URL is a script and emailAddr as passed as an argument */ mConfigURL.Append("?"); mConfigURL.Append(emailAddr); } } // create a new url nsCOMPtr<nsIURI> url; nsCOMPtr<nsIChannel> channel; rv = NS_NewURI(getter_AddRefs(url), mConfigURL.get(), nsnull, nsnull); if (NS_FAILED(rv)) { PR_LOG(MCD, PR_LOG_DEBUG, ("failed to create URL - is autoadmin.global_config_url valid? - %s\n", mConfigURL.get())); return rv; } PR_LOG(MCD, PR_LOG_DEBUG, ("running MCD url %s\n", mConfigURL.get())); // open a channel for the url rv = NS_NewChannel(getter_AddRefs(channel),url, nsnull, nsnull, nsnull, nsIRequest::INHIBIT_PERSISTENT_CACHING | nsIRequest::LOAD_BYPASS_CACHE); if (NS_FAILED(rv)) return rv; rv = channel->AsyncOpen(this, nsnull); if (NS_FAILED(rv)) { readOfflineFile(); return rv; } // Set a repeating timer if the pref is set. // This is to be done only once. // Also We are having the event queue processing only for the startup // It is not needed with the repeating timer. if (firstTime) { firstTime = PR_FALSE; // Getting the current thread. If we start an AsyncOpen, the thread // needs to wait before the reading of autoconfig is done nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); NS_ENSURE_STATE(thread); /* process events until we're finished. AutoConfig.jsc reading needs to be finished before the browser starts loading up We are waiting for the mLoaded which will be set through onStopRequest or readOfflineFile methods There is a possibility of deadlock so we need to make sure that mLoaded will be set to true in any case (success/failure) */ while (!mLoaded) NS_ENSURE_STATE(NS_ProcessNextEvent(thread)); PRInt32 minutes; rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval", &minutes); if (NS_SUCCEEDED(rv) && minutes > 0) { // Create a new timer and pass this nsAutoConfig // object as a timer callback. mTimer = do_CreateInstance("@mozilla.org/timer;1",&rv); if (NS_FAILED(rv)) return rv; rv = mTimer->InitWithCallback(this, minutes * 60 * 1000, nsITimer::TYPE_REPEATING_SLACK); if (NS_FAILED(rv)) return rv; } } //first_time return NS_OK; } // nsPref::downloadAutoConfig()
NS_IMETHODIMP nsXMLDocument::Load(const nsAString& aUrl, bool *aReturn) { bool hasHadScriptObject = true; nsIScriptGlobalObject* scriptObject = GetScriptHandlingObject(hasHadScriptObject); NS_ENSURE_STATE(scriptObject || !hasHadScriptObject); ReportUseOfDeprecatedMethod(this, "UseOfDOM3LoadMethodWarning"); NS_ENSURE_ARG_POINTER(aReturn); *aReturn = false; nsCOMPtr<nsIDocument> callingDoc = do_QueryInterface(nsContentUtils::GetDocumentFromContext()); nsIURI *baseURI = mDocumentURI; nsAutoCString charset; if (callingDoc) { baseURI = callingDoc->GetDocBaseURI(); charset = callingDoc->GetDocumentCharacterSet(); } // Create a new URI nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI); if (NS_FAILED(rv)) { return rv; } // Check to see whether the current document is allowed to load this URI. // It's important to use the current document's principal for this check so // that we don't end up in a case where code with elevated privileges is // calling us and changing the principal of this document. // Enforce same-origin even for chrome loaders to avoid someone accidentally // using a document that content has a reference to and turn that into a // chrome document. nsCOMPtr<nsIPrincipal> principal = NodePrincipal(); if (!nsContentUtils::IsSystemPrincipal(principal)) { rv = principal->CheckMayLoad(uri, false, false); NS_ENSURE_SUCCESS(rv, rv); int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST, uri, principal, callingDoc ? callingDoc.get() : static_cast<nsIDocument*>(this), NS_LITERAL_CSTRING("application/xml"), nullptr, &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); NS_ENSURE_SUCCESS(rv, rv); if (NS_CP_REJECTED(shouldLoad)) { return NS_ERROR_CONTENT_BLOCKED; } } else { // We're called from chrome, check to make sure the URI we're // about to load is also chrome. bool isChrome = false; if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) { nsAutoCString spec; if (mDocumentURI) mDocumentURI->GetSpec(spec); nsAutoString error; error.AssignLiteral("Cross site loading using document.load is no " "longer supported. Use XMLHttpRequest instead."); nsCOMPtr<nsIScriptError> errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = errorObject->InitWithWindowID(error, NS_ConvertUTF8toUTF16(spec), EmptyString(), 0, 0, nsIScriptError::warningFlag, "DOM", callingDoc ? callingDoc->InnerWindowID() : this->InnerWindowID()); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); if (consoleService) { consoleService->LogMessage(errorObject); } return NS_ERROR_DOM_SECURITY_ERR; } } // Partial Reset, need to restore principal for security reasons and // event listener manager so that load listeners etc. will // remain. This should be done before the security check is done to // ensure that the document is reset even if the new document can't // be loaded. Note that we need to hold a strong ref to |principal| // here, because ResetToURI will null out our node principal before // setting the new one. nsRefPtr<nsEventListenerManager> elm(mListenerManager); mListenerManager = nullptr; // When we are called from JS we can find the load group for the page, // and add ourselves to it. This way any pending requests // will be automatically aborted if the user leaves the page. nsCOMPtr<nsILoadGroup> loadGroup; if (callingDoc) { loadGroup = callingDoc->GetDocumentLoadGroup(); } ResetToURI(uri, loadGroup, principal); mListenerManager = elm; // Create a channel nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::GetSameOriginChecker(); NS_ENSURE_TRUE(req, NS_ERROR_OUT_OF_MEMORY); nsCOMPtr<nsIChannel> channel; // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active, // which in turn keeps STOP button from becoming active rv = NS_NewChannel(getter_AddRefs(channel), uri, nullptr, loadGroup, req, nsIRequest::LOAD_BACKGROUND); if (NS_FAILED(rv)) { return rv; } // StartDocumentLoad asserts that readyState is uninitialized, so // uninitialize it. SetReadyStateInternal make this transition invisible to // Web content. But before doing that, assert that the current readyState // is complete as it should be after the call to ResetToURI() above. MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE, "Bad readyState"); SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED); // Prepare for loading the XML document "into oneself" nsCOMPtr<nsIStreamListener> listener; if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel, loadGroup, nullptr, getter_AddRefs(listener), false))) { NS_ERROR("nsXMLDocument::Load: Failed to start the document load."); return rv; } // After this point, if we error out of this method we should clear // mChannelIsPending. // Start an asynchronous read of the XML document rv = channel->AsyncOpen(listener, nullptr); if (NS_FAILED(rv)) { mChannelIsPending = false; return rv; } if (!mAsync) { nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); nsAutoSyncOperation sync(this); mLoopingForSyncLoad = true; while (mLoopingForSyncLoad) { if (!NS_ProcessNextEvent(thread)) break; } // We set return to true unless there was a parsing error nsCOMPtr<nsIDOMNode> node = do_QueryInterface(GetRootElement()); if (node) { nsAutoString name, ns; if (NS_SUCCEEDED(node->GetLocalName(name)) && name.EqualsLiteral("parsererror") && NS_SUCCEEDED(node->GetNamespaceURI(ns)) && ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) { //return is already false } else { *aReturn = true; } } } else { *aReturn = true; } return NS_OK; }
SECStatus nsNSSHttpRequestSession::internal_send_receive_attempt(PRBool &retryable_error, PRPollDesc **pPollDesc, PRUint16 *http_response_code, const char **http_response_content_type, const char **http_response_headers, const char **http_response_data, PRUint32 *http_response_data_len) { if (pPollDesc) *pPollDesc = nsnull; if (http_response_code) *http_response_code = 0; if (http_response_content_type) *http_response_content_type = 0; if (http_response_headers) *http_response_headers = 0; if (http_response_data) *http_response_data = 0; PRUint32 acceptableResultSize = 0; if (http_response_data_len) { acceptableResultSize = *http_response_data_len; *http_response_data_len = 0; } if (!mListener) return SECFailure; if (NS_FAILED(mListener->InitLocks())) return SECFailure; PRLock *waitLock = mListener->mLock; PRCondVar *waitCondition = mListener->mCondition; volatile PRBool &waitFlag = mListener->mWaitFlag; waitFlag = PR_TRUE; nsRefPtr<nsHTTPDownloadEvent> event = new nsHTTPDownloadEvent; if (!event) return SECFailure; event->mListener = mListener; this->AddRef(); event->mRequestSession = this; nsresult rv = NS_DispatchToMainThread(event); if (NS_FAILED(rv)) { event->mResponsibleForDoneSignal = PR_FALSE; return SECFailure; } PRBool request_canceled = PR_FALSE; { nsAutoLock locker(waitLock); const PRIntervalTime start_time = PR_IntervalNow(); PRIntervalTime wait_interval; PRBool running_on_main_thread = NS_IsMainThread(); if (running_on_main_thread) { // let's process events quickly wait_interval = PR_MicrosecondsToInterval(50); } else { // On a secondary thread, it's fine to wait some more for // for the condition variable. wait_interval = PR_MillisecondsToInterval(250); } while (waitFlag) { if (running_on_main_thread) { // Networking runs on the main thread, which we happen to block here. // Processing events will allow the OCSP networking to run while we // are waiting. Thanks a lot to Darin Fisher for rewriting the // thread manager. Thanks a lot to Christian Biesinger who // made me aware of this possibility. (kaie) locker.unlock(); NS_ProcessNextEvent(nsnull); locker.lock(); } PR_WaitCondVar(waitCondition, wait_interval); if (!waitFlag) break; if (!request_canceled) { PRBool wantExit = nsSSLThread::exitRequested(); PRBool timeout = (PRIntervalTime)(PR_IntervalNow() - start_time) > mTimeoutInterval; if (wantExit || timeout) { request_canceled = PR_TRUE; nsRefPtr<nsCancelHTTPDownloadEvent> cancelevent = new nsCancelHTTPDownloadEvent; cancelevent->mListener = mListener; rv = NS_DispatchToMainThread(cancelevent); if (NS_FAILED(rv)) { NS_WARNING("cannot post cancel event"); } break; } } } } if (request_canceled) return SECFailure; if (NS_FAILED(mListener->mResultCode)) { if (mListener->mResultCode == NS_ERROR_CONNECTION_REFUSED || mListener->mResultCode == NS_ERROR_NET_RESET) { retryable_error = PR_TRUE; } return SECFailure; } if (http_response_code) *http_response_code = mListener->mHttpResponseCode; if (mListener->mHttpRequestSucceeded && http_response_data && http_response_data_len) { *http_response_data_len = mListener->mResultLen; // acceptableResultSize == 0 means: any size is acceptable if (acceptableResultSize != 0 && acceptableResultSize < mListener->mResultLen) { return SECFailure; } // return data by reference, result data will be valid // until "this" gets destroyed by NSS *http_response_data = (const char*)mListener->mResultData; } if (mListener->mHttpRequestSucceeded && http_response_content_type) { if (mListener->mHttpResponseContentType.Length()) { *http_response_content_type = mListener->mHttpResponseContentType.get(); } } return SECSuccess; }