1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2011 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_COMMON_ACTION_PROCESSOR_H_ 1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_ACTION_PROCESSOR_H_ 1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <deque> 2149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 2205735a1879a553153458aae0a25fa5d42e3e408fBen Chan#include <base/macros.h> 2314fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo#include <brillo/errors/error.h> 2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 2539910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/error_code.h" 26a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen 2749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// The structure of these classes (Action, ActionPipe, ActionProcessor, etc.) 2849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// is based on the KSAction* classes from the Google Update Engine code at 2949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// http://code.google.com/p/update-engine/ . The author of this file sends 3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// a big thanks to that team for their high quality design, implementation, 3149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// and documentation. 3249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 33072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko// See action.h for an overview of this class and other Action* classes. 3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// An ActionProcessor keeps a queue of Actions and processes them in order. 3649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine { 3849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass AbstractAction; 4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionProcessorDelegate; 4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionProcessor { 4349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public: 4414fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo ActionProcessor() = default; 4549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 46f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov virtual ~ActionProcessor(); 4749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 4849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Starts processing the first Action in the queue. If there's a delegate, 4949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // when all processing is complete, ProcessingDone() will be called on the 5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // delegate. 51f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov virtual void StartProcessing(); 5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Aborts processing. If an Action is running, it will have 54f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo // TerminateProcessing() called on it. The Action that was running and all the 55f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo // remaining actions will be lost and must be re-enqueued if this Processor is 56f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo // to use it. 5749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com void StopProcessing(); 5849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5914fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // Suspend the processing. If an Action is running, it will have the 6014fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // SuspendProcessing() called on it, and it should suspend operations until 6114fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // ResumeProcessing() is called on this class to continue. While suspended, 6214fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // no new actions will be started. Calling SuspendProcessing while the 6314fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // processing is suspended or not running this method performs no action. 6414fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo void SuspendProcessing(); 6514fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo 6614fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // Resume the suspended processing. If the ActionProcessor is not suspended 67f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo // or not running in the first place this method performs no action. 6814fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo void ResumeProcessing(); 6914fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo 7014fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // Returns true iff the processing was started but not yet completed nor 7114fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // stopped. 7214fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo bool IsRunning() const { return current_action_ != nullptr || suspended_; } 7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 7449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Adds another Action to the end of the queue. 75f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov virtual void EnqueueAction(AbstractAction* action); 7649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 7788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko // Sets/gets the current delegate. Set to null to remove a delegate. 78f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov ActionProcessorDelegate* delegate() const { return delegate_; } 7949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com void set_delegate(ActionProcessorDelegate *delegate) { 8049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com delegate_ = delegate; 8149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com } 8249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 8349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Returns a pointer to the current Action that's processing. 8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com AbstractAction* current_action() const { 8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com return current_action_; 8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com } 8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Called by an action to notify processor that it's done. Caller passes self. 89a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen void ActionComplete(AbstractAction* actionptr, ErrorCode code); 9049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 9149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private: 9214fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // Continue processing actions (if any) after the last action terminated with 9314fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // the passed error code. If there are no more actions to process, the 9414fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // processing will terminate. 9514fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo void StartNextActionOrFinish(ErrorCode code); 9614fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo 9749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Actions that have not yet begun processing, in the order in which 9849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // they'll be processed. 9949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com std::deque<AbstractAction*> actions_; 10049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 101072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko // A pointer to the currently processing Action, if any. 10214fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo AbstractAction* current_action_{nullptr}; 10314fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo 10414fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // The ErrorCode reported by an action that was suspended but finished while 10514fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // being suspended. This error code is stored here to be reported back to the 10614fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // delegate once the processor is resumed. 10714fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo ErrorCode suspended_error_code_{ErrorCode::kSuccess}; 10814fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo 10914fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo // Whether the action processor is or should be suspended. 11014fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo bool suspended_{false}; 11149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 11288b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko // A pointer to the delegate, or null if none. 11314fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo ActionProcessorDelegate* delegate_{nullptr}; 11414fd1ec41d1da4e849b724b762ca111a30c6628cAlex Deymo 11549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com DISALLOW_COPY_AND_ASSIGN(ActionProcessor); 11649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}; 11749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 11849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// A delegate object can be used to be notified of events that happen 11949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// in an ActionProcessor. An instance of this class can be passed to an 12049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// ActionProcessor to register itself. 12149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionProcessorDelegate { 12249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public: 123e89487039d0eca8130d822cabf75a729609509e0Alex Deymo virtual ~ActionProcessorDelegate() = default; 124e89487039d0eca8130d822cabf75a729609509e0Alex Deymo 12549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Called when all processing in an ActionProcessor has completed. A pointer 126c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov // to the ActionProcessor is passed. |code| is set to the exit code of the 127c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov // last completed action. 128c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov virtual void ProcessingDone(const ActionProcessor* processor, 129a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen ErrorCode code) {} 13049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 13149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Called when processing has stopped. Does not mean that all Actions have 13249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // completed. If/when all Actions complete, ProcessingDone() will be called. 13349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com virtual void ProcessingStopped(const ActionProcessor* processor) {} 13449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 13549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Called whenever an action has finished processing, either successfully 13649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // or otherwise. 137c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com virtual void ActionCompleted(ActionProcessor* processor, 138c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com AbstractAction* action, 139a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen ErrorCode code) {} 14049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}; 14149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 14249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 14349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 14439910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif // UPDATE_ENGINE_COMMON_ACTION_PROCESSOR_H_ 145