1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2009 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_PIPE_H_
1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_ACTION_PIPE_H_
1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h>
21bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo
2249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <map>
23bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo#include <memory>
2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string>
25bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo
26bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo#include <base/logging.h>
2705735a1879a553153458aae0a25fa5d42e3e408fBen Chan#include <base/macros.h>
2849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// The structure of these classes (Action, ActionPipe, ActionProcessor, etc.)
3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// is based on the KSAction* classes from the Google Update Engine code at
3149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// http://code.google.com/p/update-engine/ . The author of this file sends
3249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// a big thanks to that team for their high quality design, implementation,
3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// and documentation.
3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// This class serves as a temporary holding area for an object passed out
3649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// from one Action and into another Action. It's templated so that it may
3749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// contain any type of object that an Action outputs/inputs. Actions
3849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// cannot be bonded (i.e., connected with a pipe) if their output/input
3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// object types differ (a compiler error will result).
4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com//
4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// An ActionPipe is generally created with the Bond() method and owned by
4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// the two Action objects. a shared_ptr is used so that when the last Action
4349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// pointing to an ActionPipe dies, the ActionPipe dies, too.
4449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
4649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Used by Actions an InputObjectType or OutputObjectType to specify that
4849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// for that type, no object is taken/given.
4949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass NoneType {};
5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename T>
5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass Action;
5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename ObjectType>
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionPipe {
5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
57fbb40098314ab45efa60667ad7ccae354c4f18daDarin Petkov  virtual ~ActionPipe() {}
5849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // This should be called by an Action on its input pipe.
6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Returns a reference to the stored object.
6149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  const ObjectType& contents() const { return contents_; }
6249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // This should be called by an Action on its output pipe.
6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Stores a copy of the passed object in this pipe.
6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void set_contents(const ObjectType& contents) { contents_ = contents; }
6649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Bonds two Actions together with a new ActionPipe. The ActionPipe is
6849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // jointly owned by the two Actions and will be automatically destroyed
6949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // when the last Action is destroyed.
7049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  template<typename FromAction, typename ToAction>
7149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  static void Bond(FromAction* from, ToAction* to) {
72f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan    std::shared_ptr<ActionPipe<ObjectType>> pipe(new ActionPipe<ObjectType>);
7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    from->set_out_pipe(pipe);
7449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
7549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    to->set_in_pipe(pipe);  // If you get an error on this line, then
7649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    // it most likely means that the From object's OutputObjectType is
7749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    // different from the To object's InputObjectType.
7849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
7949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private:
8149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ObjectType contents_;
8249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // The ctor is private. This is because this class should construct itself
8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // via the static Bond() method.
8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ActionPipe() {}
8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  DISALLOW_COPY_AND_ASSIGN(ActionPipe);
8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Utility function
9049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename FromAction, typename ToAction>
9149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comvoid BondActions(FromAction* from, ToAction* to) {
92a3cf75a1d01aeb03d2341600ebff3db0a8316200Alex Vakulenko  static_assert(
93a3cf75a1d01aeb03d2341600ebff3db0a8316200Alex Vakulenko      std::is_same<typename FromAction::OutputObjectType,
94a3cf75a1d01aeb03d2341600ebff3db0a8316200Alex Vakulenko                   typename ToAction::InputObjectType>::value,
95a3cf75a1d01aeb03d2341600ebff3db0a8316200Alex Vakulenko      "FromAction::OutputObjectType doesn't match ToAction::InputObjectType");
9649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ActionPipe<typename FromAction::OutputObjectType>::Bond(from, to);
9749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
9849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
9949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
10049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
10139910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_COMMON_ACTION_PIPE_H_
102