action_pipe.h revision bc91a2743fd3ffabb3ead3181ad8da3060afe1f1
149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Use of this source code is governed by a BSD-style license that can be
349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// found in the LICENSE file.
449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5759c275760b51defcfe5545abb887ad2616335f4Alex Deymo#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_ACTION_PIPE_H_
6759c275760b51defcfe5545abb887ad2616335f4Alex Deymo#define CHROMEOS_PLATFORM_UPDATE_ENGINE_ACTION_PIPE_H_
749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h>
9bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo
1049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <iostream>
1149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <map>
12bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo#include <memory>
1349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string>
14bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo
15bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo#include <base/basictypes.h>
16bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo#include <base/logging.h>
1749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// The structure of these classes (Action, ActionPipe, ActionProcessor, etc.)
1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// is based on the KSAction* classes from the Google Update Engine code at
2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// http://code.google.com/p/update-engine/ . The author of this file sends
2149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// a big thanks to that team for their high quality design, implementation,
2249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// and documentation.
2349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// This class serves as a temporary holding area for an object passed out
2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// from one Action and into another Action. It's templated so that it may
2649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// contain any type of object that an Action outputs/inputs. Actions
2749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// cannot be bonded (i.e., connected with a pipe) if their output/input
2849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// object types differ (a compiler error will result).
2949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com//
3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// An ActionPipe is generally created with the Bond() method and owned by
3149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// the two Action objects. a shared_ptr is used so that when the last Action
3249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// pointing to an ActionPipe dies, the ActionPipe dies, too.
3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Used by Actions an InputObjectType or OutputObjectType to specify that
3749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// for that type, no object is taken/given.
3849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass NoneType {};
3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename T>
4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass Action;
4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename ObjectType>
4449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionPipe {
4549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
46fbb40098314ab45efa60667ad7ccae354c4f18daDarin Petkov  virtual ~ActionPipe() {}
4749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // This should be called by an Action on its input pipe.
4949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Returns a reference to the stored object.
5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  const ObjectType& contents() const { return contents_; }
5149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // This should be called by an Action on its output pipe.
5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Stores a copy of the passed object in this pipe.
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void set_contents(const ObjectType& contents) { contents_ = contents; }
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Bonds two Actions together with a new ActionPipe. The ActionPipe is
5749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // jointly owned by the two Actions and will be automatically destroyed
5849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // when the last Action is destroyed.
5949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  template<typename FromAction, typename ToAction>
6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  static void Bond(FromAction* from, ToAction* to) {
61bc91a2743fd3ffabb3ead3181ad8da3060afe1f1Alex Deymo    std::shared_ptr<ActionPipe<ObjectType> > pipe(
624fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes        new ActionPipe<ObjectType>);
6349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    from->set_out_pipe(pipe);
6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    to->set_in_pipe(pipe);  // If you get an error on this line, then
6649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    // it most likely means that the From object's OutputObjectType is
6749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    // different from the To object's InputObjectType.
6849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
6949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
7049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private:
7149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ObjectType contents_;
7249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // The ctor is private. This is because this class should construct itself
7449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // via the static Bond() method.
7549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ActionPipe() {}
7649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  DISALLOW_COPY_AND_ASSIGN(ActionPipe);
7749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
7849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
7949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Utility function
8049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename FromAction, typename ToAction>
8149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comvoid BondActions(FromAction* from, ToAction* to) {
8249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // TODO(adlr): find something like this that the compiler accepts:
8349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // COMPILE_ASSERT(typeof(typename FromAction::OutputObjectType) ==
8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  //                typeof(typename ToAction::InputObjectType),
8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  //     FromAction_OutputObjectType_doesnt_match_ToAction_InputObjectType);
8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ActionPipe<typename FromAction::OutputObjectType>::Bond(from, to);
8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
9049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
91759c275760b51defcfe5545abb887ad2616335f4Alex Deymo#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_ACTION_PIPE_H_
92