<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h"

#include "base/debug/trace_event.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"

using content::BrowserThread;

namespace chromeos {
namespace file_system_provider {
namespace {

// Dicards the callback from CloseFile().
void EmptyStatusCallback(base::File::Error /* result */) {
}

}  // namespace

class FileStreamWriter::OperationRunner
    : public base::RefCountedThreadSafe<FileStreamWriter::OperationRunner> {
 public:
  OperationRunner() : file_handle_(-1) {}

  // Opens a file for writing and calls the completion callback. Must be called
  // on UI thread.
  void OpenFileOnUIThread(
      const storage::FileSystemURL& url,
      const storage::AsyncFileUtil::StatusCallback& callback) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    util::FileSystemURLParser parser(url);
    if (!parser.Parse()) {
      BrowserThread::PostTask(
          BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::File::FILE_ERROR_SECURITY));
      return;
    }

    file_system_ = parser.file_system()->GetWeakPtr();
    abort_callback_ = parser.file_system()->OpenFile(
        parser.file_path(),
        ProvidedFileSystemInterface::OPEN_FILE_MODE_WRITE,
        base::Bind(
            &OperationRunner::OnOpenFileCompletedOnUIThread, this, callback));
  }

  // Closes a file. Ignores result, since outlives the caller. Must be called on
  // UI thread.
  void CloseFileOnUIThread() {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    if (file_system_.get() && file_handle_ != -1) {
      // Closing a file must not be aborted, since we could end up on files
      // which are never closed.
      file_system_->CloseFile(file_handle_, base::Bind(&EmptyStatusCallback));
      abort_callback_ = ProvidedFileSystemInterface::AbortCallback();
    }
  }

  // Requests writing bytes to the file. In case of either success or a failure
  // |callback| is executed. Must be called on UI thread.
  void WriteFileOnUIThread(
      scoped_refptr<net::IOBuffer> buffer,
      int64 offset,
      int length,
      const storage::AsyncFileUtil::StatusCallback& callback) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    // If the file system got unmounted, then abort the writing operation.
    if (!file_system_.get()) {
      BrowserThread::PostTask(
          BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::File::FILE_ERROR_ABORT));
      return;
    }

    abort_callback_ = file_system_->WriteFile(
        file_handle_,
        buffer,
        offset,
        length,
        base::Bind(
            &OperationRunner::OnWriteFileCompletedOnUIThread, this, callback));
  }<commit_msg>[fsp] Fix aborting in File Stream Writer.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h"

#include "base/debug/trace_event.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"

using content::BrowserThread;

namespace chromeos {
namespace file_system_provider {
namespace {

// Dicards the callback from CloseFile().
void EmptyStatusCallback(base::File::Error /* result */) {
}

}  // namespace

class FileStreamWriter::OperationRunner
    : public base::RefCountedThreadSafe<FileStreamWriter::OperationRunner> {
 public:
  OperationRunner() : file_handle_(-1) {}

  // Opens a file for writing and calls the completion callback. Must be called
  // on UI thread.
  void OpenFileOnUIThread(
      const storage::FileSystemURL& url,
      const storage::AsyncFileUtil::StatusCallback& callback) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    util::FileSystemURLParser parser(url);
    if (!parser.Parse()) {
      BrowserThread::PostTask(
          BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::File::FILE_ERROR_SECURITY));
      return;
    }

    file_system_ = parser.file_system()->GetWeakPtr();
    abort_callback_ = parser.file_system()->OpenFile(
        parser.file_path(),
        ProvidedFileSystemInterface::OPEN_FILE_MODE_WRITE,
        base::Bind(
            &OperationRunner::OnOpenFileCompletedOnUIThread, this, callback));
  }

  // Closes a file. Ignores result, since outlives the caller. Must be called on
  // UI thread.
  void CloseFileOnUIThread() {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    if (file_system_.get() && file_handle_ != -1) {
      // Closing a file must not be aborted, since we could end up on files
      // which are never closed.
      file_system_->CloseFile(file_handle_, base::Bind(&EmptyStatusCallback));
    }
  }

  // Requests writing bytes to the file. In case of either success or a failure
  // |callback| is executed. Must be called on UI thread.
  void WriteFileOnUIThread(
      scoped_refptr<net::IOBuffer> buffer,
      int64 offset,
      int length,
      const storage::AsyncFileUtil::StatusCallback& callback) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    // If the file system got unmounted, then abort the writing operation.
    if (!file_system_.get()) {
      BrowserThread::PostTask(
          BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::File::FILE_ERROR_ABORT));
      return;
    }

    abort_callback_ = file_system_->WriteFile(
        file_handle_,
        buffer,
        offset,
        length,
        base::Bind(
            &OperationRunner::OnWriteFileCompletedOnUIThread, this, callback));
  }
{'fraction_non_alphanumeric': 0.10588779284833538, 'fraction_numerical': 0.002466091245376079, 'mean_word_length': 3.6851985559566787, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5014242', 'n_tokens_mistral': 1948, 'n_tokens_neox': 1892, 'n_words': 448}