gboolean purpleDNS::Resolve(PurpleDnsQueryData *query_data,
                            PurpleDnsQueryResolvedCallback resolved_cb,
                            PurpleDnsQueryFailedCallback failed_cb)
{
  NS_ENSURE_TRUE(!NS_IsOffline(), false);
  nsCString host(purple_dnsquery_get_host(query_data));
  LOG(("Resolving with moz: %s", host.get()));
  NS_ENSURE_TRUE(sRequests, false);

  nsCOMPtr<nsIDNSService> dns = do_GetService("@mozilla.org/network/dns-service;1");
  nsCOMPtr<nsIDNSRecord> record;
  nsCOMPtr<nsICancelable> cancelable;
  nsCOMPtr<nsIThread> thread = do_GetMainThread();
  nsCOMPtr<purpleDNSRequest> listener;
  listener = new purpleDNSRequest();
  listener->mAccountId = purpleAccountScoper::GetCurrentAccountId();
  listener->query_data = query_data;
  listener->resolved_cb = resolved_cb;
  listener->failed_cb = failed_cb;

  nsresult rv = dns->AsyncResolve(host, 0, listener, thread,
                                  getter_AddRefs(listener->asyncResolv));
  NS_ENSURE_SUCCESS(rv, false);// The request wasn't handled.

  sRequests->AppendObject(listener);
  return true; // We handle the request, libpurple shouldn't try to do it.
}
Example #2
0
  TemporaryRef<gfx::DataSourceSurface> GetDataSurfaceSafe() {
    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    MOZ_ASSERT(mainThread);
    SyncRunnable::DispatchToThread(mainThread, this, false);

    return mDataSourceSurface.forget();
  }
Example #3
0
void
CrashReporterParent::FinalizeChildData()
{
    MOZ_ASSERT(mInitialized);

    if (NS_IsMainThread()) {
        // Inline, this is the main thread. Get this done.
        NotifyCrashService();
        return;
    }

    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    class NotifyOnMainThread : public nsRunnable
    {
    public:
        explicit NotifyOnMainThread(CrashReporterParent* aCR)
            : mCR(aCR)
        { }

        NS_IMETHOD Run() {
            mCR->NotifyCrashService();
            return NS_OK;
        }
    private:
        CrashReporterParent* mCR;
    };
    SyncRunnable::DispatchToThread(mainThread, new NotifyOnMainThread(this));
}
nsresult
nsInputStreamPump::EnsureWaiting()
{
    mMonitor.AssertCurrentThreadIn();

    // no need to worry about multiple threads... an input stream pump lives
    // on only one thread at a time.
    MOZ_ASSERT(mAsyncStream);
    if (!mWaitingForInputStreamReady && !mProcessingCallbacks) {
        // Ensure OnStateStop is called on the main thread.
        if (mState == STATE_STOP) {
            nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
            if (mTargetThread != mainThread) {
                mTargetThread = do_QueryInterface(mainThread);
            }
        }
        MOZ_ASSERT(mTargetThread);
        nsresult rv = mAsyncStream->AsyncWait(this, 0, 0, mTargetThread);
        if (NS_FAILED(rv)) {
            NS_ERROR("AsyncWait failed");
            return rv;
        }
        // Any retargeting during STATE_START or START_TRANSFER is complete
        // after the call to AsyncWait; next callback wil be on mTargetThread.
        mRetargeting = false;
        mWaitingForInputStreamReady = true;
    }
    return NS_OK;
}
Example #5
0
void
CacheFileChunk::WaitForUpdate(CacheFileChunkListener *aCallback)
{
  mFile->AssertOwnsLock();

  LOG(("CacheFileChunk::WaitForUpdate() [this=%p, listener=%p]",
       this, aCallback));

  MOZ_ASSERT(mFile->mOutput);
  MOZ_ASSERT(IsReady());

#ifdef DEBUG
  for (uint32_t i = 0 ; i < mUpdateListeners.Length() ; i++) {
    MOZ_ASSERT(mUpdateListeners[i]->mCallback != aCallback);
  }
#endif

  ChunkListenerItem *item = new ChunkListenerItem();
  item->mTarget = CacheFileIOManager::IOTarget();
  if (!item->mTarget) {
    LOG(("CacheFileChunk::WaitForUpdate() - Cannot get Cache I/O thread! Using "
         "main thread for callback."));
    item->mTarget = do_GetMainThread();
  }
  item->mCallback = aCallback;
  MOZ_ASSERT(item->mTarget);
  item->mCallback = aCallback;

  mUpdateListeners.AppendElement(item);
}
GMPParent*
GeckoMediaPluginServiceParent::ClonePlugin(const GMPParent* aOriginal)
{
  MOZ_ASSERT(aOriginal);

  // The GMPParent inherits from IToplevelProtocol, which must be created
  // on the main thread to be threadsafe. See Bug 1035653.
  nsRefPtr<CreateGMPParentTask> task(new CreateGMPParentTask());
  if (!NS_IsMainThread()) {
    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    MOZ_ASSERT(mainThread);
    mozilla::SyncRunnable::DispatchToThread(mainThread, task);
  }

  nsRefPtr<GMPParent> gmp = task->GetParent();
  nsresult rv = gmp->CloneFrom(aOriginal);

  if (NS_FAILED(rv)) {
    NS_WARNING("Can't Create GMPParent");
    return nullptr;
  }

  MutexAutoLock lock(mMutex);
  mPlugins.AppendElement(gmp);

  return gmp.get();
}
Example #7
0
void
PDMFactory::EnsureInit() const
{
  {
    StaticMutexAutoLock mon(sMonitor);
    if (sInstance) {
      // Quick exit if we already have an instance.
      return;
    }
    if (NS_IsMainThread()) {
      // On the main thread and holding the lock -> Create instance.
      sInstance = new PDMFactoryImpl();
      ClearOnShutdown(&sInstance);
      return;
    }
  }

  // Not on the main thread -> Sync-dispatch creation to main thread.
  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  nsCOMPtr<nsIRunnable> runnable =
    NS_NewRunnableFunction([]() {
      StaticMutexAutoLock mon(sMonitor);
      if (!sInstance) {
        sInstance = new PDMFactoryImpl();
        ClearOnShutdown(&sInstance);
      }
    });
  SyncRunnable::DispatchToThread(mainThread, runnable);
}
void
GeckoMediaPluginServiceParent::AddOnGMPThread(const nsAString& aDirectory)
{
  MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
  LOGD(("%s::%s: %s", __CLASS__, __FUNCTION__, NS_LossyConvertUTF16toASCII(aDirectory).get()));

  nsCOMPtr<nsIFile> directory;
  nsresult rv = NS_NewLocalFile(aDirectory, false, getter_AddRefs(directory));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return;
  }

  // The GMPParent inherits from IToplevelProtocol, which must be created
  // on the main thread to be threadsafe. See Bug 1035653.
  nsRefPtr<CreateGMPParentTask> task(new CreateGMPParentTask());
  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  MOZ_ASSERT(mainThread);
  mozilla::SyncRunnable::DispatchToThread(mainThread, task);
  nsRefPtr<GMPParent> gmp = task->GetParent();
  rv = gmp ? gmp->Init(this, directory) : NS_ERROR_NOT_AVAILABLE;
  if (NS_FAILED(rv)) {
    NS_WARNING("Can't Create GMPParent");
    return;
  }

  {
    MutexAutoLock lock(mMutex);
    mPlugins.AppendElement(gmp);
  }

  NS_DispatchToMainThread(new NotifyObserversTask("gmp-path-added"), NS_DISPATCH_NORMAL);
}
Example #9
0
void FileBlockCache::Close()
{
    NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
    MonitorAutoLock mon(mDataMonitor);

    mIsOpen = false;

    if (mThread) {
        // We must shut down the thread in another runnable. This is called
        // while we're shutting down the media cache, and nsIThread::Shutdown()
        // can cause events to run before it completes, which could end up
        // opening more streams, while the media cache is shutting down and
        // releasing memory etc! Also note we close mFD in the destructor so
        // as to not disturb any IO that's currently running.
        nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
        if (mainThread) {
            nsCOMPtr<nsIRunnable> event = new ShutdownThreadEvent(mThread);
            mainThread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
        } else {
            // we're on Mainthread already, *and* the event queues are already
            // shut down, so no events should occur - certainly not creations of
            // new streams.
            mThread->Shutdown();
        }
    }
}
Example #10
0
bool
WorkerRunnable::DispatchInternal()
{
  nsRefPtr<WorkerRunnable> runnable(this);

  if (mBehavior == WorkerThreadModifyBusyCount ||
      mBehavior == WorkerThreadUnchangedBusyCount) {
    if (IsDebuggerRunnable()) {
      return NS_SUCCEEDED(mWorkerPrivate->DispatchDebuggerRunnable(runnable.forget()));
    } else {
      return NS_SUCCEEDED(mWorkerPrivate->Dispatch(runnable.forget()));
    }
  }

  MOZ_ASSERT(mBehavior == ParentThreadUnchangedBusyCount);

  if (WorkerPrivate* parent = mWorkerPrivate->GetParent()) {
    return NS_SUCCEEDED(parent->Dispatch(runnable.forget()));
  }

  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  MOZ_ASSERT(mainThread);

  return NS_SUCCEEDED(mainThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
}
void
CacheFileOutputStream::NotifyListener()
{
  mFile->AssertOwnsLock();

  LOG(("CacheFileOutputStream::NotifyListener() [this=%p]", this));

  MOZ_ASSERT(mCallback);

  if (!mCallbackTarget) {
    mCallbackTarget = CacheFileIOManager::IOTarget();
    if (!mCallbackTarget) {
      LOG(("CacheFileOutputStream::NotifyListener() - Cannot get Cache I/O "
           "thread! Using main thread for callback."));
      mCallbackTarget = do_GetMainThread();
    }
  }

  nsCOMPtr<nsIOutputStreamCallback> asyncCallback =
    NS_NewOutputStreamReadyEvent(mCallback, mCallbackTarget);

  mCallback = nullptr;
  mCallbackTarget = nullptr;

  asyncCallback->OnOutputStreamReady(this);
}
void
ReadbackManagerD3D11::ProcessTasks()
{
  HANDLE handles[] = { mTaskSemaphore, mShutdownEvent };

  while (true) {
    DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
    if (result != WAIT_OBJECT_0) {
      return;
    }

    ::EnterCriticalSection(&mTaskMutex);
    if (mPendingReadbackTasks.Length() == 0) {
      NS_RUNTIMEABORT("Trying to read from an empty array, bad bad bad");
    }
    ReadbackTask *nextReadbackTask = mPendingReadbackTasks[0].forget();
    mPendingReadbackTasks.RemoveElementAt(0);
    ::LeaveCriticalSection(&mTaskMutex);

    // We want to block here until the texture contents are available, the
    // easiest thing is to simply map and unmap.
    D3D10_MAPPED_TEXTURE2D mappedTex;
    nextReadbackTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
    nextReadbackTask->mReadbackTexture->Unmap(0);

    // We can only send the update to the sink on the main thread, so post an
    // event there to do so. Ownership of the task is passed from
    // mPendingReadbackTasks to ReadbackResultWriter here.
    nsCOMPtr<nsIThread> thread = do_GetMainThread();
    thread->Dispatch(new ReadbackResultWriterD3D11(nextReadbackTask),
                     nsIEventTarget::DISPATCH_NORMAL);
  }
}
Example #13
0
void
DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
{
  AssertOwnerThread();
  MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");

  mStartTime.emplace(aStartTime);
  mInfo = aInfo;
  mPlaying = true;
  ConnectListener();

  class R : public Runnable {
    typedef MozPromiseHolder<GenericPromise> Promise;
  public:
    R(PlaybackInfoInit&& aInit, Promise&& aPromise, OutputStreamManager* aManager)
      : mInit(Move(aInit)), mOutputStreamManager(aManager)
    {
      mPromise = Move(aPromise);
    }
    NS_IMETHOD Run() override
    {
      MOZ_ASSERT(NS_IsMainThread());
      // No need to create a source stream when there are no output streams. This
      // happens when RemoveOutput() is called immediately after StartPlayback().
      if (!mOutputStreamManager->Graph()) {
        // Resolve the promise to indicate the end of playback.
        mPromise.Resolve(true, __func__);
        return NS_OK;
      }
      mData = MakeUnique<DecodedStreamData>(
        mOutputStreamManager, Move(mInit), Move(mPromise));
      return NS_OK;
    }
    UniquePtr<DecodedStreamData> ReleaseData()
    {
      return Move(mData);
    }
  private:
    PlaybackInfoInit mInit;
    Promise mPromise;
    RefPtr<OutputStreamManager> mOutputStreamManager;
    UniquePtr<DecodedStreamData> mData;
  };

  MozPromiseHolder<GenericPromise> promise;
  mFinishPromise = promise.Ensure(__func__);
  PlaybackInfoInit init {
    aStartTime, aInfo
  };
  nsCOMPtr<nsIRunnable> r = new R(Move(init), Move(promise), mOutputStreamManager);
  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  SyncRunnable::DispatchToThread(mainThread, r);
  mData = static_cast<R*>(r.get())->ReleaseData();

  if (mData) {
    mData->SetPlaying(mPlaying);
    SendData();
  }
}
Example #14
0
 ~nsWyciwygAsyncEvent()
 {
     nsCOMPtr<nsIThread> thread = do_GetMainThread();
     NS_WARN_IF_FALSE(thread, "Couldn't get the main thread!");
     if (thread) {
         nsIWyciwygChannel *chan = static_cast<nsIWyciwygChannel *>(mChannel);
         mozilla::unused << mChannel.forget();
         NS_ProxyRelease(thread, chan);
     }
 }
JavaXPCOMInstance::~JavaXPCOMInstance()
{
  nsresult rv = NS_OK;

  // Need to release these objects on the main thread.
  nsCOMPtr<nsIThread> thread = do_GetMainThread();
  if (thread) {
    rv = NS_ProxyRelease(thread, mInstance);
    rv |= NS_ProxyRelease(thread, mIInfo);
  }
  NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to release using NS_ProxyRelease");
}
Example #16
0
bool
CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes)
{
    MOZ_ASSERT(mInitialized);

    nsAutoCString type;
    switch (mProcessType) {
        case GeckoProcessType_Content:
            type = NS_LITERAL_CSTRING("content");
            break;
        case GeckoProcessType_Plugin:
        case GeckoProcessType_GMPlugin:
            type = NS_LITERAL_CSTRING("plugin");
            break;
        default:
            NS_ERROR("unknown process type");
            break;
    }
    mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type);

    char startTime[32];
    sprintf(startTime, "%lld", static_cast<long long>(mStartTime));
    mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));

    if (!mAppNotes.IsEmpty())
        mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);

    bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes);
    if (ret && processNotes)
        ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes);
    if (!ret)
        NS_WARNING("problem appending child data to .extra");

    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    class NotifyOnMainThread : public nsRunnable
    {
    public:
        NotifyOnMainThread(CrashReporterParent* aCR)
            : mCR(aCR)
        { }

        NS_IMETHOD Run() {
            mCR->NotifyCrashService();
            return NS_OK;
        }
    private:
        CrashReporterParent* mCR;
    };
    SyncRunnable::DispatchToThread(mainThread, new NotifyOnMainThread(this));
    return ret;
}
void HRTFDatabaseLoader::ProxyRelease()
{
    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    if (MOZ_LIKELY(mainThread)) {
        RefPtr<ProxyReleaseEvent> event = new ProxyReleaseEvent(this);
        DebugOnly<nsresult> rv =
            mainThread->Dispatch(event, NS_DISPATCH_NORMAL);
        MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to dispatch release event");
    } else {
        // Should be in XPCOM shutdown.
        MOZ_ASSERT(NS_IsMainThread(),
                   "Main thread is not available for dispatch.");
        MainThreadRelease();
    }
}
Example #18
0
ManagerId::~ManagerId()
{
  // If we're already on the main thread, then default destruction is fine
  if (NS_IsMainThread()) {
    return;
  }

  // Otherwise we need to proxy to main thread to do the release

  // The PBackground worker thread shouldn't be running after the main thread
  // is stopped.  So main thread is guaranteed to exist here.
  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  MOZ_ASSERT(mainThread);

  NS_ProxyRelease(mainThread, mPrincipal.forget().take());
}
Example #19
0
nsHTTPListener::~nsHTTPListener()
{
  if (mResponsibleForDoneSignal)
    send_done_signal();

  if (mCondition)
    PR_DestroyCondVar(mCondition);
  
  if (mLock)
    PR_DestroyLock(mLock);

  if (mLoader) {
    nsCOMPtr<nsIThread> mainThread(do_GetMainThread());
    NS_ProxyRelease(mainThread, mLoader);
  }
}
Example #20
0
nsrefcnt
nsXPCWrappedJS::Release(void)
{
    NS_PRECONDITION(0 != mRefCnt, "dup release");

    if (mMainThreadOnly && !NS_IsMainThread()) {
        // We'd like to abort here, but this can happen if someone uses a proxy
        // for the nsXPCWrappedJS.
        nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
        // If we can't get the main thread anymore we just leak, but this really
        // shouldn't happen.
        NS_ASSERTION(mainThread,
                     "Can't get main thread, leaking nsXPCWrappedJS!");
        if (mainThread) {
            NS_ProxyRelease(mainThread,
                            static_cast<nsIXPConnectWrappedJS*>(this));
        }
        return mRefCnt;
    }

    // need to take the map lock here to prevent GetNewOrUsed from trying
    // to reuse a wrapper on one thread while it's being destroyed on another
    XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
    XPCAutoLock lock(rt->GetMapLock());

do_decrement:

    nsrefcnt cnt = NS_AtomicDecrementRefcnt(mRefCnt);
    NS_LOG_RELEASE(this, cnt, "nsXPCWrappedJS");

    if (0 == cnt) {
        delete this;   // also unlinks us from chain
        return 0;
    }
    if (1 == cnt) {
        if (IsValid())
            RemoveFromRootSet(rt->GetMapLock());

        // If we are not the root wrapper or if we are not being used from a
        // weak reference, then this extra ref is not needed and we can let
        // ourself be deleted.
        // Note: HasWeakReferences() could only return true for the root.
        if (!HasWeakReferences())
            goto do_decrement;
    }
    return cnt;
}
/**
 * Free all used memory and close stream.
 */
NS_IMETHODIMP
nsGIOInputStream::Close()
{
  if (mStream)
  {
    g_object_unref(mStream);
    mStream = nullptr;
  }

  if (mHandle)
  {
    g_object_unref(mHandle);
    mHandle = nullptr;
  }

  if (mDirList)
  {
    // Destroy the list of GIOFileInfo objects...
    g_list_foreach(mDirList, (GFunc) g_object_unref, nullptr);
    g_list_free(mDirList);
    mDirList = nullptr;
    mDirListPtr = nullptr;
  }

  if (mChannel)
  {
    nsresult rv = NS_OK;

    nsCOMPtr<nsIThread> thread = do_GetMainThread();
    if (thread)
      rv = NS_ProxyRelease(thread, mChannel);

    NS_ASSERTION(thread && NS_SUCCEEDED(rv), "leaking channel reference");
    mChannel = nullptr;
    (void) rv;
  }

  mSpec.Truncate(); // free memory

  // Prevent future reads from re-opening the handle.
  if (NS_SUCCEEDED(mStatus))
    mStatus = NS_BASE_STREAM_CLOSED;

  return NS_OK;
}
JavaXPCOMInstance::~JavaXPCOMInstance()
{
  nsresult rv = NS_OK;

#ifdef VBOX
  nsCOMPtr<nsIEventQueue> eq = do_GetMainThreadQueue();
  rv = NS_ProxyRelease(eq.get(), mInstance);
  rv |= NS_ProxyRelease(eq.get(), mIInfo);
#else
  // Need to release these objects on the main thread.
  nsCOMPtr<nsIThread> thread = do_GetMainThread();
  if (thread) {
    rv = NS_ProxyRelease(thread, mInstance);
    rv |= NS_ProxyRelease(thread, mIInfo);
  }
#endif
  NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to release using NS_ProxyRelease");
}
  NS_IMETHOD Run()
  {
    mDict->SyncLoad();

    // Release the dictionary on the main thread
    mozPersonalDictionary *dict;
    mDict.forget(&dict);

    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    if (mainThread) {
      NS_ProxyRelease(mainThread, static_cast<mozIPersonalDictionary *>(dict));
    } else {
      // It's better to leak the dictionary than to release it on a wrong thread
      NS_WARNING("Cannot get main thread, leaking mozPersonalDictionary.");
    }

    return NS_OK;
  }
Example #24
0
PGMPContentParent*
GMPServiceChild::AllocPGMPContentParent(Transport* aTransport,
                                        ProcessId aOtherPid)
{
  MOZ_ASSERT(!mContentParents.GetWeak(aOtherPid));

  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  MOZ_ASSERT(mainThread);

  nsRefPtr<GMPContentParent> parent = new GMPContentParent();

  DebugOnly<bool> ok = parent->Open(aTransport, aOtherPid,
                                    XRE_GetIOMessageLoop(),
                                    mozilla::ipc::ParentSide);
  MOZ_ASSERT(ok);

  mContentParents.Put(aOtherPid, parent);
  return parent;
}
Example #25
0
// We store the records in files in the system temp dir.
static nsresult
GetGMPStorageDir(nsIFile** aTempDir, const nsString& aOrigin)
{
  if (NS_WARN_IF(!aTempDir)) {
    return NS_ERROR_INVALID_ARG;
  }

  // Directory service is main thread only...
  nsRefPtr<GetTempDirTask> task = new GetTempDirTask();
  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  mozilla::SyncRunnable::DispatchToThread(mainThread, task);

  nsCOMPtr<nsIFile> tmpFile;
  nsresult rv = NS_NewLocalFile(task->mPath, false, getter_AddRefs(tmpFile));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  rv = tmpFile->AppendNative(nsDependentCString("mozilla-gmp-storage"));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  // TODO: When aOrigin is the same node-id as the GMP sees in the child
  // process (a UUID or somesuch), we can just append it un-hashed here.
  // This should reduce the chance of hash collsions exposing data.
  nsAutoString nodeIdHash;
  nodeIdHash.AppendInt(HashString(static_cast<const char16_t*>(aOrigin.get())));
  rv = tmpFile->Append(nodeIdHash);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
  if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  tmpFile.forget(aTempDir);

  return NS_OK;
}
Example #26
0
nsresult 
nsDNSPrefetch::Prefetch(uint16_t flags)
{
    if (mHostname.IsEmpty())
        return NS_ERROR_NOT_AVAILABLE;
  
    if (!sDNSService)
        return NS_ERROR_NOT_AVAILABLE;
    
    nsCOMPtr<nsICancelable> tmpOutstanding;  

    if (mStoreTiming)
        mStartTimestamp = mozilla::TimeStamp::Now();
    // If AsyncResolve fails, for example because prefetching is disabled,
    // then our timing will be useless. However, in such a case,
    // mEndTimestamp will be a null timestamp and callers should check
    // TimingsValid() before using the timing.
    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    return sDNSService->AsyncResolve(mHostname,
                                     flags | nsIDNSService::RESOLVE_SPECULATE,
                                     this, mainThread,
                                     getter_AddRefs(tmpOutstanding));
}
  NS_IMETHOD Run() override
  {
    nsresult res;

    MOZ_ASSERT(!NS_IsMainThread());

    {
      mozilla::MonitorAutoLock mon(mDict->mMonitorSave);

      nsCOMPtr<nsIOutputStream> outStream;
      NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStream), mFile,
                                      PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
                                      0664);

      // Get a buffered output stream 4096 bytes big, to optimize writes.
      nsCOMPtr<nsIOutputStream> bufferedOutputStream;
      res = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
                                       outStream, 4096);
      if (NS_FAILED(res)) {
        return res;
      }

      uint32_t bytesWritten;
      nsAutoCString utf8Key;
      for (uint32_t i = 0; i < mDictWords.Length(); ++i) {
        CopyUTF16toUTF8(mDictWords[i], utf8Key);

        bufferedOutputStream->Write(utf8Key.get(), utf8Key.Length(),
                                    &bytesWritten);
        bufferedOutputStream->Write("\n", 1, &bytesWritten);
      }
      nsCOMPtr<nsISafeOutputStream> safeStream =
        do_QueryInterface(bufferedOutputStream);
      NS_ASSERTION(safeStream, "expected a safe output stream!");
      if (safeStream) {
        res = safeStream->Finish();
        if (NS_FAILED(res)) {
          NS_WARNING("failed to save personal dictionary file! possible data loss");
        }
      }

      // Save is done, reset the state variable and notify those who are waiting.
      mDict->mSavePending = false;
      mon.Notify();

      // Leaving the block where 'mon' was declared will call the destructor
      // and unlock.
    }

    // Release the dictionary on the main thread.
    mozPersonalDictionary *dict;
    mDict.forget(&dict);

    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
    if (mainThread) {
      NS_ProxyRelease(mainThread, static_cast<mozIPersonalDictionary *>(dict));
    } else {
      // It's better to leak the dictionary than to release it on a wrong thread.
      NS_WARNING("Cannot get main thread, leaking mozPersonalDictionary.");
    }
    return NS_OK;
  }
NS_IMETHODIMP 
nsProxyObjectManager::GetProxyForObject(nsIEventTarget* aTarget, 
                                        REFNSIID aIID, 
                                        nsISupports* aObj, 
                                        PRInt32 proxyType, 
                                        void** aProxyObject)
{
    NS_ENSURE_ARG_POINTER(aObj);

    *aProxyObject = nsnull;

    // handle special values
    nsCOMPtr<nsIThread> thread;
    if (aTarget == NS_PROXY_TO_CURRENT_THREAD) {
      aTarget = NS_GetCurrentThread();
    } else if (aTarget == NS_PROXY_TO_MAIN_THREAD) {
      thread = do_GetMainThread();
      aTarget = thread.get();
    }

    // check to see if the target is on our thread.  If so, just return the
    // real object.
    
    if (!(proxyType & NS_PROXY_ASYNC) && !(proxyType & NS_PROXY_ALWAYS))
    {
        PRBool result;
        aTarget->IsOnCurrentThread(&result);
     
        if (result)
            return aObj->QueryInterface(aIID, aProxyObject);
    }
    
    nsCOMPtr<nsISupports> realObj = do_QueryInterface(aObj);

    // Make sure the object passed in is not a proxy; if it is, be nice and
    // build the proxy for the real object.
    nsCOMPtr<nsProxyObject> po = do_QueryInterface(aObj);
    if (po) {
        realObj = po->GetRealObject();
    }

    nsCOMPtr<nsISupports> realEQ = do_QueryInterface(aTarget);

    nsProxyEventKey rootKey(realObj, realEQ, proxyType);

    {
        nsAutoLock lock(mProxyCreationLock);
        nsProxyLockedRefPtr root =
            (nsProxyObject*) mProxyObjectMap.Get(&rootKey);
        if (root)
            return root->LockedFind(aIID, aProxyObject);
    }

    // don't lock while creating the nsProxyObject
    nsProxyObject *newRoot = new nsProxyObject(aTarget, proxyType, realObj);
    if (!newRoot)
        return NS_ERROR_OUT_OF_MEMORY;

    // lock again, and check for a race putting into mProxyObjectMap
    {
        nsAutoLock lock(mProxyCreationLock);
        nsProxyLockedRefPtr root = 
            (nsProxyObject*) mProxyObjectMap.Get(&rootKey);
        if (root) {
            delete newRoot;
            return root->LockedFind(aIID, aProxyObject);
        }

        mProxyObjectMap.Put(&rootKey, newRoot);

        nsProxyLockedRefPtr kungFuDeathGrip(newRoot);
        return newRoot->LockedFind(aIID, aProxyObject);
    }
}
Example #29
0
 TracerRunnable() {
   mTracerLock = new Mutex("TracerRunnable");
   mTracerCondVar = new CondVar(*mTracerLock, "TracerRunnable");
   mMainThread = do_GetMainThread();
 }
Example #30
0
/* static */ void
CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
                                      const nsString& aChildDumpID,
                                      const AnnotationTable* aNotes)
{
  if (!NS_IsMainThread()) {
    RefPtr<Runnable> runnable = NS_NewRunnableFunction(
      "ipc::CrashReporterHost::NotifyCrashService", [=]() -> void {
        CrashReporterHost::NotifyCrashService(
          aProcessType, aChildDumpID, aNotes);
      });
    RefPtr<nsIThread> mainThread = do_GetMainThread();
    SyncRunnable::DispatchToThread(mainThread, runnable);
    return;
  }

  MOZ_ASSERT(!aChildDumpID.IsEmpty());

  nsCOMPtr<nsICrashService> crashService =
    do_GetService("@mozilla.org/crashservice;1");
  if (!crashService) {
    return;
  }

  int32_t processType;
  int32_t crashType = nsICrashService::CRASH_TYPE_CRASH;

  nsCString telemetryKey;

  switch (aProcessType) {
    case GeckoProcessType_Content:
      processType = nsICrashService::PROCESS_TYPE_CONTENT;
      telemetryKey.AssignLiteral("content");
      break;
    case GeckoProcessType_Plugin: {
      processType = nsICrashService::PROCESS_TYPE_PLUGIN;
      telemetryKey.AssignLiteral("plugin");
      nsAutoCString val;
      if (aNotes->Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
        val.EqualsLiteral("1")) {
        crashType = nsICrashService::CRASH_TYPE_HANG;
        telemetryKey.AssignLiteral("pluginhang");
      }
      break;
    }
    case GeckoProcessType_GMPlugin:
      processType = nsICrashService::PROCESS_TYPE_GMPLUGIN;
      telemetryKey.AssignLiteral("gmplugin");
      break;
    case GeckoProcessType_GPU:
      processType = nsICrashService::PROCESS_TYPE_GPU;
      telemetryKey.AssignLiteral("gpu");
      break;
    default:
      NS_ERROR("unknown process type");
      return;
  }

  nsCOMPtr<nsISupports> promise;
  crashService->AddCrash(processType, crashType, aChildDumpID, getter_AddRefs(promise));
  Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1);
}