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