예제 #1
0
FileSystemTaskParentBase::~FileSystemTaskParentBase()
{
  // This task can be released on different threads because we dispatch it (as
  // runnable) to main-thread, I/O and then back to the PBackground thread.
  NS_ProxyRelease(mBackgroundEventTarget, mFileSystem.forget());
  NS_ProxyRelease(mBackgroundEventTarget, mRequestParent.forget());
}
AsyncConnectionHelper::~AsyncConnectionHelper()
{
  if (!NS_IsMainThread()) {
    IDBDatabase* database;
    mDatabase.forget(&database);

    IDBTransaction* transaction;
    mTransaction.forget(&transaction);

    nsCOMPtr<nsIThread> mainThread;
    NS_GetMainThread(getter_AddRefs(mainThread));
    NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");

    if (mainThread) {
      if (database) {
        NS_ProxyRelease(mainThread, static_cast<nsIIDBDatabase*>(database));
      }
      if (transaction) {
        NS_ProxyRelease(mainThread,
                        static_cast<nsIIDBTransaction*>(transaction));
      }
    }
  }

  NS_ASSERTION(!mOldProgressHandler, "Should not have anything here!");
}
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");
}
nsInterfaceRequestorAgg::~nsInterfaceRequestorAgg()
{
  nsIInterfaceRequestor* iir = nullptr;
  mFirst.swap(iir);
  if (iir) {
    NS_ProxyRelease(mConsumerTarget, iir);
  }
  iir = nullptr;
  mSecond.swap(iir);
  if (iir) {
    NS_ProxyRelease(mConsumerTarget, iir);
  }
}
예제 #5
0
NS_IMETHODIMP
nsStreamListenerTee::OnStopRequest(nsIRequest *request,
                                   nsISupports *context,
                                   nsresult status)
{
    NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
    // it is critical that we close out the input stream tee
    if (mInputTee) {
        mInputTee->SetSink(nullptr);
        mInputTee = 0;
    }

    // release sink on the same thread where the data was written (bug 716293)
    if (mEventTarget) {
        nsIOutputStream *sink = nullptr;
        mSink.swap(sink);
        NS_ProxyRelease(mEventTarget, sink);
    }
    else {
        mSink = 0;
    }

    nsresult rv = mListener->OnStopRequest(request, context, status);
    if (mObserver)
        mObserver->OnStopRequest(request, context, status);
    mObserver = 0;
    return rv;
}
예제 #6
0
void
nsServerSocket::OnSocketDetached(PRFileDesc *fd)
{
  // force a failure condition if none set; maybe the STS is shutting down :-/
  if (NS_SUCCEEDED(mCondition))
    mCondition = NS_ERROR_ABORT;

  if (mFD)
  {
    NS_ASSERTION(mFD == fd, "wrong file descriptor");
    PR_Close(mFD);
    mFD = nullptr;
  }

  if (mListener)
  {
    mListener->OnStopListening(this, mCondition);

    // need to atomically clear mListener.  see our Close() method.
    RefPtr<nsIServerSocketListener> listener = nullptr;
    {
      MutexAutoLock lock(mLock);
      listener = mListener.forget();
    }

    // XXX we need to proxy the release to the listener's target thread to work
    // around bug 337492.
    if (listener) {
      NS_ProxyRelease(mListenerTarget, listener.forget());
    }
  }
}
예제 #7
0
void
PeerConnectionMedia::RemoveTransportFlow(int aIndex, bool aRtcp)
{
  int index_inner = GetTransportFlowIndex(aIndex, aRtcp);
  NS_ProxyRelease(
    "PeerConnectionMedia::mTransportFlows",
    GetSTSThread(), mTransportFlows[index_inner].forget());
}
예제 #8
0
void
PeerConnectionMedia::RemoveTransportFlow(int aIndex, bool aRtcp)
{
  int index_inner = GetTransportFlowIndex(aIndex, aRtcp);
  TransportFlow* flow = mTransportFlows[index_inner].forget().take();
  if (flow) {
    NS_ProxyRelease(GetSTSThread(), flow);
  }
}
예제 #9
0
NullHttpTransaction::~NullHttpTransaction()
{
  if (mCallbacks) {
    nsIInterfaceRequestor *cbs = nsnull;
    mCallbacks.swap(cbs);
    NS_ProxyRelease(mEventTarget, cbs);
  }
  delete mRequestHead;
}
예제 #10
0
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");
}
예제 #11
0
 ~nsUrlClassifierCallbackWrapper()
 {
   nsCOMPtr<nsIEventQueue> mainEventQ;
   NS_GetMainEventQ(getter_AddRefs(mainEventQ));
   if (mainEventQ) {
     NS_ProxyRelease(mainEventQ, mInner);
   } else {
     NS_WARNING("unable to get main event queue");
   }
 }
SpeechStreamListener::~SpeechStreamListener()
{
  nsCOMPtr<nsIThread> mainThread;
  NS_GetMainThread(getter_AddRefs(mainThread));

  SpeechRecognition* forgottenRecognition = nullptr;
  mRecognition.swap(forgottenRecognition);
  NS_ProxyRelease(mainThread,
                  static_cast<DOMEventTargetHelper*>(forgottenRecognition));
}
예제 #13
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);
     }
 }
예제 #14
0
DocGroup::~DocGroup()
{
  MOZ_ASSERT(mDocuments.IsEmpty());
  if (!NS_IsMainThread()) {
    nsIEventTarget* target = EventTargetFor(TaskCategory::Other);
    NS_ProxyRelease(target, mReactionsStack.forget());
  }

  mTabGroup->mDocGroups.RemoveEntry(mKey);
}
예제 #15
0
void
nsFileCopyEvent::DoCopy()
{
  // We'll copy in chunks this large by default.  This size affects how
  // frequently we'll check for interrupts.
  const int32_t chunk = nsIOService::gDefaultSegmentSize * nsIOService::gDefaultSegmentCount;

  nsresult rv = NS_OK;

  int64_t len = mLen, progress = 0;
  while (len) {
    // If we've been interrupted, then stop copying.
    rv = mInterruptStatus;
    if (NS_FAILED(rv))
      break;

    int32_t num = std::min((int32_t) len, chunk);

    uint32_t result;
    rv = mSource->ReadSegments(NS_CopySegmentToStream, mDest, num, &result);
    if (NS_FAILED(rv))
      break;
    if (result != (uint32_t) num) {
      rv = NS_ERROR_FILE_DISK_FULL;  // stopped prematurely (out of disk space)
      break;
    }

    // Dispatch progress notification
    if (mSink) {
      progress += num;
      mSink->OnTransportStatus(nullptr, NS_NET_STATUS_WRITING, progress,
                               mLen);
    }
                               
    len -= num;
  }

  if (NS_FAILED(rv))
    mStatus = rv;

  // Close the output stream before notifying our callback so that others may
  // freely "play" with the file.
  mDest->Close();

  // Notify completion
  if (mCallback) {
    mCallbackTarget->Dispatch(mCallback, NS_DISPATCH_NORMAL);

    // Release the callback on the target thread to avoid destroying stuff on
    // the wrong thread.
    nsIRunnable *doomed = nullptr;
    mCallback.swap(doomed);
    NS_ProxyRelease(mCallbackTarget, doomed);
  }
}
  NS_IMETHOD Run()
  {
    if (mStatement->mAsyncStatement) {
      sqlite3_finalize(mStatement->mAsyncStatement);
      mStatement->mAsyncStatement = nullptr;
    }

    nsCOMPtr<nsIThread> targetThread(mConnection->threadOpenedOn);
    NS_ProxyRelease(targetThread, mStatement.forget());
    return NS_OK;
  }
예제 #17
0
nsWyciwygChannel::~nsWyciwygChannel()
{
    if (mLoadInfo) {
        nsCOMPtr<nsIThread> mainThread;
        NS_GetMainThread(getter_AddRefs(mainThread));

        nsILoadInfo *forgetableLoadInfo;
        mLoadInfo.forget(&forgetableLoadInfo);
        NS_ProxyRelease(mainThread, forgetableLoadInfo, false);
    }
}
nsRequestObserverProxy::~nsRequestObserverProxy()
{
    if (mObserver) {
        // order is crucial here... we must be careful to clear mObserver
        // before posting the proxy release event.  otherwise, we'd risk
        // releasing the object on this thread.
        nsIRequestObserver *obs = nsnull;
        mObserver.swap(obs);
        NS_ProxyRelease(mTarget, obs);
    }
}
예제 #19
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());
}
예제 #20
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);
  }
}
예제 #21
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;
}
HelperBase::~HelperBase()
{
  if (!NS_IsMainThread()) {
    IDBRequest* request;
    mRequest.forget(&request);

    if (request) {
      nsCOMPtr<nsIThread> mainThread;
      NS_GetMainThread(getter_AddRefs(mainThread));
      NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");

      if (mainThread) {
        NS_ProxyRelease(mainThread, static_cast<nsIDOMEventTarget*>(request));
      }
    }
  }
}
예제 #23
0
/**
 * 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;
}
예제 #24
0
  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;
  }
예제 #25
0
void
Service::unregisterConnection(Connection *aConnection)
{
  // If this is the last Connection it might be the only thing keeping Service
  // alive.  So ensure that Service is destroyed only after the Connection is
  // cleanly unregistered and destroyed.
  RefPtr<Service> kungFuDeathGrip(this);
  RefPtr<Connection> forgettingRef;
  {
    mRegistrationMutex.AssertNotCurrentThreadOwns();
    MutexAutoLock mutex(mRegistrationMutex);

    for (uint32_t i = 0 ; i < mConnections.Length(); ++i) {
      if (mConnections[i] == aConnection) {
        // Because dropping the final reference can potentially result in
        // spinning a nested event loop if the connection was not properly
        // shutdown, we want to do that outside this loop so that we can finish
        // mutating the array and drop our mutex.
        forgettingRef = mConnections[i].forget();
        mConnections.RemoveElementAt(i);
        break;
      }
    }
  }

  MOZ_ASSERT(forgettingRef,
             "Attempt to unregister unknown storage connection!");

  // Ensure the connection is released on its opening thread.  We explicitly use
  // aAlwaysDispatch=false because at the time of writing this, LocalStorage's
  // StorageDBThread uses a hand-rolled PRThread implementation that cannot
  // handle us dispatching events at it during shutdown.  However, it is
  // arguably also desirable for callers to not be aware of our connection
  // tracking mechanism.  And by synchronously dropping the reference (when
  // on the correct thread), this avoids surprises for the caller and weird
  // shutdown edge cases.
  nsCOMPtr<nsIThread> thread = forgettingRef->threadOpenedOn;
  NS_ProxyRelease(
    "storage::Service::mConnections", thread, forgettingRef.forget(), false);
}
예제 #26
0
nsInterfaceRequestorAgg::~nsInterfaceRequestorAgg()
{
  NS_ProxyRelease(mConsumerTarget, mFirst.forget());
  NS_ProxyRelease(mConsumerTarget, mSecond.forget());
}
  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;
  }
ServiceWorkerCloneData::~ServiceWorkerCloneData() {
  RefPtr<ipc::SharedJSAllocatedData> sharedData = TakeSharedData();
  if (sharedData) {
    NS_ProxyRelease(__func__, mEventTarget, sharedData.forget());
  }
}