198 lines
5.0 KiB
C++
Executable File
198 lines
5.0 KiB
C++
Executable File
/**
|
|
* @file plugin_process_launcher.cpp
|
|
* @brief Testbed for llplugin which launches the plugin loader shell.
|
|
*
|
|
* $LicenseInfo:firstyear=2008&license=viewergpl$
|
|
*
|
|
* Copyright (c) 2008-2009, Linden Research, Inc.
|
|
*
|
|
* Second Life Viewer Source Code
|
|
* The source code in this file ("Source Code") is provided by Linden Lab
|
|
* to you under the terms of the GNU General Public License, version 2.0
|
|
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
*
|
|
* There are special exceptions to the terms and conditions of the GPL as
|
|
* it is applied to this Source Code. View the full text of the exception
|
|
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
* online at
|
|
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge
|
|
* that you have read and understood your obligations described above,
|
|
* and agree to abide by those obligations.
|
|
*
|
|
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
* COMPLETENESS OR PERFORMANCE.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "linden_common.h"
|
|
|
|
#include "llprocesslauncher.h"
|
|
#include "lltimer.h" // for ms_sleep()
|
|
#include "llpumpio.h"
|
|
#include "llapr.h"
|
|
#include "llerrorcontrol.h"
|
|
#include "llpluginprocessparent.h"
|
|
|
|
class PluginProcessLauncherMessageReceiver : public LLPluginProcessParentOwner
|
|
{
|
|
LOG_CLASS(PluginProcessLauncherMessageReceiver);
|
|
|
|
public:
|
|
virtual ~PluginProcessLauncherMessageReceiver()
|
|
{
|
|
}
|
|
|
|
/* virtual */ void receivePluginMessage(const LLPluginMessage &message)
|
|
{
|
|
LL_INFOS("plugin_process_launcher") << "received message: \n" << message.generate() << LL_ENDL;
|
|
}
|
|
};
|
|
|
|
LLPumpIO* gServicePump;
|
|
LLPluginProcessParent *gPlugin;
|
|
|
|
|
|
#define SHARED_MEMORY_SIZE 0x10000
|
|
#define SHARED_MEMORY_NAME "testsegment"
|
|
enum State
|
|
{
|
|
STATE_STARTUP,
|
|
STATE_ADD_MEMORY,
|
|
STATE_RUNNING,
|
|
STATE_REMOVE_MEMORY,
|
|
STATE_SHUTDOWN,
|
|
STATE_CLEANUP,
|
|
STATE_DONE
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
ll_init_apr();
|
|
|
|
// Set up llerror logging
|
|
{
|
|
LLError::initForApplication(".");
|
|
LLError::setDefaultLevel(LLError::LEVEL_INFO);
|
|
}
|
|
|
|
std::string launcher_name;
|
|
std::string plugin_name;
|
|
|
|
if(argc >= 3)
|
|
{
|
|
launcher_name = argv[1];
|
|
plugin_name = argv[2];
|
|
}
|
|
else
|
|
{
|
|
#if LL_DARWIN
|
|
// hardcoding the testbed arguments by default
|
|
launcher_name = "plugin_process_host";
|
|
plugin_name = "libdemo_plugin.dylib";
|
|
#elif LL_WINDOWS
|
|
// hardcoding the testbed arguments by default
|
|
launcher_name = "plugin_process_host.exe";
|
|
plugin_name = "demo_plugin.dll";
|
|
#else
|
|
LL_ERRS("plugin_process_launcher") << "usage: " << argv[0] << " launcher_filename plugin_filename" << LL_ENDL;
|
|
#endif
|
|
}
|
|
|
|
PluginProcessLauncherMessageReceiver receiver;
|
|
|
|
gServicePump = new LLPumpIO(gAPRPoolp);
|
|
gServicePump->prime(gAPRPoolp);
|
|
|
|
gPlugin = new LLPluginProcessParent(gServicePump, &receiver);
|
|
|
|
State state = STATE_STARTUP;
|
|
while(state != STATE_DONE)
|
|
{
|
|
switch(state)
|
|
{
|
|
case STATE_STARTUP:
|
|
LL_INFOS("plugin_process_launcher") << "startup" << LL_ENDL;
|
|
gPlugin->init(launcher_name, plugin_name);
|
|
state = STATE_ADD_MEMORY;
|
|
break;
|
|
|
|
case STATE_ADD_MEMORY:
|
|
if(gPlugin->isRunning())
|
|
{
|
|
LL_INFOS("plugin_process_launcher") << "adding shared memory" << LL_ENDL;
|
|
gPlugin->addSharedMemory(SHARED_MEMORY_SIZE);
|
|
state = STATE_RUNNING;
|
|
}
|
|
break;
|
|
|
|
case STATE_RUNNING:
|
|
{
|
|
volatile unsigned char *addr = (unsigned char*)gPlugin->getSharedMemoryAddress(SHARED_MEMORY_NAME);
|
|
if(addr != NULL)
|
|
{
|
|
int val = (int)(addr[0]);
|
|
if(val >= 16)
|
|
{
|
|
state = STATE_REMOVE_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS("plugin_process_launcher") << "running, value from shared memory is " << val << LL_ENDL;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STATE_REMOVE_MEMORY:
|
|
LL_INFOS("plugin_process_launcher") << "removing shared memory" << LL_ENDL;
|
|
gPlugin->removeSharedMemory(SHARED_MEMORY_NAME);
|
|
state = STATE_SHUTDOWN;
|
|
break;
|
|
|
|
case STATE_SHUTDOWN:
|
|
{
|
|
volatile unsigned char *addr = (unsigned char*)gPlugin->getSharedMemoryAddress(SHARED_MEMORY_NAME);
|
|
if(addr == NULL)
|
|
{
|
|
LL_INFOS("plugin_process_launcher") << "sending shutdown request" << LL_ENDL;
|
|
gPlugin->shutdownRequest();
|
|
state = STATE_CLEANUP;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STATE_CLEANUP:
|
|
if(gPlugin->isDone())
|
|
{
|
|
LL_INFOS("plugin_process_launcher") << "plugin is done" << LL_ENDL;
|
|
state = STATE_DONE;
|
|
}
|
|
break;
|
|
|
|
case STATE_DONE:
|
|
// should never reach here -- the while() should exit first.
|
|
break;
|
|
}
|
|
|
|
// Do this every time through the loop
|
|
if(state != STATE_DONE)
|
|
{
|
|
gServicePump->pump();
|
|
gServicePump->callback();
|
|
gPlugin->idle();
|
|
ms_sleep(100);
|
|
}
|
|
}
|
|
|
|
delete gPlugin;
|
|
|
|
ll_cleanup_apr();
|
|
|
|
}
|