1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_GN_INPUT_FILE_MANAGER_H_ 6 #define TOOLS_GN_INPUT_FILE_MANAGER_H_ 7 8 #include <set> 9 #include <utility> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/callback.h" 14 #include "base/containers/hash_tables.h" 15 #include "base/files/file_path.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/synchronization/lock.h" 18 #include "base/synchronization/waitable_event.h" 19 #include "tools/gn/build_settings.h" 20 #include "tools/gn/input_file.h" 21 #include "tools/gn/parse_tree.h" 22 #include "tools/gn/settings.h" 23 24 class Err; 25 class LocationRange; 26 class ParseNode; 27 class Token; 28 29 // Manages loading and parsing files from disk. This doesn't actually have 30 // any context for executing the results, so potentially multiple configs 31 // could use the same input file (saving parsing). 32 // 33 // This class is threadsafe. 34 // 35 // InputFile objects must never be deleted while the program is running since 36 // various state points into them. 37 class InputFileManager : public base::RefCountedThreadSafe<InputFileManager> { 38 public: 39 // Callback issued when a file is laoded. On auccess, the parse node will 40 // refer to the root block of the file. On failure, this will be NULL. 41 typedef base::Callback<void(const ParseNode*)> FileLoadCallback; 42 43 InputFileManager(); 44 45 // Loads the given file and executes the callback on the worker pool. 46 // 47 // There are two types of errors. For errors known synchronously, the error 48 // will be set, it will return false, and no work will be scheduled. 49 // 50 // For parse errors and such that happen in the future, the error will be 51 // logged to the scheduler and the callback will be invoked with a null 52 // ParseNode pointer. The given |origin| will be blamed for the invocation. 53 bool AsyncLoadFile(const LocationRange& origin, 54 const BuildSettings* build_settings, 55 const SourceFile& file_name, 56 const FileLoadCallback& callback, 57 Err* err); 58 59 // Loads and parses the given file synchronously, returning the root block 60 // corresponding to the parsed result. On error, return NULL and the given 61 // Err is set. 62 const ParseNode* SyncLoadFile(const LocationRange& origin, 63 const BuildSettings* build_settings, 64 const SourceFile& file_name, 65 Err* err); 66 67 int GetInputFileCount() const; 68 69 // Fills the vector with all input files. 70 void GetAllPhysicalInputFileNames(std::vector<base::FilePath>* result) const; 71 72 private: 73 friend class base::RefCountedThreadSafe<InputFileManager>; 74 75 struct InputFileData { 76 InputFileData(const SourceFile& file_name); 77 ~InputFileData(); 78 79 // Don't touch this outside the lock until it's marked loaded. 80 InputFile file; 81 82 bool loaded; 83 84 bool sync_invocation; 85 86 // Lists all invocations that need to be executed when the file completes 87 // loading. 88 std::vector<FileLoadCallback> scheduled_callbacks; 89 90 // Event to signal when the load is complete (or fails). This is lazily 91 // created only when a thread is synchronously waiting for this load (which 92 // only happens for imports). 93 scoped_ptr<base::WaitableEvent> completion_event; 94 95 std::vector<Token> tokens; 96 97 // Null before the file is loaded or if loading failed. 98 scoped_ptr<ParseNode> parsed_root; 99 }; 100 101 virtual ~InputFileManager(); 102 103 void BackgroundLoadFile(const LocationRange& origin, 104 const BuildSettings* build_settings, 105 const SourceFile& name, 106 InputFile* file); 107 108 // Loads the given file. On error, sets the Err and return false. 109 bool LoadFile(const LocationRange& origin, 110 const BuildSettings* build_settings, 111 const SourceFile& name, 112 InputFile* file, 113 Err* err); 114 115 mutable base::Lock lock_; 116 117 // Maps repo-relative filenames to the corresponding owned pointer. 118 typedef base::hash_map<SourceFile, InputFileData*> InputFileMap; 119 InputFileMap input_files_; 120 121 DISALLOW_COPY_AND_ASSIGN(InputFileManager); 122 }; 123 124 #endif // TOOLS_GN_INPUT_FILE_MANAGER_H_ 125