| Index: filesystem_copier_action.h
|
| diff --git a/filesystem_copier_action.h b/filesystem_copier_action.h
|
| index 6720a47c0c0113dce36c22493a412211a6b2cea5..6dbde413f46346ad9572d7f697d121ab8708244c 100644
|
| --- a/filesystem_copier_action.h
|
| +++ b/filesystem_copier_action.h
|
| @@ -37,14 +37,8 @@ class ActionTraits<FilesystemCopierAction> {
|
|
|
| class FilesystemCopierAction : public Action<FilesystemCopierAction> {
|
| public:
|
| - explicit FilesystemCopierAction(bool copying_kernel_install_path)
|
| - : copying_kernel_install_path_(copying_kernel_install_path),
|
| - src_stream_(NULL),
|
| - dst_stream_(NULL),
|
| - canceller_(NULL),
|
| - read_in_flight_(false),
|
| - buffer_valid_size_(0),
|
| - filesystem_size_(kint64max) {}
|
| + explicit FilesystemCopierAction(bool copying_kernel_install_path);
|
| +
|
| typedef ActionTraits<FilesystemCopierAction>::InputObjectType
|
| InputObjectType;
|
| typedef ActionTraits<FilesystemCopierAction>::OutputObjectType
|
| @@ -53,9 +47,7 @@ class FilesystemCopierAction : public Action<FilesystemCopierAction> {
|
| void TerminateProcessing();
|
|
|
| // Used for testing, so we can copy from somewhere other than root
|
| - void set_copy_source(const std::string& path) {
|
| - copy_source_ = path;
|
| - }
|
| + void set_copy_source(const std::string& path) { copy_source_ = path; }
|
|
|
| // Debugging/logging
|
| static std::string StaticType() { return "FilesystemCopierAction"; }
|
| @@ -65,19 +57,34 @@ class FilesystemCopierAction : public Action<FilesystemCopierAction> {
|
| friend class FilesystemCopierActionTest;
|
| FRIEND_TEST(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest);
|
|
|
| - // Callback from glib when the copy operation is done.
|
| - void AsyncReadyCallback(GObject *source_object, GAsyncResult *res);
|
| - static void StaticAsyncReadyCallback(GObject *source_object,
|
| - GAsyncResult *res,
|
| - gpointer user_data) {
|
| - reinterpret_cast<FilesystemCopierAction*>(user_data)->AsyncReadyCallback(
|
| - source_object, res);
|
| - }
|
| -
|
| - // Cleans up all the variables we use for async operations and tells
|
| - // the ActionProcessor we're done w/ success as passed in.
|
| - // was_cancelled should be true if TerminateProcessing() was called.
|
| - void Cleanup(bool success, bool was_cancelled);
|
| + // Ping-pong buffers generally cycle through the following states:
|
| + // Empty->Reading->Full->Writing->Empty.
|
| + enum BufferState {
|
| + kBufferStateEmpty,
|
| + kBufferStateReading,
|
| + kBufferStateFull,
|
| + kBufferStateWriting
|
| + };
|
| +
|
| + // Callbacks from glib when the read/write operation is done.
|
| + void AsyncReadReadyCallback(GObject *source_object, GAsyncResult *res);
|
| + static void StaticAsyncReadReadyCallback(GObject *source_object,
|
| + GAsyncResult *res,
|
| + gpointer user_data);
|
| +
|
| + void AsyncWriteReadyCallback(GObject *source_object, GAsyncResult *res);
|
| + static void StaticAsyncWriteReadyCallback(GObject *source_object,
|
| + GAsyncResult *res,
|
| + gpointer user_data);
|
| +
|
| + // Based on the state of the ping-pong buffers spawns appropriate read/write
|
| + // actions asynchronously.
|
| + void SpawnAsyncActions();
|
| +
|
| + // Cleans up all the variables we use for async operations and tells the
|
| + // ActionProcessor we're done w/ success as passed in. |cancelled_| should be
|
| + // true if TerminateProcessing() was called.
|
| + void Cleanup(bool success);
|
|
|
| // Determine, if possible, the source file system size to avoid copying the
|
| // whole partition. Currently this supports only the root file system assuming
|
| @@ -101,18 +108,22 @@ class FilesystemCopierAction : public Action<FilesystemCopierAction> {
|
| GInputStream* src_stream_;
|
| GOutputStream* dst_stream_;
|
|
|
| - // If non-NULL, the cancellable object for the in-flight async call.
|
| - GCancellable* canceller_;
|
| + // Ping-pong buffers for storing data we read/write. Only one buffer is being
|
| + // read at a time and only one buffer is being written at a time.
|
| + std::vector<char> buffer_[2];
|
| +
|
| + // The state of each buffer.
|
| + BufferState buffer_state_[2];
|
|
|
| - // True if we're waiting on a read to complete; false if we're
|
| - // waiting on a write.
|
| - bool read_in_flight_;
|
| + // Number of valid elements in |buffer_| if its state is kBufferStateFull.
|
| + std::vector<char>::size_type buffer_valid_size_[2];
|
|
|
| - // The buffer for storing data we read/write.
|
| - std::vector<char> buffer_;
|
| + // The cancellable objects for the in-flight async calls.
|
| + GCancellable* canceller_[2];
|
|
|
| - // Number of valid elements in buffer_.
|
| - std::vector<char>::size_type buffer_valid_size_;
|
| + bool read_done_; // true if reached EOF on the input stream.
|
| + bool failed_; // true if the action has failed.
|
| + bool cancelled_; // true if the action has been cancelled.
|
|
|
| // The install plan we're passed in via the input pipe.
|
| InstallPlan install_plan_;
|
|
|