action_pipe.h revision 49fdf1889b965be25f929eeebc5b60cd40b9043
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
549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#ifndef UPDATE_ENGINE_PIPE_H__
649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#define UPDATE_ENGINE_PIPE_H__
749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h>
949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <iostream>
1049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <map>
1149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string>
1249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <tr1/memory>
1349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <glog/logging.h>
1449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "base/basictypes.h"
1549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// The structure of these classes (Action, ActionPipe, ActionProcessor, etc.)
1749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// is based on the KSAction* classes from the Google Update Engine code at
1849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// http://code.google.com/p/update-engine/ . The author of this file sends
1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// a big thanks to that team for their high quality design, implementation,
2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// and documentation.
2149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// This class serves as a temporary holding area for an object passed out
2349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// from one Action and into another Action. It's templated so that it may
2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// contain any type of object that an Action outputs/inputs. Actions
2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// cannot be bonded (i.e., connected with a pipe) if their output/input
2649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// object types differ (a compiler error will result).
2749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com//
2849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// An ActionPipe is generally created with the Bond() method and owned by
2949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// the two Action objects. a shared_ptr is used so that when the last Action
3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// pointing to an ActionPipe dies, the ActionPipe dies, too.
3149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::map;
3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::string;
3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::tr1::shared_ptr;
3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
3749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Used by Actions an InputObjectType or OutputObjectType to specify that
3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// for that type, no object is taken/given.
4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass NoneType {};
4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename T>
4349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass Action;
4449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename ObjectType>
4649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionPipe {
4749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
4849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual ~ActionPipe() {
4949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    LOG(INFO) << "ActionPipe died";
5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
5149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // This should be called by an Action on its input pipe.
5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Returns a reference to the stored object.
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  const ObjectType& contents() const { return contents_; }
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // This should be called by an Action on its output pipe.
5749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Stores a copy of the passed object in this pipe.
5849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void set_contents(const ObjectType& contents) { contents_ = contents; }
5949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Bonds two Actions together with a new ActionPipe. The ActionPipe is
6149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // jointly owned by the two Actions and will be automatically destroyed
6249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // when the last Action is destroyed.
6349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  template<typename FromAction, typename ToAction>
6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  static void Bond(FromAction* from, ToAction* to) {
6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    shared_ptr<ActionPipe<ObjectType> > pipe(new ActionPipe<ObjectType>);
6649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    from->set_out_pipe(pipe);
6749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    to->set_in_pipe(pipe);  // If you get an error on this line, then
6949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    // it most likely means that the From object's OutputObjectType is
7049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    // different from the To object's InputObjectType.
7149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
7249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private:
7449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ObjectType contents_;
7549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
7649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // The ctor is private. This is because this class should construct itself
7749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // via the static Bond() method.
7849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ActionPipe() {}
7949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  DISALLOW_COPY_AND_ASSIGN(ActionPipe);
8049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
8149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Utility function
8349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<typename FromAction, typename ToAction>
8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comvoid BondActions(FromAction* from, ToAction* to) {
8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // TODO(adlr): find something like this that the compiler accepts:
8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // COMPILE_ASSERT(typeof(typename FromAction::OutputObjectType) ==
8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  //                typeof(typename ToAction::InputObjectType),
8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  //     FromAction_OutputObjectType_doesnt_match_ToAction_InputObjectType);
8949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ActionPipe<typename FromAction::OutputObjectType>::Bond(from, to);
9049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
9149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
9249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
9349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
9449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#endif  // UPDATE_ENGINE_PIPE_H__
95