nsresult
nsAsyncRedirectVerifyHelper::Init(nsIChannel* oldChan, nsIChannel* newChan,
                                  PRUint32 flags, PRBool synchronize)
{
    LOG(("nsAsyncRedirectVerifyHelper::Init() "
         "oldChan=%p newChan=%p", oldChan, newChan));
    mOldChan           = oldChan;
    mNewChan           = newChan;
    mFlags             = flags;
    mCallbackThread    = do_GetCurrentThread();

    if (synchronize)
      mWaitingForRedirectCallback = PR_TRUE;

    nsresult rv;
    rv = NS_DispatchToMainThread(this);
    NS_ENSURE_SUCCESS(rv, rv);

    if (synchronize) {
      nsIThread *thread = NS_GetCurrentThread();
      while (mWaitingForRedirectCallback) {
        if (!NS_ProcessNextEvent(thread)) {
          return NS_ERROR_UNEXPECTED;
        }
      }
    }

    return NS_OK;
}
    NS_DECL_ISUPPORTS

    NS_IMETHOD Run()
    {
        LOG(("TEST: Verifing calling Proxy on eventQ thread.\n"));

        nsCOMPtr<nsIThread> thread = do_GetCurrentThread();

        nsITestProxy *proxyObject;
        nsTestXPCFoo *foo = new nsTestXPCFoo();
        NS_ENSURE_STATE(foo);

        nsCOMPtr<nsIProxyObjectManager> manager =
                do_GetService(NS_XPCOMPROXY_CONTRACTID);

        manager->GetProxyForObject(thread,
                                   NS_GET_IID(nsITestProxy), foo,
                                   NS_PROXY_SYNC, (void**)&proxyObject);

        PRInt32 a;
        proxyObject->Test(1, 2, &a);
        proxyObject->Test2();
        
        NS_RELEASE(proxyObject);
        delete foo;

        LOG(("TEST: End of Verification calling Proxy on eventQ thread.\n"));

        return NS_OK;
    }
NS_IMETHODIMP
Service::Observe(nsISupports *, const char *aTopic, const PRUnichar *)
{
  if (strcmp(aTopic, "xpcom-shutdown") == 0)
    shutdown();
  if (strcmp(aTopic, "xpcom-shutdown-threads") == 0) {
    nsCOMPtr<nsIObserverService> os =
      mozilla::services::GetObserverService();
    os->RemoveObserver(this, "xpcom-shutdown-threads");
    bool anyOpen = false;
    do {
      nsTArray<nsRefPtr<Connection> > connections;
      getConnections(connections);
      anyOpen = false;
      for (PRUint32 i = 0; i < connections.Length(); i++) {
        nsRefPtr<Connection> &conn = connections[i];

        // While it would be nice to close all connections, we only
        // check async ones for now.
        if (conn->isAsyncClosing()) {
          anyOpen = true;
          break;
        }
      }
      if (anyOpen) {
        nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
        NS_ProcessNextEvent(thread);
      }
    } while (anyOpen);
  }

  return NS_OK;
}
Beispiel #4
0
NuwaParent::NuwaParent()
  : mBlocked(false)
  , mMonitor("NuwaParent")
  , mClonedActor(nullptr)
  , mWorkerThread(do_GetCurrentThread())
  , mNewProcessPid(0)
{
  AssertIsOnBackgroundThread();
}
 nsAsyncDoomEvent(nsCacheEntryDescriptor *descriptor,
                  nsICacheListener *listener)
 {
     mDescriptor = descriptor;
     mListener = listener;
     mThread = do_GetCurrentThread();
     // We addref the listener here and release it in nsNotifyDoomListener
     // on the callers thread. If posting of nsNotifyDoomListener event fails
     // we leak the listener which is better than releasing it on a wrong
     // thread.
     NS_IF_ADDREF(mListener);
 }
CycleCollectedJSContext::CycleCollectedJSContext()
  : mIsPrimaryContext(true)
  , mRuntime(nullptr)
  , mJSContext(nullptr)
  , mDoingStableStates(false)
  , mDisableMicroTaskCheckpoint(false)
{
  MOZ_COUNT_CTOR(CycleCollectedJSContext);
  nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
  mOwningThread = thread.forget().downcast<nsThread>().take();
  MOZ_RELEASE_ASSERT(mOwningThread);
}
void
nsCacheEntry::SetData(nsISupports * data)
{
    if (mData) {
        nsCacheService::ReleaseObject_Locked(mData, mThread);
        mData = nsnull;
    }

    if (data) {
        NS_ADDREF(mData = data);
        mThread = do_GetCurrentThread();
    }
}
Beispiel #8
0
int
main(int argc, char** argv)
{
    nsresult rv;

    if (argc < 2) {
        fprintf(stderr, "usage: %s <url>\n", argv[0]);
        return 1;
    }

    NS_InitXPCOM2(nullptr, nullptr, nullptr);

    // Create a stream data source and initialize it on argv[1], which
    // is hopefully a "file:" URL.
    nsCOMPtr<nsIRDFDataSource> ds =
        do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource",
                          &rv);
    RETURN_IF_FAILED(rv, "RDF/XML datasource creation");

    nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds, &rv);
    RETURN_IF_FAILED(rv, "QI to nsIRDFRemoteDataSource");

    rv = remote->Init(argv[1]);
    RETURN_IF_FAILED(rv, "datasource initialization");

    // Okay, this should load the XML file...
    rv = remote->Refresh(false);
    RETURN_IF_FAILED(rv, "datasource refresh");

    // Pump events until the load is finished
    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
    bool done = false;
    while (!done) {
        NS_ENSURE_TRUE(NS_ProcessNextEvent(thread), 1);
        remote->GetLoaded(&done);
    }

    nsCOMPtr<rdfIDataSource> rdfds = do_QueryInterface(ds, &rv);
    RETURN_IF_FAILED(rv, "QI to rdIDataSource");
    {
        nsCOMPtr<nsIOutputStream> out = new ConsoleOutputStreamImpl();
        nsCOMPtr<rdfISerializer> ser =
            do_CreateInstance(NS_RDF_SERIALIZER "ntriples", &rv);
        RETURN_IF_FAILED(rv, "Creation of NTriples Serializer");
        rv = ser->Serialize(rdfds, out);
        RETURN_IF_FAILED(rv, "Serialization to NTriples");
        out->Close();
    }

    return 0;
}
Beispiel #9
0
int
main(int argc, char** argv)
{
    nsresult rv;

    if (argc < 2) {
        fprintf(stderr, "usage: %s <url>\n", argv[0]);
        return 1;
    }

    NS_InitXPCOM2(nsnull, nsnull, nsnull);

    // Create a stream data source and initialize it on argv[1], which
    // is hopefully a "file:" URL.
    nsCOMPtr<nsIRDFDataSource> ds = do_CreateInstance(kRDFXMLDataSourceCID,
                                                      &rv);
    RETURN_IF_FAILED(rv, "RDF/XML datasource creation");

    nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds, &rv);
    RETURN_IF_FAILED(rv, "QI to nsIRDFRemoteDataSource");

    rv = remote->Init(argv[1]);
    RETURN_IF_FAILED(rv, "datasource initialization");

    // Okay, this should load the XML file...
    rv = remote->Refresh(false);
    RETURN_IF_FAILED(rv, "datasource refresh");

    // Pump events until the load is finished
    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
    bool done = false;
    while (!done) {
        NS_ENSURE_STATE(NS_ProcessNextEvent(thread));
        remote->GetLoaded(&done);
    }

    // And this should write it back out. The do_QI() on the pointer
    // is a hack to make sure that the new object gets AddRef()-ed.
    nsCOMPtr<nsIOutputStream> out =
        do_QueryInterface(new ConsoleOutputStreamImpl, &rv);
    RETURN_IF_FAILED(rv, "creation of console output stream");

    nsCOMPtr<nsIRDFXMLSource> source = do_QueryInterface(ds);
    RETURN_IF_FAILED(rv, "QI to nsIRDFXMLSource");

    rv = source->Serialize(out);
    RETURN_IF_FAILED(rv, "datasoure serialization");

    return NS_OK;
}
Connection::Connection(Service *aService,
                       int aFlags)
: sharedAsyncExecutionMutex("Connection::sharedAsyncExecutionMutex")
, sharedDBMutex("Connection::sharedDBMutex")
, threadOpenedOn(do_GetCurrentThread())
, mDBConn(nsnull)
, mAsyncExecutionThreadShuttingDown(false)
, mTransactionInProgress(PR_FALSE)
, mProgressHandler(nsnull)
, mFlags(aFlags)
, mStorageService(aService)
{
  mFunctions.Init();
}
/* wstring getQueryResults (in nsILDAPURL aServerURL, in unsigned long aVersion); */
NS_IMETHODIMP nsLDAPSyncQuery::GetQueryResults(nsILDAPURL *aServerURL,
                                               PRUint32 aProtocolVersion,
                                               PRUnichar **_retval)
{
    nsresult rv;
    
    if (!aServerURL) {
        NS_ERROR("nsLDAPSyncQuery::GetQueryResults() called without LDAP URL");
        return NS_ERROR_FAILURE;
    }
    mServerURL = aServerURL;
    mProtocolVersion = aProtocolVersion;

    nsCOMPtr<nsIThread> currentThread = do_GetCurrentThread();

    // Start an LDAP query. 
    // InitConnection will bind to the ldap server and post a OnLDAPMessage 
    // event. This event will trigger a search and the whole operation will 
    // be carried out by chain of events
    //
    rv = InitConnection();
    if (NS_FAILED(rv))
        return rv;
    
    // We want this LDAP query to be synchronous while the XPCOM LDAP is 
    // async in nature. So this eventQueue handling will wait for the 
    // LDAP operation to be finished. 
    // mFinished controls the state of the LDAP opertion. 
    // It will be released in any case (success/failure)
    
    
    // Run the event loop, 
    // mFinished is a control variable
    //
    while (!mFinished)
        NS_ENSURE_STATE(NS_ProcessNextEvent(currentThread));

    // Return results
    //
    if (!mResults.IsEmpty()) {
        *_retval = ToNewUnicode(mResults);
        if (!_retval)
          rv = NS_ERROR_OUT_OF_MEMORY;
    }
    return rv;

}
Beispiel #12
0
static JSBool
Suspend(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsJSSh* shell;
  if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;

  nsCOMPtr<nsIThread> thread = do_GetCurrentThread();

  PR_AtomicIncrement(&shell->mSuspendCount);
  
  while (shell->mSuspendCount) {
    LOG(("|"));
    NS_ProcessNextEvent(thread);
  }
           
  return JS_TRUE;
}
// AsyncWait - async
TEST(TestBufferedInputStream, AsyncWait_async) {
  const size_t kBufSize = 10;

  nsCString buf;
  RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);

  RefPtr<testing::InputStreamCallback> cb =
    new testing::InputStreamCallback();
  nsCOMPtr<nsIThread> thread = do_GetCurrentThread();

  ASSERT_EQ(NS_OK, bis->AsyncWait(cb, 0, 0, thread));

  ASSERT_FALSE(cb->Called());

  // Eventually it is called.
  MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil([&]() { return cb->Called(); }));
  ASSERT_TRUE(cb->Called());
}
Beispiel #14
0
static nsresult
RunApartmentTest()
{
    LOG(("RunApartmentTest: start\n"));

    const PRUint32 numDispatched = 160;

    PRUint32 numCompleted = 0;
    nsCOMPtr<nsIRunnable> obj = new MainThreadOnly(&numCompleted);

    nsCOMPtr<nsIProxyObjectManager> manager =
            do_GetService(NS_XPCOMPROXY_CONTRACTID);

    nsCOMPtr<nsIRunnable> objProxy;
    manager->GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD,
                               NS_GET_IID(nsIRunnable),
                               obj,
                               NS_PROXY_ASYNC,
                               getter_AddRefs(objProxy));
    nsCOMPtr<nsIThread> thread;
    NS_NewThread(getter_AddRefs(thread));

    obj = nsnull;

    nsCOMPtr<nsIThreadPool> pool = do_CreateInstance(NS_THREADPOOL_CONTRACTID);

    pool->SetThreadLimit(8);
    for (PRUint32 i = 0; i < numDispatched; ++i)
        pool->Dispatch(objProxy, NS_DISPATCH_NORMAL);

    objProxy = nsnull;

    nsCOMPtr<nsIThread> curThread = do_GetCurrentThread();
    while (numCompleted < numDispatched) {
        NS_ProcessNextEvent(curThread);
    }

    pool->Shutdown();

    LOG(("RunApartmentTest: end\n"));
    return NS_OK;
}
Beispiel #15
0
FileReader::FileReader(nsPIDOMWindow* aWindow,
                       WorkerPrivate* aWorkerPrivate)
  : DOMEventTargetHelper(aWindow)
  , mFileData(nullptr)
  , mDataLen(0)
  , mDataFormat(FILE_AS_BINARY)
  , mResultArrayBuffer(nullptr)
  , mProgressEventWasDelayed(false)
  , mTimerIsActive(false)
  , mReadyState(EMPTY)
  , mTotal(0)
  , mTransferred(0)
  , mTarget(do_GetCurrentThread())
  , mBusyCount(0)
  , mWorkerPrivate(aWorkerPrivate)
{
  MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerPrivate && !aWindow);
  MOZ_ASSERT_IF(NS_IsMainThread(), !mWorkerPrivate);
  SetDOMStringToNull(mResult);
}
Beispiel #16
0
nsTimerImpl::nsTimerImpl() :
  mClosure(nsnull),
  mCallbackType(CALLBACK_TYPE_UNKNOWN),
  mFiring(PR_FALSE),
  mArmed(PR_FALSE),
  mCanceled(PR_FALSE),
  mGeneration(0),
  mDelay(0),
  mTimeout(0)
{
  // XXXbsmedberg: shouldn't this be in Init()?
  mCallingThread = do_GetCurrentThread();

  mCallback.c = nsnull;

#ifdef DEBUG_TIMERS
  mStart = 0;
  mStart2 = 0;
#endif
}
// AsyncWait - async
TEST(TestBufferedInputStream, AsyncWait_async_closureOnly) {
  const size_t kBufSize = 10;

  nsCString buf;
  RefPtr<nsBufferedInputStream> bis = CreateStream(kBufSize, buf);

  RefPtr<testing::InputStreamCallback> cb =
    new testing::InputStreamCallback();
  nsCOMPtr<nsIThread> thread = do_GetCurrentThread();

  ASSERT_EQ(NS_OK, bis->AsyncWait(cb, nsIAsyncInputStream::WAIT_CLOSURE_ONLY,
                                  0, thread));

  ASSERT_FALSE(cb->Called());
  bis->CloseWithStatus(NS_ERROR_FAILURE);
  ASSERT_FALSE(cb->Called());

  // Eventually it is called.
  MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil([&]() { return cb->Called(); }));
  ASSERT_TRUE(cb->Called());
}
Beispiel #18
0
// this is used for Send without UI
nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields)
{
  nsresult rv = NS_OK ;

  if (!IsBlindSendAllowed())
    return NS_ERROR_FAILURE;

  /** create nsIMsgComposeParams obj and other fields to populate it **/

  nsCOMPtr<nsIDOMWindow>  hiddenWindow;
  // get parent window
  nsCOMPtr<nsIAppShellService> appService = do_GetService( "@mozilla.org/appshell/appShellService;1", &rv);
  if (NS_FAILED(rv)|| (!appService) ) return rv ;

  rv = appService->GetHiddenDOMWindow(getter_AddRefs(hiddenWindow));
  if ( NS_FAILED(rv) ) return rv ;
  // smtp password and Logged in used IdKey from MapiConfig (session obj)
  nsMAPIConfiguration * pMapiConfig = nsMAPIConfiguration::GetMAPIConfiguration() ;
  if (!pMapiConfig) return NS_ERROR_FAILURE ;  // get the singelton obj
  PRUnichar * password = pMapiConfig->GetPassword(aSession) ;
  // password
  nsCAutoString smtpPassword;
  LossyCopyUTF16toASCII(password, smtpPassword);

  // Id key
  nsCString MsgIdKey;
  pMapiConfig->GetIdKey(aSession, MsgIdKey);

  // get the MsgIdentity for the above key using AccountManager
  nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService (NS_MSGACCOUNTMANAGER_CONTRACTID) ;
  if (NS_FAILED(rv) || (!accountManager) ) return rv ;

  nsCOMPtr <nsIMsgIdentity> pMsgId ;
  rv = accountManager->GetIdentity (MsgIdKey, getter_AddRefs(pMsgId)) ;
  if (NS_FAILED(rv) ) return rv ;

  // create a send listener to get back the send status
  nsCOMPtr <nsIMsgSendListener> sendListener ;
  rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ;
  if (NS_FAILED(rv) || (!sendListener) ) return rv;

  // create the compose params object
  nsCOMPtr<nsIMsgComposeParams> pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv));
  if (NS_FAILED(rv) || (!pMsgComposeParams) ) return rv ;

  // populate the compose params
  bool forcePlainText;
  aCompFields->GetForcePlainText(&forcePlainText);
  pMsgComposeParams->SetType(nsIMsgCompType::New);
  pMsgComposeParams->SetFormat(forcePlainText ? nsIMsgCompFormat::PlainText : nsIMsgCompFormat::HTML);
  pMsgComposeParams->SetIdentity(pMsgId);
  pMsgComposeParams->SetComposeFields(aCompFields);
  pMsgComposeParams->SetSendListener(sendListener) ;
  pMsgComposeParams->SetSmtpPassword(smtpPassword.get());

  // create the nsIMsgCompose object to send the object
  nsCOMPtr<nsIMsgCompose> pMsgCompose (do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv));
  if (NS_FAILED(rv) || (!pMsgCompose) ) return rv ;

  /** initialize nsIMsgCompose, Send the message, wait for send completion response **/

  rv = pMsgCompose->Initialize(pMsgComposeParams, hiddenWindow, nsnull);
  if (NS_FAILED(rv)) return rv ;

  // If we're in offline mode, we'll need to queue it for later. No point in trying to send it.
  return pMsgCompose->SendMsg(WeAreOffline() ? nsIMsgSend::nsMsgQueueForLater : nsIMsgSend::nsMsgDeliverNow,
			      pMsgId, nsnull, nsnull, nsnull);
  if (NS_FAILED(rv)) return rv ;

  // assign to interface pointer from nsCOMPtr to facilitate typecast below
  nsIMsgSendListener * pSendListener = sendListener ;

  // we need to wait here to make sure that we return only after send is completed
  // so we will have a event loop here which will process the events till the Send IsDone.
  nsCOMPtr<nsIThread> thread(do_GetCurrentThread());
  while ( !((nsMAPISendListener *) pSendListener)->IsDone() )
  {
    PR_CEnterMonitor(pSendListener);
    PR_CWait(pSendListener, PR_MicrosecondsToInterval(1000UL));
    PR_CExitMonitor(pSendListener);
    NS_ProcessPendingEvents(thread);
  }

  return rv ;
}
Beispiel #19
0
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;
}
Beispiel #20
0
nsresult
ShutdownXPCOM(nsIServiceManager* aServMgr)
{
  // Make sure the hang monitor is enabled for shutdown.
  HangMonitor::NotifyActivity();

  if (!NS_IsMainThread()) {
    NS_RUNTIMEABORT("Shutdown on wrong thread");
  }

  nsresult rv;
  nsCOMPtr<nsISimpleEnumerator> moduleLoaders;

  // Notify observers of xpcom shutting down
  {
    // Block it so that the COMPtr will get deleted before we hit
    // servicemanager shutdown

    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
    if (NS_WARN_IF(!thread)) {
      return NS_ERROR_UNEXPECTED;
    }

    RefPtr<nsObserverService> observerService;
    CallGetService("@mozilla.org/observer-service;1",
                   (nsObserverService**)getter_AddRefs(observerService));

    if (observerService) {
      observerService->NotifyObservers(nullptr,
                                       NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
                                       nullptr);

      nsCOMPtr<nsIServiceManager> mgr;
      rv = NS_GetServiceManager(getter_AddRefs(mgr));
      if (NS_SUCCEEDED(rv)) {
        observerService->NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                         nullptr);
      }
    }

    // This must happen after the shutdown of media and widgets, which
    // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
    NS_ProcessPendingEvents(thread);
    gfxPlatform::ShutdownLayersIPC();

    mozilla::scache::StartupCache::DeleteSingleton();
    if (observerService)
      observerService->NotifyObservers(nullptr,
                                       NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
                                       nullptr);

    gXPCOMThreadsShutDown = true;
    NS_ProcessPendingEvents(thread);

    // Shutdown the timer thread and all timers that might still be alive before
    // shutting down the component manager
    nsTimerImpl::Shutdown();

    NS_ProcessPendingEvents(thread);

    // Shutdown all remaining threads.  This method does not return until
    // all threads created using the thread manager (with the exception of
    // the main thread) have exited.
    nsThreadManager::get()->Shutdown();

    NS_ProcessPendingEvents(thread);

    HangMonitor::NotifyActivity();

    // Late-write checks needs to find the profile directory, so it has to
    // be initialized before mozilla::services::Shutdown or (because of
    // xpcshell tests replacing the service) modules being unloaded.
    mozilla::InitLateWriteChecks();

    // We save the "xpcom-shutdown-loaders" observers to notify after
    // the observerservice is gone.
    if (observerService) {
      observerService->EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
                                          getter_AddRefs(moduleLoaders));

      observerService->Shutdown();
    }
  }

  // Free ClearOnShutdown()'ed smart pointers.  This needs to happen *after*
  // we've finished notifying observers of XPCOM shutdown, because shutdown
  // observers themselves might call ClearOnShutdown().
  mozilla::KillClearOnShutdown();

  // XPCOM is officially in shutdown mode NOW
  // Set this only after the observers have been notified as this
  // will cause servicemanager to become inaccessible.
  mozilla::services::Shutdown();

#ifdef DEBUG_dougt
  fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
#endif
  // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
  // here again:
  NS_IF_RELEASE(aServMgr);

  // Shutdown global servicemanager
  if (nsComponentManagerImpl::gComponentManager) {
    nsComponentManagerImpl::gComponentManager->FreeServices();
  }

  // Release the directory service
  NS_IF_RELEASE(nsDirectoryService::gService);

  free(gGREBinPath);
  gGREBinPath = nullptr;

  if (moduleLoaders) {
    bool more;
    nsCOMPtr<nsISupports> el;
    while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) && more) {
      moduleLoaders->GetNext(getter_AddRefs(el));

      // Don't worry about weak-reference observers here: there is
      // no reason for weak-ref observers to register for
      // xpcom-shutdown-loaders

      // FIXME: This can cause harmless writes from sqlite committing
      // log files. We have to ignore them before we can move
      // the mozilla::PoisonWrite call before this point. See bug
      // 834945 for the details.
      nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
      if (obs) {
        obs->Observe(nullptr, NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID, nullptr);
      }
    }

    moduleLoaders = nullptr;
  }

  nsCycleCollector_shutdown();

  layers::AsyncTransactionTrackersHolder::Finalize();

  PROFILER_MARKER("Shutdown xpcom");
  // If we are doing any shutdown checks, poison writes.
  if (gShutdownChecks != SCM_NOTHING) {
#ifdef XP_MACOSX
    mozilla::OnlyReportDirtyWrites();
#endif /* XP_MACOSX */
    mozilla::BeginLateWriteChecks();
  }

  // Shutdown nsLocalFile string conversion
  NS_ShutdownLocalFile();
#ifdef XP_UNIX
  NS_ShutdownNativeCharsetUtils();
#endif

#if defined(XP_WIN)
  // This exit(0) call is intended to be temporary, to get shutdown leak
  // checking working on Linux.
  // On Windows XP debug, there are intermittent failures in
  // dom/media/tests/mochitest/test_peerConnection_basicH264Video.html
  // if we don't exit early in a child process. See bug 1073310.
  if (XRE_IsContentProcess() && !IsVistaOrLater()) {
      NS_WARNING("Exiting child process early!");
      exit(0);
  }
#endif

  // Shutdown xpcom. This will release all loaders and cause others holding
  // a refcount to the component manager to release it.
  if (nsComponentManagerImpl::gComponentManager) {
    rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
    NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
  } else {
    NS_WARNING("Component Manager was never created ...");
  }

#ifdef MOZ_ENABLE_PROFILER_SPS
  // In optimized builds we don't do shutdown collections by default, so
  // uncollected (garbage) objects may keep the nsXPConnect singleton alive,
  // and its XPCJSRuntime along with it. However, we still destroy various
  // bits of state in JS_ShutDown(), so we need to make sure the profiler
  // can't access them when it shuts down. This call nulls out the
  // JS pseudo-stack's internal reference to the main thread JSRuntime,
  // duplicating the call in XPCJSRuntime::~XPCJSRuntime() in case that
  // never fired.
  if (PseudoStack* stack = mozilla_get_pseudo_stack()) {
    stack->sampleRuntime(nullptr);
  }
#endif

  // Shut down the JS engine.
  JS_ShutDown();

  // Release our own singletons
  // Do this _after_ shutting down the component manager, because the
  // JS component loader will use XPConnect to call nsIModule::canUnload,
  // and that will spin up the InterfaceInfoManager again -- bad mojo
  XPTInterfaceInfoManager::FreeInterfaceInfoManager();

  // Finally, release the component manager last because it unloads the
  // libraries:
  if (nsComponentManagerImpl::gComponentManager) {
    nsrefcnt cnt;
    NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
    NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
  }
  nsComponentManagerImpl::gComponentManager = nullptr;
  nsCategoryManager::Destroy();

  NS_PurgeAtomTable();

  NS_IF_RELEASE(gDebug);

  delete sIOThread;
  sIOThread = nullptr;

  delete sMessageLoop;
  sMessageLoop = nullptr;

  if (sCommandLineWasInitialized) {
    CommandLine::Terminate();
    sCommandLineWasInitialized = false;
  }

  delete sExitManager;
  sExitManager = nullptr;

  Omnijar::CleanUp();

  HangMonitor::Shutdown();

  delete sMainHangMonitor;
  sMainHangMonitor = nullptr;

  BackgroundHangMonitor::Shutdown();

  profiler_shutdown();

  NS_LogTerm();

#if defined(MOZ_WIDGET_GONK)
  // This exit(0) call is intended to be temporary, to get shutdown leak
  // checking working on Linux.
  // On debug B2G, the child process crashes very late.  Instead, just
  // give up so at least we exit cleanly. See bug 1071866.
  if (XRE_IsContentProcess()) {
      NS_WARNING("Exiting child process early!");
      exit(0);
  }
#endif

  return NS_OK;
}
NS_IMETHODIMP
nsInputStreamPump::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
{
    NS_ENSURE_TRUE(mState == STATE_IDLE, NS_ERROR_IN_PROGRESS);
    NS_ENSURE_ARG_POINTER(listener);

    //
    // OK, we need to use the stream transport service if
    //
    // (1) the stream is blocking
    // (2) the stream does not support nsIAsyncInputStream
    //

    bool nonBlocking;
    nsresult rv = mStream->IsNonBlocking(&nonBlocking);
    if (NS_FAILED(rv)) return rv;

    if (nonBlocking) {
        mAsyncStream = do_QueryInterface(mStream);
        //
        // if the stream supports nsIAsyncInputStream, and if we need to seek
        // to a starting offset, then we must do so here.  in the non-async
        // stream case, the stream transport service will take care of seeking
        // for us.
        // 
        if (mAsyncStream && (mStreamOffset != LL_MAXUINT)) {
            nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mStream);
            if (seekable)
                seekable->Seek(nsISeekableStream::NS_SEEK_SET, mStreamOffset);
        }
    }

    if (!mAsyncStream) {
        // ok, let's use the stream transport service to read this stream.
        nsCOMPtr<nsIStreamTransportService> sts =
            do_GetService(kStreamTransportServiceCID, &rv);
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsITransport> transport;
        rv = sts->CreateInputTransport(mStream, mStreamOffset, mStreamLength,
                                       mCloseWhenDone, getter_AddRefs(transport));
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsIInputStream> wrapper;
        rv = transport->OpenInputStream(0, mSegSize, mSegCount, getter_AddRefs(wrapper));
        if (NS_FAILED(rv)) return rv;

        mAsyncStream = do_QueryInterface(wrapper, &rv);
        if (NS_FAILED(rv)) return rv;
    }

    // release our reference to the original stream.  from this point forward,
    // we only reference the "stream" via mAsyncStream.
    mStream = 0;

    // mStreamOffset now holds the number of bytes currently read.  we use this
    // to enforce the mStreamLength restriction.
    mStreamOffset = 0;

    // grab event queue (we must do this here by contract, since all notifications
    // must go to the thread which called AsyncRead)
    mTargetThread = do_GetCurrentThread();
    NS_ENSURE_STATE(mTargetThread);

    rv = EnsureWaiting();
    if (NS_FAILED(rv)) return rv;

    if (mLoadGroup)
        mLoadGroup->AddRequest(this, nullptr);

    mState = STATE_START;
    mListener = listener;
    mListenerContext = ctxt;
    return NS_OK;
}
Beispiel #22
0
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()
Beispiel #23
0
NS_IMETHODIMP
nsLDAPConnection::Init(nsILDAPURL *aUrl, const nsACString &aBindName,
                       nsILDAPMessageListener *aMessageListener,
                       nsISupports *aClosure, uint32_t aVersion)
{
  NS_ENSURE_ARG_POINTER(aUrl);
  NS_ENSURE_ARG_POINTER(aMessageListener);

  nsresult rv;
  nsCOMPtr<nsIObserverService> obsServ =
        do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  // We have to abort all LDAP pending operation before shutdown.
  obsServ->AddObserver(this, "profile-change-net-teardown", true);

  // Save various items that we'll use later
  mBindName.Assign(aBindName);
  mClosure = aClosure;
  mInitListener = aMessageListener;

  // Make sure we haven't called Init earlier, i.e. there's a DNS
  // request pending.
  NS_ASSERTION(!mDNSRequest, "nsLDAPConnection::Init() "
               "Connection was already initialized\n");

  // Check and save the version number
  if (aVersion != nsILDAPConnection::VERSION2 &&
      aVersion != nsILDAPConnection::VERSION3) {
    NS_ERROR("nsLDAPConnection::Init(): illegal version");
    return NS_ERROR_ILLEGAL_VALUE;
  }
  mVersion = aVersion;

  // Get the port number, SSL flag for use later, once the DNS server(s)
  // has resolved the host part.
  rv = aUrl->GetPort(&mPort);
  NS_ENSURE_SUCCESS(rv, rv);

  uint32_t options;
  rv = aUrl->GetOptions(&options);
  NS_ENSURE_SUCCESS(rv, rv);

  mSSL = options & nsILDAPURL::OPT_SECURE;

  // Initialise the hashtable to keep track of pending operations.
  // 10 buckets seems like a reasonable size.
  mPendingOperations.Init(10);

  nsCOMPtr<nsIThread> curThread = do_GetCurrentThread();
  if (!curThread) {
    NS_ERROR("nsLDAPConnection::Init(): couldn't get current thread");
    return NS_ERROR_FAILURE;
  }

  // Do the pre-resolve of the hostname, using the DNS service. This
  // will also initialize the LDAP connection properly, once we have
  // the IPs resolved for the hostname. This includes creating the
  // new thread for this connection.
  //
  // XXX - What return codes can we expect from the DNS service?
  //
  nsCOMPtr<nsIDNSService>
    pDNSService(do_GetService(kDNSServiceContractId, &rv));

  if (NS_FAILED(rv)) {
    NS_ERROR("nsLDAPConnection::Init(): couldn't create the DNS Service object");
    return NS_ERROR_FAILURE;
  }

  rv = aUrl->GetAsciiHost(mDNSHost);
  NS_ENSURE_SUCCESS(rv, rv);

  // if the caller has passed in a space-delimited set of hosts, as the
  // ldap c-sdk allows, strip off the trailing hosts for now.
  // Soon, we'd like to make multiple hosts work, but now make
  // at least the first one work.
  LdapCompressWhitespace(mDNSHost);

  int32_t spacePos = mDNSHost.FindChar(' ');
  // trim off trailing host(s)
  if (spacePos != kNotFound)
    mDNSHost.SetLength(spacePos);

  rv = pDNSService->AsyncResolve(mDNSHost, 0, this, curThread,
                                 getter_AddRefs(mDNSRequest));

  if (NS_FAILED(rv)) {
    switch (rv) {
    case NS_ERROR_OUT_OF_MEMORY:
    case NS_ERROR_UNKNOWN_HOST:
    case NS_ERROR_FAILURE:
    case NS_ERROR_OFFLINE:
      break;

    default:
      rv = NS_ERROR_UNEXPECTED;
    }
    mDNSHost.Truncate();
  }
  return rv;
}
Beispiel #24
0
inline void
NuwaParent::AssertIsOnWorkerThread()
{
  nsCOMPtr<nsIThread> currentThread = do_GetCurrentThread();
  MOZ_ASSERT(currentThread ==  mWorkerThread);
}
nsresult
nsMsgCopy::DoCopy(nsIFile *aDiskFile, nsIMsgFolder *dstFolder,
                  nsIMsgDBHdr *aMsgToReplace, bool aIsDraft,
                  nsIMsgWindow *msgWindow,
                  nsIMsgSend   *aMsgSendObj)
{
  nsresult rv = NS_OK;

  // Check sanity
  if ((!aDiskFile) || (!dstFolder))
    return NS_ERROR_INVALID_ARG;

  //Call copyservice with dstFolder, disk file, and txnManager
  if(NS_SUCCEEDED(rv))
  {
    nsRefPtr<CopyListener> copyListener = new CopyListener();
    if (!copyListener)
      return NS_ERROR_OUT_OF_MEMORY;

    copyListener->SetMsgComposeAndSendObject(aMsgSendObj);
    nsCOMPtr<nsIThread> thread;

    if (aIsDraft)
    {
        nsCOMPtr<nsIMsgImapMailFolder> imapFolder =
            do_QueryInterface(dstFolder);
        nsCOMPtr<nsIMsgAccountManager> accountManager =
                 do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
        if (NS_FAILED(rv)) return rv;
        bool shutdownInProgress = false;
        rv = accountManager->GetShutdownInProgress(&shutdownInProgress);

        if (NS_SUCCEEDED(rv) && shutdownInProgress && imapFolder)
        {
          // set the following only when we were in the middle of shutdown
          // process
            copyListener->mCopyInProgress = true;
            thread = do_GetCurrentThread();
        }
    }
    nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = copyService->CopyFileMessage(aDiskFile, dstFolder, aMsgToReplace,
                                      aIsDraft,
                                      aIsDraft ? 0 : nsMsgMessageFlags::Read,
                                      EmptyCString(), copyListener, msgWindow);
    // copyListener->mCopyInProgress can only be set when we are in the
    // middle of the shutdown process
    while (copyListener->mCopyInProgress)
    {
        PR_CEnterMonitor(copyListener);
        PR_CWait(copyListener, PR_MicrosecondsToInterval(1000UL));
        PR_CExitMonitor(copyListener);
        if (thread)
            NS_ProcessPendingEvents(thread);
    }
  }

  return rv;
}
Beispiel #26
0
NS_INTERFACE_MAP_END


//----------------------------------------------------------------------
// nsIRunnable methods:

NS_IMETHODIMP nsJSSh::Run()
{
  nsCOMPtr<nsIJSSh> proxied_shell;
  if (!NS_IsMainThread()) {
    nsCOMPtr<nsIProxyObjectManager> pom = do_GetService(NS_XPCOMPROXY_CONTRACTID);
    NS_ASSERTION(pom, "uh-oh, no proxy object manager!");
    pom->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                           NS_GET_IID(nsIJSSh),
                           (nsIJSSh*)this,
                           NS_PROXY_SYNC,
                           getter_AddRefs(proxied_shell));
  }
  else {
    LOG(("jssh shell will block main thread!\n"));
    proxied_shell = this;
  }
  proxied_shell->Init();

  if (mInput) {
    // read-eval-print loop
    PRUint32 bytesWritten;
    if (mOutput && !mProtocol.Equals(NS_LITERAL_CSTRING("plain")))
      mOutput->Write(gWelcome, strlen(gWelcome), &bytesWritten);
    
    while (!mQuit) {
      if (mOutput)
        mOutput->Write(mPrompt.get(), mPrompt.Length(), &bytesWritten);
      
      // accumulate input until we get a compilable unit:
      PRBool iscompilable;
      mBufferPtr = 0;
#ifdef DEBUG
//     nsCOMPtr<nsIThread> thread;
//     nsIThread::GetCurrent(getter_AddRefs(thread));
//     printf("blocking on thread %p\n", thread.get());
#endif
      do {
        PRUint32 bytesRead = 0;
        mInput->Read(mBuffer+mBufferPtr, 1, &bytesRead);
        if (bytesRead) {
          ++mBufferPtr;
        }
        else {
          // connection was terminated by the client
          mQuit = PR_TRUE;
          break;
        }
        // XXX signal buffer overflow ??
        // XXX ideally we want a dynamically resizing buffer.
      }while (mBufferPtr<cBufferSize &&
              (mBuffer[mBufferPtr-1]!=10 || (NS_SUCCEEDED(proxied_shell->IsBufferCompilable(&iscompilable)) && !iscompilable)));
      NS_ASSERTION(mBufferPtr<cBufferSize, "buffer overflow");
      
      proxied_shell->ExecuteBuffer();
    }
  }
  
  proxied_shell->Cleanup();

  if (!NS_IsMainThread()) {
    // Shutdown the current thread, which must be done from the main thread.
    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
    nsCOMPtr<nsIThread> proxied_thread;
    nsCOMPtr<nsIProxyObjectManager> pom = do_GetService(NS_XPCOMPROXY_CONTRACTID);
    NS_ASSERTION(pom, "uh-oh, no proxy object manager!");
    pom->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                           NS_GET_IID(nsIThread),
                           thread.get(),
                           NS_PROXY_ASYNC,
                           getter_AddRefs(proxied_thread));
    if (proxied_thread)
      proxied_thread->Shutdown();
  }
  return NS_OK;
}
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;
}
NS_IMETHODIMP
nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
    nsresult rv = NS_CheckPortSafety(mPort, "finger");
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
    NS_ENSURE_STATE(thread);

    //
    // create transport
    //
    nsCOMPtr<nsISocketTransportService> sts = 
             do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;

    rv = sts->CreateTransport(nsnull, 0, mHost, mPort, mProxyInfo,
                              getter_AddRefs(mTransport));
    if (NS_FAILED(rv)) return rv;

    // not fatal if this fails
    mTransport->SetEventSink(this, thread);

    rv = WriteRequest(mTransport);
    if (NS_FAILED(rv)) return rv;

    //
    // create TXT to HTML stream converter
    //
    nsCOMPtr<nsIStreamConverterService> scs = 
             do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsIStreamListener> convListener;
    rv = scs->AsyncConvertData("text/plain", "text/html", this, nsnull,
                               getter_AddRefs(convListener));
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsITXTToHTMLConv> conv = do_QueryInterface(convListener);
    if (conv) {
        nsCAutoString userHost;
        rv = mURI->GetPath(userHost);

        nsAutoString title;
        title.AppendLiteral("Finger information for ");
        AppendUTF8toUTF16(userHost, title);

        conv->SetTitle(title.get());
        conv->PreFormatHTML(PR_TRUE);
    }

    //
    // open input stream, and create input stream pump...
    //
    nsCOMPtr<nsIInputStream> sockIn;
    rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(sockIn));
    if (NS_FAILED(rv)) return rv;

    rv = NS_NewInputStreamPump(getter_AddRefs(mPump), sockIn);
    if (NS_FAILED(rv)) return rv;

    rv = mPump->AsyncRead(convListener, nsnull);
    if (NS_FAILED(rv)) return rv;

    if (mLoadGroup)
        mLoadGroup->AddRequest(this, nsnull);

    mListener = aListener;
    mListenerContext = ctxt;
    return NS_OK;
}
nsresult
ShutdownXPCOM(nsIServiceManager* servMgr)
{
    // Make sure the hang monitor is enabled for shutdown.
    HangMonitor::NotifyActivity();

    NS_ENSURE_STATE(NS_IsMainThread());

    nsresult rv;
    nsCOMPtr<nsISimpleEnumerator> moduleLoaders;

    // Notify observers of xpcom shutting down
    {
        // Block it so that the COMPtr will get deleted before we hit
        // servicemanager shutdown

        nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
        NS_ENSURE_STATE(thread);

        nsRefPtr<nsObserverService> observerService;
        CallGetService("@mozilla.org/observer-service;1",
                       (nsObserverService**) getter_AddRefs(observerService));

        if (observerService)
        {
            (void) observerService->
                NotifyObservers(nullptr, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
                                nullptr);

            nsCOMPtr<nsIServiceManager> mgr;
            rv = NS_GetServiceManager(getter_AddRefs(mgr));
            if (NS_SUCCEEDED(rv))
            {
                (void) observerService->
                    NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                    nullptr);
            }
        }

        NS_ProcessPendingEvents(thread);
        mozilla::scache::StartupCache::DeleteSingleton();
        if (observerService)
            (void) observerService->
                NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
                                nullptr);

        nsCycleCollector_shutdownThreads();

        NS_ProcessPendingEvents(thread);

        // Shutdown the timer thread and all timers that might still be alive before
        // shutting down the component manager
        nsTimerImpl::Shutdown();

        NS_ProcessPendingEvents(thread);

        // Shutdown all remaining threads.  This method does not return until
        // all threads created using the thread manager (with the exception of
        // the main thread) have exited.
        nsThreadManager::get()->Shutdown();

        NS_ProcessPendingEvents(thread);

        HangMonitor::NotifyActivity();

        // We save the "xpcom-shutdown-loaders" observers to notify after
        // the observerservice is gone.
        if (observerService) {
            observerService->
                EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
                                   getter_AddRefs(moduleLoaders));

            observerService->Shutdown();
        }
    }

    // Free ClearOnShutdown()'ed smart pointers.  This needs to happen *after*
    // we've finished notifying observers of XPCOM shutdown, because shutdown
    // observers themselves might call ClearOnShutdown().
    mozilla::KillClearOnShutdown();

    // XPCOM is officially in shutdown mode NOW
    // Set this only after the observers have been notified as this
    // will cause servicemanager to become inaccessible.
    mozilla::services::Shutdown();

#ifdef DEBUG_dougt
    fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
#endif
    // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
    // here again:
    NS_IF_RELEASE(servMgr);

    // Shutdown global servicemanager
    if (nsComponentManagerImpl::gComponentManager) {
        nsComponentManagerImpl::gComponentManager->FreeServices();
    }

    // Release the directory service
    NS_IF_RELEASE(nsDirectoryService::gService);

    SAMPLE_MARKER("Shutdown xpcom");
    mozilla::PoisonWrite();

    nsCycleCollector_shutdown();

    if (moduleLoaders) {
        bool more;
        nsCOMPtr<nsISupports> el;
        while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) &&
               more) {
            moduleLoaders->GetNext(getter_AddRefs(el));

            // Don't worry about weak-reference observers here: there is
            // no reason for weak-ref observers to register for
            // xpcom-shutdown-loaders

            nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
            if (obs)
                (void) obs->Observe(nullptr,
                                    NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
                                    nullptr);
        }

        moduleLoaders = nullptr;
    }

    // Shutdown nsLocalFile string conversion
    NS_ShutdownLocalFile();
#ifdef XP_UNIX
    NS_ShutdownNativeCharsetUtils();
#endif

    // Shutdown xpcom. This will release all loaders and cause others holding
    // a refcount to the component manager to release it.
    if (nsComponentManagerImpl::gComponentManager) {
        rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
        NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
    } else
        NS_WARNING("Component Manager was never created ...");

    // Release our own singletons
    // Do this _after_ shutting down the component manager, because the
    // JS component loader will use XPConnect to call nsIModule::canUnload,
    // and that will spin up the InterfaceInfoManager again -- bad mojo
    xptiInterfaceInfoManager::FreeInterfaceInfoManager();

    // Finally, release the component manager last because it unloads the
    // libraries:
    if (nsComponentManagerImpl::gComponentManager) {
      nsrefcnt cnt;
      NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
      NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
    }
    nsComponentManagerImpl::gComponentManager = nullptr;
    nsCategoryManager::Destroy();

    NS_PurgeAtomTable();

    NS_IF_RELEASE(gDebug);

    if (sIOThread) {
        delete sIOThread;
        sIOThread = nullptr;
    }
    if (sMessageLoop) {
        delete sMessageLoop;
        sMessageLoop = nullptr;
    }
    if (sCommandLineWasInitialized) {
        CommandLine::Terminate();
        sCommandLineWasInitialized = false;
    }
    if (sExitManager) {
        delete sExitManager;
        sExitManager = nullptr;
    }

    Omnijar::CleanUp();

    HangMonitor::Shutdown();

    eventtracer::Shutdown();

    NS_LogTerm();

    return NS_OK;
}
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;
}