190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_SYNCABLE_FILE_OPERATION_RUNNER_H_
62385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_SYNCABLE_FILE_OPERATION_RUNNER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_status.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileSystemURL;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class must run only on IO thread.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Owned by LocalFileSyncContext.
272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochclass SyncableFileOperationRunner
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::NonThreadSafe,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::SupportsWeakPtr<SyncableFileOperationRunner>,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public LocalFileSyncStatus::Observer {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Represents an operation task (which usually wraps one FileSystemOperation).
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Task {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Task() {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Task() {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only one of Run() or Cancel() is called.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void Run() = 0;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void Cancel() = 0;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is never called after Run() or Cancel() is called.
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    virtual const std::vector<storage::FileSystemURL>& target_paths() const = 0;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend class SyncableFileOperationRunner;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool IsRunnable(LocalFileSyncStatus* status) const;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Start(LocalFileSyncStatus* status);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static void CancelAndDelete(Task* task);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(Task);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncableFileOperationRunner(int64 max_inflight_tasks,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LocalFileSyncStatus* sync_status);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SyncableFileOperationRunner();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LocalFileSyncStatus::Observer overrides.
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnSyncEnabled(const storage::FileSystemURL& url) OVERRIDE;
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnWriteEnabled(const storage::FileSystemURL& url) OVERRIDE;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs the given |task| if no sync operation is running on any of
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // its target_paths(). This also runs pending tasks that have become
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runnable (before running the given operation).
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there're ongoing sync tasks on the target_paths this method
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just queues up the |task|.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pending tasks are cancelled when this class is destructed.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PostOperationTask(scoped_ptr<Task> task);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs a next runnable task (if there's any).
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunNextRunnableTask();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when an operation is completed. This will make |target_paths|
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // writable and may start a next runnable task.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnOperationCompleted(
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const std::vector<storage::FileSystemURL>& target_paths);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileSyncStatus* sync_status() const { return sync_status_; }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 num_pending_tasks() const {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<int64>(pending_tasks_.size());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 num_inflight_tasks() const { return num_inflight_tasks_; }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if we should start more tasks.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldStartMoreTasks() const;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keeps track of the writing/syncing status. Not owned.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileSyncStatus* sync_status_;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<Task*> pending_tasks_;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 max_inflight_tasks_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 num_inflight_tasks_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SyncableFileOperationRunner);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_SYNCABLE_FILE_OPERATION_RUNNER_H_
105