Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSO search in-process/OOP unification #1761

Merged
merged 3 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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