diff options
Diffstat (limited to 'tools/gn/input_file_manager.h')
-rw-r--r-- | tools/gn/input_file_manager.h | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/tools/gn/input_file_manager.h b/tools/gn/input_file_manager.h new file mode 100644 index 0000000..0f708d5 --- /dev/null +++ b/tools/gn/input_file_manager.h @@ -0,0 +1,123 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TOOLS_GN_INPUT_FILE_MANAGER_H_ +#define TOOLS_GN_INPUT_FILE_MANAGER_H_ + +#include <set> +#include <utility> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/containers/hash_tables.h" +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "base/synchronization/waitable_event.h" +#include "tools/gn/build_settings.h" +#include "tools/gn/input_file.h" +#include "tools/gn/parse_tree.h" +#include "tools/gn/settings.h" + +class Err; +class LocationRange; +class ParseNode; +class Token; + +// Manages loading and parsing files from disk. This doesn't actually have +// any context for executing the results, so potentially multiple configs +// could use the same input file (saving parsing). +// +// This class is threadsafe. +// +// InputFile objects must never be deleted while the program is running since +// various state points into them. +class InputFileManager : public base::RefCountedThreadSafe<InputFileManager> { + public: + // Callback issued when a file is laoded. On auccess, the parse node will + // refer to the root block of the file. On failure, this will be NULL. + typedef base::Callback<void(const ParseNode*)> FileLoadCallback; + + InputFileManager(); + + // Loads the given file and executes the callback on the worker pool. + // + // There are two types of errors. For errors known synchronously, the error + // will be set, it will return false, and no work will be scheduled. + // + // For parse errors and such that happen in the future, the error will be + // logged to the scheduler and the callback will be invoked with a null + // ParseNode pointer. The given |origin| will be blamed for the invocation. + bool AsyncLoadFile(const LocationRange& origin, + const BuildSettings* build_settings, + const SourceFile& file_name, + const FileLoadCallback& callback, + Err* err); + + // Loads and parses the given file synchronously, returning the root block + // corresponding to the parsed result. On error, return NULL and the given + // Err is set. + const ParseNode* SyncLoadFile(const LocationRange& origin, + const BuildSettings* build_settings, + const SourceFile& file_name, + Err* err); + + int GetInputFileCount() const; + + void GetAllInputFileNames(std::vector<SourceFile>* result) const; + + private: + friend class base::RefCountedThreadSafe<InputFileManager>; + + struct InputFileData { + InputFileData(const SourceFile& file_name); + ~InputFileData(); + + // Don't touch this outside the lock until it's marked loaded. + InputFile file; + + bool loaded; + + bool sync_invocation; + + // Lists all invocations that need to be executed when the file completes + // loading. + std::vector<FileLoadCallback> scheduled_callbacks; + + // Event to signal when the load is complete (or fails). This is lazily + // created only when a thread is synchronously waiting for this load (which + // only happens for imports). + scoped_ptr<base::WaitableEvent> completion_event; + + std::vector<Token> tokens; + + // Null before the file is loaded or if loading failed. + scoped_ptr<ParseNode> parsed_root; + }; + + virtual ~InputFileManager(); + + void BackgroundLoadFile(const LocationRange& origin, + const BuildSettings* build_settings, + const SourceFile& name, + InputFile* file); + + // Loads the given file. On error, sets the Err and return false. + bool LoadFile(const LocationRange& origin, + const BuildSettings* build_settings, + const SourceFile& name, + InputFile* file, + Err* err); + + mutable base::Lock lock_; + + // Maps repo-relative filenames to the corresponding owned pointer. + typedef base::hash_map<SourceFile, InputFileData*> InputFileMap; + InputFileMap input_files_; + + DISALLOW_COPY_AND_ASSIGN(InputFileManager); +}; + +#endif // TOOLS_GN_INPUT_FILE_MANAGER_H_ |