|
19 | 19 | #include <array>
|
20 | 20 | #include <iostream>
|
21 | 21 | #include <memory>
|
| 22 | +#include <mutex> |
| 23 | +#include <stack> |
| 24 | +#include <unordered_set> |
22 | 25 | using namespace nvinfer1;
|
23 | 26 | using namespace nvinfer1::plugin;
|
24 | 27 |
|
@@ -54,47 +57,93 @@ namespace plugin
|
54 | 57 | {
|
55 | 58 | ILogger* gLogger{};
|
56 | 59 |
|
57 |
| -// Instances of this class are statically constructed in initializePlugin. |
58 |
| -// This ensures that each plugin is only registered a single time, as further calls to |
59 |
| -// initializePlugin will be no-ops. |
60 |
| -template <typename CreatorType> |
61 |
| -class InitializePlugin |
| 60 | +// This singleton ensures that each plugin is only registered once for a given |
| 61 | +// namespace and type, and attempts of duplicate registration are ignored. |
| 62 | +class PluginCreatorRegistry |
62 | 63 | {
|
63 | 64 | public:
|
64 |
| - InitializePlugin(void* logger, const char* libNamespace) |
65 |
| - : mCreator{new CreatorType{}} |
| 65 | + static PluginCreatorRegistry& getInstance() |
| 66 | + { |
| 67 | + static PluginCreatorRegistry instance; |
| 68 | + return instance; |
| 69 | + } |
| 70 | + |
| 71 | + template <typename CreatorType> |
| 72 | + void addPluginCreator(void* logger, const char* libNamespace) |
66 | 73 | {
|
67 |
| - mCreator->setPluginNamespace(libNamespace); |
68 |
| - bool status = getPluginRegistry()->registerCreator(*mCreator, libNamespace); |
| 74 | + // Make accesses to the plugin creator registry thread safe |
| 75 | + std::lock_guard<std::mutex> lock(mRegistryLock); |
| 76 | + |
| 77 | + std::string errorMsg; |
| 78 | + std::string verboseMsg; |
| 79 | + |
| 80 | + std::unique_ptr<CreatorType> pluginCreator{new CreatorType{}}; |
| 81 | + pluginCreator->setPluginNamespace(libNamespace); |
| 82 | + |
| 83 | + nvinfer1::plugin::gLogger = static_cast<nvinfer1::ILogger*>(logger); |
| 84 | + std::string pluginType |
| 85 | + = std::string(pluginCreator->getPluginNamespace()) + "::" + std::string(pluginCreator->getPluginName()); |
| 86 | + |
| 87 | + if (mRegistryList.find(pluginType) == mRegistryList.end()) |
| 88 | + { |
| 89 | + bool status = getPluginRegistry()->registerCreator(*pluginCreator, libNamespace); |
| 90 | + if (status) |
| 91 | + { |
| 92 | + mRegistry.push(std::move(pluginCreator)); |
| 93 | + mRegistryList.insert(pluginType); |
| 94 | + verboseMsg = "Plugin creator registration succeeded - " + pluginType; |
| 95 | + } |
| 96 | + else |
| 97 | + { |
| 98 | + errorMsg = "Could not register plugin creator: " + pluginType; |
| 99 | + } |
| 100 | + } |
| 101 | + else |
| 102 | + { |
| 103 | + verboseMsg = "Plugin creator already registered - " + pluginType; |
| 104 | + } |
| 105 | + |
69 | 106 | if (logger)
|
70 | 107 | {
|
71 |
| - nvinfer1::plugin::gLogger = static_cast<nvinfer1::ILogger*>(logger); |
72 |
| - if (!status) |
| 108 | + if (!errorMsg.empty()) |
73 | 109 | {
|
74 |
| - std::string errorMsg{"Could not register plugin creator: " + std::string(mCreator->getPluginName()) |
75 |
| - + " in namespace: " + std::string{mCreator->getPluginNamespace()}}; |
76 | 110 | nvinfer1::plugin::gLogger->log(ILogger::Severity::kERROR, errorMsg.c_str());
|
77 | 111 | }
|
78 |
| - else |
| 112 | + if (!verboseMsg.empty()) |
79 | 113 | {
|
80 |
| - std::string verboseMsg{ |
81 |
| - "Plugin Creator registration succeeded - " + std::string{mCreator->getPluginName()}}; |
82 | 114 | nvinfer1::plugin::gLogger->log(ILogger::Severity::kVERBOSE, verboseMsg.c_str());
|
83 | 115 | }
|
84 | 116 | }
|
85 | 117 | }
|
86 | 118 |
|
87 |
| - InitializePlugin(const InitializePlugin&) = delete; |
88 |
| - InitializePlugin(InitializePlugin&&) = delete; |
| 119 | + ~PluginCreatorRegistry() |
| 120 | + { |
| 121 | + std::lock_guard<std::mutex> lock(mRegistryLock); |
| 122 | + |
| 123 | + // Release pluginCreators in LIFO order of registration. |
| 124 | + while (!mRegistry.empty()) |
| 125 | + { |
| 126 | + mRegistry.pop(); |
| 127 | + } |
| 128 | + mRegistryList.clear(); |
| 129 | + } |
89 | 130 |
|
90 | 131 | private:
|
91 |
| - std::unique_ptr<CreatorType> mCreator; |
| 132 | + PluginCreatorRegistry() {} |
| 133 | + |
| 134 | + std::mutex mRegistryLock; |
| 135 | + std::stack<std::unique_ptr<IPluginCreator>> mRegistry; |
| 136 | + std::unordered_set<std::string> mRegistryList; |
| 137 | + |
| 138 | +public: |
| 139 | + PluginCreatorRegistry(PluginCreatorRegistry const&) = delete; |
| 140 | + void operator=(PluginCreatorRegistry const&) = delete; |
92 | 141 | };
|
93 | 142 |
|
94 | 143 | template <typename CreatorType>
|
95 | 144 | void initializePlugin(void* logger, const char* libNamespace)
|
96 | 145 | {
|
97 |
| - static InitializePlugin<CreatorType> plugin{logger, libNamespace}; |
| 146 | + PluginCreatorRegistry::getInstance().addPluginCreator<CreatorType>(logger, libNamespace); |
98 | 147 | }
|
99 | 148 |
|
100 | 149 | } // namespace plugin
|
|
0 commit comments