Files
SingularityViewer/indra/test_apps/llplugintest/plugin_process_launcher.cpp
2010-04-02 02:48:44 -03:00

198 lines
5.0 KiB
C++

/**
* @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();
}