action.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //
  2. // Copyright (C) 2009 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #ifndef UPDATE_ENGINE_COMMON_ACTION_H_
  17. #define UPDATE_ENGINE_COMMON_ACTION_H_
  18. #include <stdio.h>
  19. #include <memory>
  20. #include <string>
  21. #include <base/logging.h>
  22. #include <base/macros.h>
  23. #include "update_engine/common/action_pipe.h"
  24. #include "update_engine/common/action_processor.h"
  25. // The structure of these classes (Action, ActionPipe, ActionProcessor, etc.)
  26. // is based on the KSAction* classes from the Google Update Engine code at
  27. // http://code.google.com/p/update-engine/ . The author of this file sends
  28. // a big thanks to that team for their high quality design, implementation,
  29. // and documentation.
  30. //
  31. // Readers may want to consult this wiki page from the Update Engine site:
  32. // http://code.google.com/p/update-engine/wiki/ActionProcessor
  33. // Although it's referring to the Objective-C KSAction* classes, much
  34. // applies here as well.
  35. //
  36. // How it works:
  37. //
  38. // First off, there is only one thread and all I/O should be asynchronous.
  39. // A message loop blocks whenever there is no work to be done. This happens
  40. // where there is no CPU work to be done and no I/O ready to transfer in or
  41. // out. Two kinds of events can wake up the message loop: timer alarm or file
  42. // descriptors. If either of these happens, the message loop finds out the owner
  43. // of what fired and calls the appropriate code to handle it. As such, all the
  44. // code in the Action* classes and the code that is calls is non-blocking.
  45. //
  46. // An ActionProcessor contains a queue of Actions to perform. When
  47. // ActionProcessor::StartProcessing() is called, it executes the first action.
  48. // Each action tells the processor when it has completed, which causes the
  49. // Processor to execute the next action. ActionProcessor may have a delegate
  50. // (an object of type ActionProcessorDelegate). If it does, the delegate
  51. // is called to be notified of events as they happen.
  52. //
  53. // ActionPipe classes
  54. //
  55. // See action_pipe.h
  56. //
  57. // ActionTraits
  58. //
  59. // We need to use an extra class ActionTraits. ActionTraits is a simple
  60. // templated class that contains only two typedefs: OutputObjectType and
  61. // InputObjectType. Each action class also has two typedefs of the same name
  62. // that are of the same type. So, to get the input/output types of, e.g., the
  63. // DownloadAction class, we look at the type of
  64. // DownloadAction::InputObjectType.
  65. //
  66. // Each concrete Action class derives from Action<T>. This means that during
  67. // template instantiation of Action<T>, T is declared but not defined, which
  68. // means that T::InputObjectType (and OutputObjectType) is not defined.
  69. // However, the traits class is constructed in such a way that it will be
  70. // template instantiated first, so Action<T> *can* find the types it needs by
  71. // consulting ActionTraits<T>::InputObjectType (and OutputObjectType).
  72. // This is why the ActionTraits classes are needed.
  73. namespace chromeos_update_engine {
  74. // It is handy to have a non-templated base class of all Actions.
  75. class AbstractAction {
  76. public:
  77. AbstractAction() : processor_(nullptr) {}
  78. virtual ~AbstractAction() = default;
  79. // Begin performing the action. Since this code is asynchronous, when this
  80. // method returns, it means only that the action has started, not necessarily
  81. // completed. However, it's acceptable for this method to perform the
  82. // action synchronously; Action authors should understand the implications
  83. // of synchronously performing, though, because this is a single-threaded
  84. // app, the entire process will be blocked while the action performs.
  85. //
  86. // When the action is complete, it must call
  87. // ActionProcessor::ActionComplete(this); to notify the processor that it's
  88. // done.
  89. virtual void PerformAction() = 0;
  90. // Called on ActionProcess::ActionComplete() by ActionProcessor.
  91. virtual void ActionCompleted(ErrorCode code) {}
  92. // Called by the ActionProcessor to tell this Action which processor
  93. // it belongs to.
  94. void SetProcessor(ActionProcessor* processor) {
  95. if (processor)
  96. CHECK(!processor_);
  97. else
  98. CHECK(processor_);
  99. processor_ = processor;
  100. }
  101. // Returns true iff the action is the current action of its ActionProcessor.
  102. bool IsRunning() const {
  103. if (!processor_)
  104. return false;
  105. return processor_->current_action() == this;
  106. }
  107. // Called on asynchronous actions if canceled. Actions may implement if
  108. // there's any cleanup to do. There is no need to call
  109. // ActionProcessor::ActionComplete() because the processor knows this
  110. // action is terminating.
  111. // Only the ActionProcessor should call this.
  112. virtual void TerminateProcessing() {}
  113. // Called on asynchronous actions if the processing is suspended and resumed,
  114. // respectively. These methods are called by the ActionProcessor and should
  115. // not be explicitly called.
  116. // The action may still call ActionCompleted() once the action is completed
  117. // while the processing is suspended, for example if suspend/resume is not
  118. // implemented for the given action.
  119. virtual void SuspendAction() {}
  120. virtual void ResumeAction() {}
  121. // These methods are useful for debugging. TODO(adlr): consider using
  122. // std::type_info for this?
  123. // Type() returns a string of the Action type. I.e., for DownloadAction,
  124. // Type() would return "DownloadAction".
  125. virtual std::string Type() const = 0;
  126. protected:
  127. // A weak pointer to the processor that owns this Action.
  128. ActionProcessor* processor_;
  129. };
  130. // Forward declare a couple classes we use.
  131. template <typename T>
  132. class ActionPipe;
  133. template <typename T>
  134. class ActionTraits;
  135. template <typename SubClass>
  136. class Action : public AbstractAction {
  137. public:
  138. ~Action() override {}
  139. // Attaches an input pipe to this Action. This is optional; an Action
  140. // doesn't need to have an input pipe. The input pipe must be of the type
  141. // of object that this class expects.
  142. // This is generally called by ActionPipe::Bond()
  143. void set_in_pipe(
  144. // this type is a fancy way of saying: a shared_ptr to an
  145. // ActionPipe<InputObjectType>.
  146. const std::shared_ptr<
  147. ActionPipe<typename ActionTraits<SubClass>::InputObjectType>>&
  148. in_pipe) {
  149. in_pipe_ = in_pipe;
  150. }
  151. // Attaches an output pipe to this Action. This is optional; an Action
  152. // doesn't need to have an output pipe. The output pipe must be of the type
  153. // of object that this class expects.
  154. // This is generally called by ActionPipe::Bond()
  155. void set_out_pipe(
  156. // this type is a fancy way of saying: a shared_ptr to an
  157. // ActionPipe<OutputObjectType>.
  158. const std::shared_ptr<
  159. ActionPipe<typename ActionTraits<SubClass>::OutputObjectType>>&
  160. out_pipe) {
  161. out_pipe_ = out_pipe;
  162. }
  163. // Returns true iff there is an associated input pipe. If there's an input
  164. // pipe, there's an input object, but it may have been constructed with the
  165. // default ctor if the previous action didn't call SetOutputObject().
  166. bool HasInputObject() const { return in_pipe_.get(); }
  167. // returns a const reference to the object in the input pipe.
  168. const typename ActionTraits<SubClass>::InputObjectType& GetInputObject()
  169. const {
  170. CHECK(HasInputObject());
  171. return in_pipe_->contents();
  172. }
  173. // Returns true iff there's an output pipe.
  174. bool HasOutputPipe() const { return out_pipe_.get(); }
  175. // Copies the object passed into the output pipe. It will be accessible to
  176. // the next Action via that action's input pipe (which is the same as this
  177. // Action's output pipe).
  178. void SetOutputObject(
  179. const typename ActionTraits<SubClass>::OutputObjectType& out_obj) {
  180. CHECK(HasOutputPipe());
  181. out_pipe_->set_contents(out_obj);
  182. }
  183. // Returns a reference to the object sitting in the output pipe.
  184. const typename ActionTraits<SubClass>::OutputObjectType& GetOutputObject() {
  185. CHECK(HasOutputPipe());
  186. return out_pipe_->contents();
  187. }
  188. protected:
  189. // We use a shared_ptr to the pipe. shared_ptr objects destroy what they
  190. // point to when the last such shared_ptr object dies. We consider the
  191. // Actions on either end of a pipe to "own" the pipe. When the last Action
  192. // of the two dies, the ActionPipe will die, too.
  193. std::shared_ptr<ActionPipe<typename ActionTraits<SubClass>::InputObjectType>>
  194. in_pipe_;
  195. std::shared_ptr<ActionPipe<typename ActionTraits<SubClass>::OutputObjectType>>
  196. out_pipe_;
  197. };
  198. }; // namespace chromeos_update_engine
  199. #endif // UPDATE_ENGINE_COMMON_ACTION_H_