// Called on the control thread.
NS_IMETHODIMP
BackgroundFileSaver::Finish(nsresult aStatus)
{
  nsresult rv;

  // This will cause the NS_AsyncCopy operation, if it's in progress, to consume
  // all the data that is still in the pipe, and then finish.
  rv = mPipeOutputStream->Close();
  NS_ENSURE_SUCCESS(rv, rv);

  // Ensure that, when we get attention from the worker thread, if no pending
  // rename operation is waiting, the operation will complete.
  {
    MutexAutoLock lock(mLock);
    mFinishRequested = true;
    if (NS_SUCCEEDED(mStatus)) {
      mStatus = aStatus;
    }
  }

  // After the worker thread wakes up because attention is requested, it will
  // process the completion conditions, detect that completion is requested, and
  // notify the main thread of the completion.  If this function was called with
  // a success code, we wait for the copy to finish before processing the
  // completion conditions, otherwise we interrupt the copy immediately.
  return GetWorkerThreadAttention(NS_FAILED(aStatus));
}
// Called on the control thread.
NS_IMETHODIMP
BackgroundFileSaver::SetTarget(nsIFile *aTarget, bool aKeepPartial)
{
  NS_ENSURE_ARG(aTarget);
  {
    MutexAutoLock lock(mLock);
    aTarget->Clone(getter_AddRefs(mAssignedTarget));
    mAssignedTargetKeepPartial = aKeepPartial;
  }

  // After the worker thread wakes up because attention is requested, it will
  // rename or create the target file as requested, and start copying data.
  return GetWorkerThreadAttention(true);
}