void
nsColorPicker::Done(GtkWidget* color_chooser, gint response)
{
  switch (response) {
    case GTK_RESPONSE_OK:
    case GTK_RESPONSE_ACCEPT:
      ReadValueFromColorChooser(color_chooser);
      break;
    case GTK_RESPONSE_CANCEL:
    case GTK_RESPONSE_CLOSE:
    case GTK_RESPONSE_DELETE_EVENT:
      break;
    default:
      NS_WARNING("Unexpected response");
      break;
  }

  // A "response" signal won't be sent again but "destroy" will be.
  g_signal_handlers_disconnect_by_func(color_chooser,
                                       FuncToGpointer(OnDestroy), this);

  gtk_widget_destroy(color_chooser);
  if (mCallback) {
    mCallback->Done(mColor);
    mCallback = nullptr;
  }

  NS_RELEASE_THIS();
}
示例#2
0
void
MediaQueryList::AddListener(MediaQueryListListener& aListener)
{
  if (!HasListeners()) {
    // When we have listeners, the pres context owns a reference to
    // this.  This is a cyclic reference that can only be broken by
    // cycle collection.
    NS_ADDREF_THIS();
  }

  if (!mMatchesValid) {
    MOZ_ASSERT(!HasListeners(),
               "when listeners present, must keep mMatches current");
    RecomputeMatches();
  }

  for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
    if (aListener == *mCallbacks[i]) {
      // Already registered
      return;
    }
  }

  if (!mCallbacks.AppendElement(&aListener, fallible)) {
    if (!HasListeners()) {
      // Append failed; undo the AddRef above.
      NS_RELEASE_THIS();
    }
  }
}
void
nsXMLPrettyPrinter::EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType)
{
    mUpdateDepth--;

    // Only remove the binding once we're outside all updates. This protects us
    // from nasty surprices of elements being removed from the document in the
    // midst of setting attributes etc.
    if (mUnhookPending && mUpdateDepth == 0) {
        mDocument->RemoveObserver(this);
        nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(mDocument);
        nsCOMPtr<nsIDOMElement> rootElem;
        document->GetDocumentElement(getter_AddRefs(rootElem));

        if (rootElem) {
            nsCOMPtr<nsIDOMDocumentXBL> xblDoc = do_QueryInterface(mDocument);
            xblDoc->RemoveBinding(rootElem,
                                  NS_LITERAL_STRING("chrome://global/content/xml/XMLPrettyPrint.xml#prettyprint"));
        }

        mDocument = nsnull;

        NS_RELEASE_THIS();
    }
}
示例#4
0
//-------------------------------------------------------------------------
//
// Send a resize message to the listener
//
//-------------------------------------------------------------------------
PRBool nsWidget::OnResize( nsRect &aRect ) {

    PRBool result = PR_FALSE;

    // call the event callback
    if( mEventCallback ) {
        nsSizeEvent event(PR_TRUE, 0, nsnull);

        InitEvent(event, NS_SIZE);

        nsRect *foo = new nsRect(0, 0, aRect.width, aRect.height);
        event.windowSize = foo;

        event.point.x = 0;
        event.point.y = 0;
        event.mWinWidth = aRect.width;
        event.mWinHeight = aRect.height;

        NS_ADDREF_THIS();
        result = DispatchWindowEvent(&event);
        NS_RELEASE_THIS();
        delete foo;
    }

    return result;
}
NS_IMETHODIMP
sbRemoteNotificationManager::Notify(nsITimer* aTimer)
{
  TRACE(("sbRemoteNotificationManager[0x%.8x] - Notify", this));

  NS_ENSURE_ARG_POINTER(aTimer);

  nsresult rv;

  if (mCancelPending) {
    nsRefPtr<sbRemoteNotificationManager> kungFuDeathGrip(this);
    nsresult rv, rv2;
    // clear the status bar text
    mCurrentActionType = eNone;
    rv = UpdateStatus();

    // and clear the timer (regardless of if the status bar was cleared)
    // keep the return value so we always return the worst one
    rv2 = mTimer->Cancel();
    mTimer = nsnull;

    // kung fu death grip, matched in Notify. without this the manager goes
    // away before the timer and deadlocks - bug7970
    NS_RELEASE_THIS();

    NS_ENSURE_SUCCESS(rv, rv);
    return rv2;
  }

  PRTime now = PR_Now();

  // If we're currently showing a message, check to see if it has been up
  // long enough
  if (mCurrentActionType > eNone) {
    if (now > mPriorityList[mCurrentActionType].mDisplayUntilTime) {
      mPriorityList[mCurrentActionType].mDisplayUntilTime = 0;
    }
    else {
      // The current message still has time left, do nothing
      return NS_OK;
    }
  }

  // Is there another message waiting to be displayed?  If so, bump the
  // display until time, update status message and return
  for (ActionType i = eDownload; i <= eEditedPlaylist; i = ActionType(i + 1)) {
    if (mPriorityList[i].mDisplayUntilTime > 0) {
      mCurrentActionType = i;
      mPriorityList[i].mDisplayUntilTime = now + MAX_NOTIFICATION_TIME;
      rv = UpdateStatus();
      NS_ENSURE_SUCCESS(rv, rv);

      return NS_OK;
    }
  }

  // If we get here, there are no messages to display, so cancel the timer.
  return Cancel();
}
示例#6
0
NS_IMETHODIMP
nsOfflineCachePendingUpdate::OnStateChange(nsIWebProgress* aWebProgress,
                                           nsIRequest *aRequest,
                                           PRUint32 progressStateFlags,
                                           nsresult aStatus)
{
    nsCOMPtr<nsIDOMDocument> updateDoc = do_QueryReferent(mDocument);
    if (!updateDoc) {
        // The document that scheduled this update has gone away,
        // we don't need to listen anymore.
        aWebProgress->RemoveProgressListener(this);
        NS_RELEASE_THIS();
        return NS_OK;
    }

    if (!(progressStateFlags & STATE_STOP)) {
        return NS_OK;
    }

    nsCOMPtr<nsIDOMWindow> window;
    aWebProgress->GetDOMWindow(getter_AddRefs(window));
    if (!window) return NS_OK;

    nsCOMPtr<nsIDOMDocument> progressDoc;
    window->GetDocument(getter_AddRefs(progressDoc));
    if (!progressDoc) return NS_OK;

    if (!SameCOMIdentity(progressDoc, updateDoc)) {
        return NS_OK;
    }

    LOG(("nsOfflineCachePendingUpdate::OnStateChange [%p, doc=%p]",
         this, progressDoc.get()));

    // Only schedule the update if the document loaded successfully
    if (NS_SUCCEEDED(aStatus)) {
        nsCOMPtr<nsIOfflineCacheUpdate> update;
        mService->Schedule(mManifestURI, mDocumentURI,
                           updateDoc, window, getter_AddRefs(update));
    }

    aWebProgress->RemoveProgressListener(this);
    NS_RELEASE_THIS();

    return NS_OK;
}
示例#7
0
void
MediaQueryList::RemoveAllListeners()
{
  bool hadListeners = HasListeners();
  mCallbacks.Clear();
  if (hadListeners) {
    // See NS_ADDREF_THIS() in AddListener.
    NS_RELEASE_THIS();
  }
}
示例#8
0
void
MediaQueryList::RemoveListener(MediaQueryListListener& aListener)
{
  for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
    if (aListener == *mCallbacks[i]) {
      mCallbacks.RemoveElementAt(i);
      if (!HasListeners()) {
        // See NS_ADDREF_THIS() in AddListener.
        NS_RELEASE_THIS();
      }
      break;
    }
  }
}
示例#9
0
void nsXPInstallManager::Shutdown(PRInt32 status)
{
    if (mDlg)
    {
        // tell the dialog it can go away
        mDlg->OnStateChange(0, nsIXPIProgressDialog::DIALOG_CLOSE, 0 );
        mDlg = nsnull;
    }

    if (mNeedsShutdown)
    {
        mNeedsShutdown = PR_FALSE;

        // Send remaining status notifications if we were cancelled early
        nsXPITriggerItem* item;
        while ( mNextItem < mTriggers->Size() )
        {
            item = (nsXPITriggerItem*)mTriggers->Get(mNextItem++);
            if ( item && !item->mURL.IsEmpty() )
            {
                mTriggers->SendStatus( item->mURL.get(), status );
            }
        }

        // Clean up downloaded files (regular install only, not chrome installs)
        for (PRUint32 i = 0; i < mTriggers->Size(); i++ )
        {
            item = static_cast<nsXPITriggerItem*>(mTriggers->Get(i));
            if ( item && item->mFile && !item->IsFileURL() )
                item->mFile->Remove(PR_FALSE);
        }

        nsCOMPtr<nsIObserverService> os =
          mozilla::services::GetObserverService();
        if (os)
        {
            os->RemoveObserver(this, NS_IOSERVICE_GOING_OFFLINE_TOPIC);
            os->RemoveObserver(this, "quit-application");
        }

        if (mTriggers)
        {
            delete mTriggers;
            mTriggers = nsnull;
        }

        NS_RELEASE_THIS();
    }
}
示例#10
0
NS_IMETHODIMP
nsXPInstallManager::InitManager(nsIDOMWindowInternal* aParentWindow, nsXPITriggerInfo* aTriggers, PRUint32 aChromeType)
{
    if ( !aTriggers || aTriggers->Size() == 0 )
    {
        NS_WARNING("XPInstallManager called with no trigger info!");
        delete aTriggers;
        NS_RELEASE_THIS();
        return NS_ERROR_INVALID_POINTER;
    }

    nsresult rv = NS_OK;

    mNeedsShutdown = PR_TRUE;
    mTriggers = aTriggers;
    mChromeType = aChromeType;

    mParentWindow = aParentWindow;

    // Attempt to find a load group, continue if we can't find one though
    if (aParentWindow) {
        nsCOMPtr<nsIDOMDocument> domdoc;
        rv = aParentWindow->GetDocument(getter_AddRefs(domdoc));
        if (NS_SUCCEEDED(rv) && domdoc) {
            nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
            if (doc)
                mLoadGroup = doc->GetDocumentLoadGroup();
        }
    }

    // Start downloading initial chunks looking for signatures,
    mOutstandingCertLoads = mTriggers->Size();

    nsXPITriggerItem *item = mTriggers->Get(--mOutstandingCertLoads);

    nsCOMPtr<nsIURI> uri;
    NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(item->mURL));
    nsCOMPtr<nsIStreamListener> listener = new CertReader(uri, nsnull, this);
    if (listener)
        rv = NS_OpenURI(listener, nsnull, uri, nsnull, mLoadGroup);
    else
        rv = NS_ERROR_OUT_OF_MEMORY;

    if (NS_FAILED(rv)) {
        Shutdown();
    }
    return rv;
}
示例#11
0
NS_IMETHODIMP
nsIOThreadPool::PostEvent(PLEvent *event)
{
    LOG(("nsIOThreadPool::PostEvent [event=%p]\n", event));

    nsAutoLock lock(mLock);

    // if we are shutting down, then prevent additional events from being
    // added to the queue...
    if (mShutdown)
        return NS_ERROR_UNEXPECTED;
    
    nsresult rv = NS_OK;

    PR_APPEND_LINK(&event->link, &mEventQ);

    // now, look for an available idle thread...
    if (mNumIdleThreads)
        PR_NotifyCondVar(mIdleThreadCV); // wake up an idle thread

    // or, try to create a new thread unless we have reached our maximum...
    else if (mNumThreads < MAX_THREADS) {
        NS_ADDREF_THIS(); // the thread owns a reference to us
        mNumThreads++;
        PRThread *thread = PR_CreateThread(PR_USER_THREAD,
                                           ThreadFunc,
                                           this,
                                           PR_PRIORITY_NORMAL,
                                           PR_GLOBAL_THREAD,
                                           PR_UNJOINABLE_THREAD,
                                           0);
        if (!thread) {
            NS_RELEASE_THIS();
            mNumThreads--;
            rv = NS_ERROR_OUT_OF_MEMORY;
        }
    }
    // else, we expect one of the active threads to process the event queue.

    return rv;
}
示例#12
0
void
nsDNSAsyncRequest::OnLookupComplete(nsHostResolver *resolver,
                                    nsHostRecord   *hostRecord,
                                    nsresult        status)
{
    // need to have an owning ref when we issue the callback to enable
    // the caller to be able to addref/release multiple times without
    // destroying the record prematurely.
    nsCOMPtr<nsIDNSRecord> rec;
    if (NS_SUCCEEDED(status)) {
        NS_ASSERTION(hostRecord, "no host record");
        rec = new nsDNSRecord(hostRecord);
        if (!rec)
            status = NS_ERROR_OUT_OF_MEMORY;
    }

    mListener->OnLookupComplete(this, rec, status);
    mListener = nsnull;

    // release the reference to ourselves that was added before we were
    // handed off to the host resolver.
    NS_RELEASE_THIS();
}
示例#13
0
NS_IMETHODIMP
PendingPACQuery::OnLookupComplete(nsICancelable *request,
                                  nsIDNSRecord *record,
                                  nsresult status)
{
  // NOTE: we don't care about the results of this DNS query.  We issued
  //       this DNS query just to pre-populate our DNS cache.
 
  mDNSRequest = nsnull;  // break reference cycle

  // If we've already completed this query then do nothing.
  if (!mCallback)
    return NS_OK;

  // We're no longer pending, so we can remove ourselves.
  PR_REMOVE_LINK(this);
  NS_RELEASE_THIS();

  nsCAutoString pacString;
  status = mPACMan->GetProxyForURI(mURI, pacString);
  Complete(status, pacString);
  return NS_OK;
}
示例#14
0
// nsIBaseWindow
NS_IMETHODIMP nsWebShellWindow::Destroy()
{
  nsresult rv;
  nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
  if (webProgress) {
    webProgress->RemoveProgressListener(this);
  }

  nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
  if (mSPTimerLock) {
  PR_Lock(mSPTimerLock);
  if (mSPTimer) {
    mSPTimer->Cancel();
    SavePersistentAttributes();
    mSPTimer = nsnull;
    NS_RELEASE_THIS(); // the timer held a reference to us
  }
  PR_Unlock(mSPTimerLock);
  PR_DestroyLock(mSPTimerLock);
  mSPTimerLock = nsnull;
  }
  return nsXULWindow::Destroy();
}
示例#15
0
NS_IMETHODIMP
nsXPInstallManager::InitManager(nsIDOMWindowInternal* aParentWindow, nsXPITriggerInfo* aTriggers, PRUint32 aChromeType)
{
    if ( !aTriggers || aTriggers->Size() == 0 )
    {
        NS_WARNING("XPInstallManager called with no trigger info!");
        delete aTriggers;
        NS_RELEASE_THIS();
        return NS_ERROR_INVALID_POINTER;
    }

    nsresult rv = NS_OK;

    mNeedsShutdown = PR_TRUE;
    mTriggers = aTriggers;
    mChromeType = aChromeType;

    mParentWindow = aParentWindow;

    // Start downloading initial chunks looking for signatures,
    mOutstandingCertLoads = mTriggers->Size();

    nsXPITriggerItem *item = mTriggers->Get(--mOutstandingCertLoads);

    nsCOMPtr<nsIURI> uri;
    NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(item->mURL));
    nsCOMPtr<nsIStreamListener> listener = new CertReader(uri, nsnull, this);
    if (listener)
        rv = NS_OpenURI(listener, nsnull, uri);
    else
        rv = NS_ERROR_OUT_OF_MEMORY;

    if (NS_FAILED(rv)) {
        Shutdown();
    }
    return rv;
}
示例#16
0
NS_IMETHODIMP
nsXPInstallManager::InitManagerWithInstallInfo(nsIXPIInstallInfo* aInstallInfo)
{
    nsXPITriggerInfo* triggers;
    nsresult rv = aInstallInfo->GetTriggerInfo(&triggers);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMWindowInternal> win;
    rv = aInstallInfo->GetOriginatingWindow(getter_AddRefs(win));
    if (NS_SUCCEEDED(rv))
    {
        PRUint32 type;
        rv = aInstallInfo->GetChromeType(&type);
        if (NS_SUCCEEDED(rv))
        {
            // Passing ownership onto InitManager which will free when necessary
            aInstallInfo->SetTriggerInfo(nsnull);
            return InitManager(win, triggers, type);
        }
    }

    NS_RELEASE_THIS();
    return rv;
}
示例#17
0
nsresult
nsDownloadScanner::Scan::Run()
{
  NS_ASSERTION(NS_IsMainThread(), "Antivirus scan dispatch should be run on the main thread");

  // Cleanup our thread
  if (mStatus != AVSCAN_TIMEDOUT)
    WaitForSingleObject(mThread, INFINITE);
  CloseHandle(mThread);

  DownloadState downloadState = 0;
  EnterCriticalSection(&mStateSync);
  switch (mStatus) {
    case AVSCAN_BAD:
      downloadState = nsIDownloadManager::DOWNLOAD_DIRTY;
      break;
    default:
    case AVSCAN_FAILED:
    case AVSCAN_GOOD:
    case AVSCAN_UGLY:
    case AVSCAN_TIMEDOUT:
      downloadState = nsIDownloadManager::DOWNLOAD_FINISHED;
      break;
  }
  LeaveCriticalSection(&mStateSync);
  // Download will be null if we already timed out
  if (mDownload)
    (void)mDownload->SetState(downloadState);

  // Clean up some other variables
  // In the event of a timeout, our destructor won't be called
  mDownload = nsnull;

  NS_RELEASE_THIS();
  return NS_OK;
}
示例#18
0
void
nsColorPicker::Done(GtkWidget* color_chooser, gint response)
{
  switch (response) {
    case GTK_RESPONSE_OK:
    case GTK_RESPONSE_ACCEPT:
#if defined(ACTIVATE_GTK3_COLOR_PICKER) && GTK_CHECK_VERSION(3,4,0)
      GdkRGBA color;
      gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(color_chooser), &color);
      SetColor(&color);
#else
      ReadValueFromColorSelection(WidgetGetColorSelection(color_chooser));
#endif
      break;
    case GTK_RESPONSE_CANCEL:
    case GTK_RESPONSE_CLOSE:
    case GTK_RESPONSE_DELETE_EVENT:
      mColor = mInitialColor;
      break;
    default:
      NS_WARNING("Unexpected response");
      break;
  }

  // A "response" signal won't be sent again but "destroy" will be.
  g_signal_handlers_disconnect_by_func(color_chooser,
                                       FuncToGpointer(OnDestroy), this);

  gtk_widget_destroy(color_chooser);
  if (mCallback) {
    mCallback->Done(mColor);
    mCallback = nullptr;
  }

  NS_RELEASE_THIS();
}
nsresult
nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason)
{
  nsresult rv = NS_ERROR_FAILURE;

  // Various bits of code in the rest of this method may result in the
  // deletion of this object. Use a KungFuDeathGrip to keep ourselves
  // alive during cleanup.
  nsRefPtr<nsNPAPIPluginStreamListener> kungFuDeathGrip(this);

  if (mStreamCleanedUp)
    return NS_OK;
  
  mStreamCleanedUp = true;
  
  StopDataPump();

  // Release any outstanding redirect callback.
  if (mHTTPRedirectCallback) {
    mHTTPRedirectCallback->OnRedirectVerifyCallback(NS_ERROR_FAILURE);
    mHTTPRedirectCallback = nullptr;
  }

  // Seekable streams have an extra addref when they are created which must
  // be matched here.
  if (NP_SEEK == mStreamType && mStreamStarted)
    NS_RELEASE_THIS();

  if (mStreamListenerPeer) {
    mStreamListenerPeer->CancelRequests(NS_BINDING_ABORTED);
    mStreamListenerPeer = nullptr;
  }

  if (!mInst || !mInst->CanFireNotifications())
    return rv;
  
  PluginDestructionGuard guard(mInst);

  nsNPAPIPlugin* plugin = mInst->GetPlugin();
  if (!plugin || !plugin->GetLibrary())
    return rv;

  NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();

  NPP npp;
  mInst->GetNPP(&npp);

  if (mStreamStarted && pluginFunctions->destroystream) {
    NPPAutoPusher nppPusher(npp);

    NPError error;
    NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroystream)(npp, &mNPStreamWrapper->mNPStream, reason), mInst,
                            NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
    
    NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
                   ("NPP DestroyStream called: this=%p, npp=%p, reason=%d, return=%d, url=%s\n",
                    this, npp, reason, error, mNPStreamWrapper->mNPStream.url));
    
    if (error == NPERR_NO_ERROR)
      rv = NS_OK;
  }
  
  mStreamStarted = false;
  
  // fire notification back to plugin, just like before
  CallURLNotify(reason);
  
  return rv;
}
void
nsXMLPrettyPrinter::NodeWillBeDestroyed(const nsINode* aNode)
{
    mDocument = nsnull;
    NS_RELEASE_THIS();
}
示例#21
0
nsresult
nsMenuListener::KeyPress(nsIDOMEvent* aKeyEvent)
{
  // Don't check prevent default flag -- menus always get first shot at key events.
  // When a menu is open, the prevent default flag on a keypress is always set, so
  // that no one else uses the key event.

  //handlers shouldn't be triggered by non-trusted events.
  nsCOMPtr<nsIDOMNSEvent> domNSEvent = do_QueryInterface(aKeyEvent);
  PRBool trustedEvent = PR_FALSE;

  if (domNSEvent) {
    domNSEvent->GetIsTrusted(&trustedEvent);
  }

  if (!trustedEvent)
    return NS_OK;

  nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
  PRUint32 theChar;
	keyEvent->GetKeyCode(&theChar);
  PRBool handled = PR_FALSE;

  if (theChar == NS_VK_LEFT ||
      theChar == NS_VK_RIGHT ||
      theChar == NS_VK_UP ||
      theChar == NS_VK_DOWN ||
      theChar == NS_VK_HOME ||
      theChar == NS_VK_END) {
    // The navigation keys were pressed. User is moving around within
    // the menus.
	  mMenuParent->KeyboardNavigation(theChar, handled);
  }
  else if (theChar == NS_VK_ESCAPE) {
    // Close one level.
    // Prevents us from getting destroyed by Escape(), we need to return to ourselves
    NS_ADDREF_THIS();
	  mMenuParent->Escape(handled);
    NS_RELEASE_THIS();
    if (!handled)
      mMenuParent->DismissChain();
  }
  else if (theChar == NS_VK_TAB)
    mMenuParent->DismissChain();
  else if (theChar == NS_VK_ENTER ||
           theChar == NS_VK_RETURN) {
    // Open one level.
    mMenuParent->Enter();
  }
#if !defined(XP_MAC) && !defined(XP_MACOSX)
  else if (theChar == NS_VK_F10) {
    // doesn't matter what modifier keys are down in Non-Mac platform
    // if the menu bar is active and F10 is pressed - deactivate it
    mMenuParent->DismissChain();
  }
#endif // !XP_MAC && !XP_MACOSX
  else {
    PRInt32 menuAccessKey = -1;
    nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
    if (menuAccessKey) {
      // Do shortcut navigation.
      // A letter was pressed. We want to see if a shortcut gets matched. If
      // so, we'll know the menu got activated.
      keyEvent->GetCharCode(&theChar);
      mMenuParent->ShortcutNavigation(keyEvent, handled);
    }
  }

  aKeyEvent->StopPropagation();
  aKeyEvent->PreventDefault();
  return NS_ERROR_BASE; // I am consuming event
}
void
DOMBindingBase::_finalize(JSFreeOp* aFop)
{
  ClearWrapper();
  NS_RELEASE_THIS();
}
示例#23
0
nsresult ReleaseDispatcher::Run() {
  NS_ASSERTION(NS_IsMainThread(), "Antivirus scan release dispatch should be run on the main thread");
  NS_RELEASE(mPtr);
  NS_RELEASE_THIS();
  return NS_OK;
}