Skip to content

Commit

Permalink
DSO search in-process/OOP unification (#1761)
Browse files Browse the repository at this point in the history
Co-authored-by: Pierre Wielders <pierre@wielders.net>
  • Loading branch information
sebaszm and pwielders authored Sep 24, 2024
1 parent 7622fef commit 257d635
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 86 deletions.
80 changes: 44 additions & 36 deletions Source/Thunder/PluginServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,7 @@ namespace PluginHost {
{
ASSERT(_connection == nullptr);

void* result(_administrator.Instantiate(object, waitTime, sessionId, DataPath(), PersistentPath(), VolatilePath()));
void* result(_administrator.Instantiate(object, waitTime, sessionId, DataPath(), PersistentPath(), VolatilePath(), _administrator.Configuration().LinkerPluginPaths()));

if (result != nullptr) {
_connection = _administrator.RemoteConnection(sessionId);
Expand Down Expand Up @@ -1373,54 +1373,54 @@ namespace PluginHost {

RPC::IStringIterator* GetLibrarySearchPaths(const string& locator) const override
{
std::vector<string> all_paths;
const std::vector<string> temp = _administrator.Configuration().LinkerPluginPaths();
string rootPath(PluginHost::Service::Configuration().SystemRootPath.Value());
std::vector<string> searchPaths;

if (rootPath.empty() == false) {
rootPath = Core::Directory::Normalize(rootPath);
}
const string normalized(Core::File::Normalize(locator));
const string rootPath(Core::Directory::Normalize(PluginHost::Service::Configuration().SystemRootPath));

if (!temp.empty())
{
// additionaly defined user paths
for (const string& s : temp) {
if (rootPath.empty() == true) {
all_paths.push_back(Core::Directory::Normalize(s) + locator);
ASSERT_VERBOSE((normalized.empty() == locator.empty()), "path normalization failed");
ASSERT_VERBOSE((rootPath.empty() == PluginHost::Service::Configuration().SystemRootPath.Value().empty()), "path normalization failed");

if (normalized.empty() == false) {
if (Core::File::IsPathAbsolute(locator) == true) {
searchPaths.push_back(Core::File::Normalize(rootPath + normalized));
}
else {
const std::vector<string>& linkerPaths = _administrator.Configuration().LinkerPluginPaths();

if (linkerPaths.empty() == false) {
// override system paths
for (const string& path : linkerPaths) {
searchPaths.push_back(Core::Directory::Normalize(rootPath + path) + normalized);
}
}
else {
all_paths.push_back(rootPath + Core::Directory::Normalize(s) + locator);
// system configured paths
searchPaths.push_back(Core::Directory::Normalize(rootPath + DataPath()) + normalized);
searchPaths.push_back(Core::Directory::Normalize(rootPath + PersistentPath()) + normalized);
searchPaths.push_back(Core::Directory::Normalize(rootPath + SystemPath()) + normalized);
searchPaths.push_back(Core::Directory::Normalize(rootPath + PluginPath()) + normalized);
}
}
}
else if (rootPath.empty() == false)
{
// system configured paths
all_paths.push_back(rootPath + DataPath() + locator);
all_paths.push_back(rootPath + PersistentPath() + locator);
all_paths.push_back(rootPath + SystemPath() + locator);
all_paths.push_back(rootPath + PluginPath() + locator);
}
else {
// system configured paths
all_paths.push_back(DataPath() + locator);
all_paths.push_back(PersistentPath() + locator);
all_paths.push_back(SystemPath() + locator);
all_paths.push_back(PluginPath() + locator);
}

return (Core::ServiceType<RPC::StringIterator>::Create<RPC::IStringIterator>(all_paths));
return (Core::ServiceType<RPC::StringIterator>::Create<RPC::IStringIterator>(searchPaths));
}

Core::Library LoadLibrary(const string& name) {
uint8_t progressedState = 0;
Core::Library result;

RPC::IStringIterator* all_paths = GetLibrarySearchPaths(name);
ASSERT(all_paths != nullptr);

string element;
while((all_paths->Next(element) == true) && (progressedState <= 2)) {

TRACE_L1("attempting to load library %s", element.c_str());

Core::File libraryToLoad(element);

if (libraryToLoad.Exists() == true) {
if (progressedState == 0) {
progressedState = 1;
Expand Down Expand Up @@ -2086,6 +2086,7 @@ namespace PluginHost {
const string& proxyStubPath,
const string& observableProxyStubPath,
const string& postMortemPath,
const std::vector<string>& linkerPaths,
const uint8_t softKillCheckWaitTime,
const uint8_t hardKillCheckWaitTime,
const bool delegatedReleases,
Expand All @@ -2103,6 +2104,7 @@ namespace PluginHost {
#else
, _application(EXPAND_AND_QUOTE(HOSTING_COMPROCESS))
#endif
, _linkerPaths(linkerPaths)
, _adminLock()
, _requestObservers()
, _proxyStubObserver(*this, observableProxyStubPath)
Expand Down Expand Up @@ -2141,9 +2143,9 @@ namespace PluginHost {
}

public:
void* Create(uint32_t& connectionId, const RPC::Object& instance, const uint32_t waitTime, const string& dataPath, const string& persistentPath, const string& volatilePath)
void* Create(uint32_t& connectionId, const RPC::Object& instance, const uint32_t waitTime, const string& dataPath, const string& persistentPath, const string& volatilePath, const std::vector<string>& linkerPaths)
{
return (RPC::Communicator::Create(connectionId, instance, RPC::Config(RPC::Communicator::Connector(), _application, persistentPath, _systemPath, dataPath, volatilePath, _appPath, RPC::Communicator::ProxyStubPath(), _postMortemPath), waitTime));
return (RPC::Communicator::Create(connectionId, instance, RPC::Config(RPC::Communicator::Connector(), _application, persistentPath, _systemPath, dataPath, volatilePath, _appPath, RPC::Communicator::ProxyStubPath(), _postMortemPath, linkerPaths), waitTime));
}
const string& PersistentPath() const
{
Expand Down Expand Up @@ -2177,6 +2179,10 @@ namespace PluginHost {
{
return (_application);
}
const std::vector<string>& LinkerPaths() const
{
return (_linkerPaths);
}
void Register(RPC::IRemoteConnection::INotification* sink)
{
RPC::Communicator::Register(sink);
Expand Down Expand Up @@ -2328,6 +2334,7 @@ namespace PluginHost {
const string _observableProxyStubPath;
const string _postMortemPath;
const string _application;
std::vector<string> _linkerPaths;
mutable Core::CriticalSection _adminLock;
Observers _requestObservers;
ProxyStubObserver _proxyStubObserver;
Expand Down Expand Up @@ -2405,7 +2412,7 @@ namespace PluginHost {
}

uint32_t id;
RPC::Config config(_connector, _comms.Application(), persistentPath, _comms.SystemPath(), dataPath, volatilePath, _comms.AppPath(), _comms.ProxyStubPath(), _comms.PostMortemPath());
RPC::Config config(_connector, _comms.Application(), persistentPath, _comms.SystemPath(), dataPath, volatilePath, _comms.AppPath(), _comms.ProxyStubPath(), _comms.PostMortemPath(), _comms.LinkerPaths());
RPC::Object instance(libraryName, className, callsign, interfaceId, version, user, group, threads, priority, RPC::Object::HostType::LOCAL, systemRootPath, _T(""), configuration);

RPC::Communicator::Process process(requestId, config, instance);
Expand Down Expand Up @@ -2652,6 +2659,7 @@ namespace PluginHost {
server._config.ProxyStubPath(),
server._config.ObservableProxyStubPath(),
server._config.PostMortemPath(),
server._config.LinkerPluginPaths(),
server._config.SoftKillCheckWaitTime(),
server._config.HardKillCheckWaitTime(),
server._config.DelegatedReleases(),
Expand Down Expand Up @@ -2895,9 +2903,9 @@ namespace PluginHost {
return (result);
}

void* Instantiate(const RPC::Object& object, const uint32_t waitTime, uint32_t& sessionId, const string& dataPath, const string& persistentPath, const string& volatilePath)
void* Instantiate(const RPC::Object& object, const uint32_t waitTime, uint32_t& sessionId, const string& dataPath, const string& persistentPath, const string& volatilePath, const std::vector<string>& linkerPaths)
{
return (_processAdministrator.Create(sessionId, object, waitTime, dataPath, persistentPath, volatilePath));
return (_processAdministrator.Create(sessionId, object, waitTime, dataPath, persistentPath, volatilePath, linkerPaths));
}
void Destroy(const uint32_t id) {
_processAdministrator.Destroy(id);
Expand Down
95 changes: 54 additions & 41 deletions Source/ThunderPlugin/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ POP_WARNING()
TRACE_L1("We still have living object [%d].", instances);
}
else {

TRACE_L1("All living objects are killed. Time for HaraKiri!!.");

// Seems there is no more live here, time to signal the
Expand Down Expand Up @@ -130,7 +129,6 @@ POP_WARNING()
}
void Run()
{

Core::WorkerPool::Run();
Core::WorkerPool::Join();
}
Expand Down Expand Up @@ -161,7 +159,7 @@ POP_WARNING()
class ConsoleOptions : public Core::Options {
public:
ConsoleOptions(int argumentCount, TCHAR* arguments[])
: Core::Options(argumentCount, arguments, _T("h:l:c:C:r:p:s:d:a:m:i:u:g:t:e:x:V:v:P:S:"))
: Core::Options(argumentCount, arguments, _T("h:l:c:C:r:p:s:d:a:m:i:u:g:t:e:x:V:v:P:S:f:"))
, Locator(nullptr)
, ClassName(nullptr)
, Callsign(nullptr)
Expand All @@ -180,6 +178,7 @@ POP_WARNING()
, User(nullptr)
, Group(nullptr)
, Threads(1)
, LinkerPaths()
{
Parse();
}
Expand All @@ -206,6 +205,7 @@ POP_WARNING()
const TCHAR* User;
const TCHAR* Group;
uint8_t Threads;
std::vector<string> LinkerPaths;

private:
string Strip(const TCHAR text[]) const
Expand Down Expand Up @@ -236,28 +236,28 @@ POP_WARNING()
RemoteChannel = argument;
break;
case 'p':
PersistentPath = Strip(argument);
PersistentPath = Core::Directory::Normalize(Strip(argument));
break;
case 's':
SystemPath = Strip(argument);
SystemPath = Core::Directory::Normalize(Strip(argument));
break;
case 'd':
DataPath = Strip(argument);
DataPath = Core::Directory::Normalize(Strip(argument));
break;
case 'P':
PostMortemPath = Strip(argument);
PostMortemPath = Core::Directory::Normalize(Strip(argument));
break;
case 'S':
SystemRootPath = Strip(argument);
SystemRootPath = Core::Directory::Normalize(Strip(argument));
break;
case 'v':
VolatilePath = Strip(argument);
VolatilePath = Core::Directory::Normalize(Strip(argument));
break;
case 'a':
AppPath = Strip(argument);
AppPath = Core::Directory::Normalize(Strip(argument));
break;
case 'm':
ProxyStubPath = Strip(argument);
ProxyStubPath = Core::Directory::Normalize(Strip(argument));
break;
case 'u':
User = argument;
Expand All @@ -277,6 +277,9 @@ POP_WARNING()
case 't':
Threads = Core::NumberType<uint8_t>(Core::TextFragment(argument)).Value();
break;
case 'f':
LinkerPaths.push_back(Strip(argument));
break;
case 'h':
default:
RequestUsage(true);
Expand All @@ -285,52 +288,59 @@ POP_WARNING()
}
};

static void* CheckInstance(const string& path, const TCHAR locator[], const TCHAR className[], const uint32_t ID, const uint32_t version)
static void* CheckInstance(const string& path, const ConsoleOptions& options)
{
void* result = nullptr;

if (path.empty() == false) {
Core::ServiceAdministrator& admin(Core::ServiceAdministrator::Instance());

string libraryPath = locator;
if (libraryPath.empty() || (libraryPath[0] != '/')) {
// Relative path, prefix with path name.
string pathName(Core::Directory::Normalize(path));
libraryPath = pathName + locator;
}
TRACE_L1("Attempting to load '%s' from %s...", options.ClassName, path.c_str());

Core::Library library(libraryPath.c_str());
Core::Library library(path.c_str());

if (library.IsLoaded() == true) {
// Instantiate the object
result = admin.Instantiate(library, className, version, ID);
result = Core::ServiceAdministrator::Instance().Instantiate(library, options.ClassName, options.Version, options.InterfaceId);
}
}

return (result);
}

static void* AcquireInterfaces(ConsoleOptions& options)
static void* AcquireInterfaces(const ConsoleOptions& options)
{
void* result = nullptr;

if ((options.Locator != nullptr) && (options.ClassName != nullptr)) {
string path = (!options.SystemRootPath.empty() ? options.SystemRootPath : "") + options.PersistentPath;
result = CheckInstance(path, options.Locator, options.ClassName, options.InterfaceId, options.Version);

if (result == nullptr) {
path = (!options.SystemRootPath.empty() ? options.SystemRootPath : "") + options.SystemPath;
result = CheckInstance(path, options.Locator, options.ClassName, options.InterfaceId, options.Version);
const string rootPath = Core::Directory::Normalize(options.SystemRootPath);

if (Core::File::IsPathAbsolute(options.Locator) == true) {
result = CheckInstance(Core::File::Normalize(rootPath + options.Locator), options);
}
else if (options.LinkerPaths.empty() == false) {
// Linker paths override system paths
for (const string& linkerPath : options.LinkerPaths) {
result = CheckInstance((Core::Directory::Normalize(options.SystemRootPath + linkerPath) + options.Locator), options);

if (result != nullptr) {
break;
}
}
}
else {
// System paths
result = CheckInstance((Core::Directory::Normalize(options.SystemRootPath + options.PersistentPath) + options.Locator), options);

if (result == nullptr) {
path = (!options.SystemRootPath.empty() ? options.SystemRootPath : "") + options.DataPath;
result = CheckInstance(path, options.Locator, options.ClassName, options.InterfaceId, options.Version);
result = CheckInstance((Core::Directory::Normalize(options.SystemRootPath + options.SystemPath) + options.Locator), options);

if (result == nullptr) {
string searchPath(options.AppPath.empty() == false ? Core::Directory::Normalize(options.AppPath) : string());
result = CheckInstance((Core::Directory::Normalize(options.SystemRootPath + options.DataPath) + options.Locator), options);

path = (!options.SystemRootPath.empty() ? options.SystemRootPath : "") + searchPath;
result = CheckInstance((path + _T("Plugins/")), options.Locator, options.ClassName, options.InterfaceId, options.Version);
if (result == nullptr) {
result = CheckInstance((Core::Directory::Normalize(options.SystemRootPath + options.AppPath + _T("Plugins")) + options.Locator), options);
}
}
}
}
Expand Down Expand Up @@ -577,23 +587,26 @@ int main(int argc, char** argv)
printf(" [-s <system path>]\n");
printf(" [-d <data path>]\n");
printf(" [-v <volatile path>]\n");
printf(" [-f <linker_path>...\n");
printf(" [-a <app path>]\n");
printf(" [-m <proxy stub library path>]\n");
printf(" [-P <post mortem path>]\n\n");
printf(" [-S <system root path>]\n\n");
printf("\n");
printf("This application spawns a seperate process space for a plugin. The plugins");
printf("are searched in the same order as they are done in process. Starting from:\n");
printf(" 1) <persistent path>/<locator>\n");
printf(" 2) <system path>/<locator>\n");
printf(" 3) <data path>/<locator>\n");
printf(" 4) <app path>/Plugins/<locator>\n\n");
printf(" 1) [system_path/]<persistent path>/<locator>\n");
printf(" 2) [system_path/]<system path>/<locator>\n");
printf(" 3) [system_path/]<data path>/<locator>\n");
printf(" 4) [system_path/]<app path>/Plugins/<locator>\n\n");
printf("\n");
printf("Alternatively, if linker paths are specified:\n");
printf(" 1) [system_path/]<linker_path_1>/locator\n");
printf(" 2) [system_path/]<linker_path_2>/locator, ...\n");
printf("\n");
printf("Within the DSO, the system looks for an object with <classname>, this object must implement ");
printf("the interface, indicated byt the Id <interfaceId>, and if passed, the object should be of ");
printf("version <version>. All these conditions must met for an object to be instantiated and thus run.\n\n");

for (uint8_t teller = 0; teller < argc; teller++) {
printf("Argument [%02d]: %s\n", teller, argv[teller]);
}
} else {
string callsign;
if (options.Callsign != nullptr) {
Expand Down Expand Up @@ -640,7 +653,7 @@ int main(int argc, char** argv)
if (remoteNode.IsValid()) {
void* base = nullptr;

TRACE_L1("Spawning a new plugin %s.", options.ClassName);
TRACE_L1("Spawning a new plugin %s", options.Callsign);

// Firts make sure we apply the correct rights to our selves..
if (options.Group != nullptr) {
Expand Down
Loading

0 comments on commit 257d635

Please sign in to comment.