Hello,
i would like the client application to remain responsive after the
connection to the render servers has been initialized. The
MultiDisplayWindow::init() function blocks until all render servers have
connected, therefore i would like to call init or initAsync on the
MultiDisplayWindow instance in another thread.
I changed the code of the testDynamicClusterClient.cpp file (attached)
such that on connection request a thread is created that operates on
aspect 1. After that, the function in the main thread returns.
The MultiDisplayWindow pointer is changed to a MTRecPtr such that it will
be available in the connection thread. After the thread is synced to the
main thread, initAsync is called. Once a server connected, the thread
waits on a barrier.
The main thread continuously polls if the thread is waiting on the barrier
and if so, pulls the changes from the connection thread to the main
thread.
The connection thread then finishes.
This works until i want to disconnect. Setting the
MultiDisplayWindowMTRecPtr to NULL does not free the object, the
connection is lost but the server window is not closed. At this point only
the main thread exists, therefore i am puzzled what could keep the window
from being destroyed. Any ideas?
P.S. How about an explicit ClusterWindow::disconnect() that would set any
pointers that refer to the window instance to NULL, like the WeakPtr?
// testDynamicClusterClient2
//
// OpenSG cluster client program where you can dynamicly connect/disconnect
// to the servers.
// It is similar to testDynamicClusterClient but this time we create from the
// current state a changelist and send this to the cluster servers.
// This variant is much easier to implement in your own app but could be
// problematic if you use more than one aspect in your app.
// To test it, run
// ./testClusterServer -w pipe0 &
// ./testDynamicClusterClient2 pipe0
//
// press 'c' to connect to the servers and 'd' to disconnect.
#include "OSGGLUT.h"
#include "OSGConfig.h"
#include "OSGSimpleGeometry.h"
#include "OSGGLUTWindow.h"
#include "OSGSimpleSceneManager.h"
#include "OSGMultiDisplayWindow.h"
#include "OSGSceneFileHandler.h"
#include "OSGRemoteAspect.h"
#include "OSGFieldContainerFactory.h"
#include "OSGBasetypes.h"
#include "OSGThread.h"
#include "OSGBarrier.h"
#include "OSGLock.h"
#include <string>
#include <vector>
// The SimpleSceneManager to manage simple applications
OSG::SimpleSceneManagerRefPtr _mgr = NULL;
OSG::GLUTWindowRecPtr _client_win = NULL;
OSG::MultiDisplayWindowMTRecPtr _cluster_win = NULL;
OSG::NodeRecPtr _root = NULL;
std::vector<std::string> _pipenames;
OSG::ThreadRefPtr m_connThread = 0;
OSG::ThreadRefPtr m_appThread = 0;
OSG::BarrierRefPtr m_syncBarrier = 0;
OSG::LockRefPtr m_lock = 0;
// forward declaration so we can have the interesting stuff upfront
int setupGLUT( int *argc, char *argv[] );
void display(void);
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
std::cout << "start a cluster server with './testClusterServer -w pipe0'\n"
"press 'c' to connect to the servers.\n"
"press 'd' to disconnect from the servers.\n"
"press 'n' to delete current scene.\n"
"press 't' to create a torus.\n"
"press 'l' to load scene 'tie.wrl'.\n"
<< std::endl;
// OSG init
OSG::osgInit(argc,argv);
// GLUT init
int winid = setupGLUT(&argc, argv);
// the connection between GLUT and OpenSG
_client_win = OSG::GLUTWindow::create();
_client_win->setGlutId(winid);
_client_win->init();
_client_win->setSize(300,300);
for(OSG::Int32 i=0;i<argc-1;++i)
{
if(argv[i+1] != NULL)
_pipenames.push_back(argv[i+1]);
}
if(_pipenames.empty())
_pipenames.push_back("pipe0");
_root = OSG::Node::create();
_root->setCore(OSG::Group::create());
// create default scene
OSG::NodeUnrecPtr scene = OSG::makeTorus(.5, 2, 16, 16);
_root->addChild(scene);
// create the SimpleSceneManager helper
_mgr = OSG::SimpleSceneManager::create();
// tell the manager what to manage
_mgr->setWindow(_client_win );
_mgr->setRoot (_root);
// show the whole scene
_mgr->showAll();
return 0;
}
int main(int argc, char **argv)
{
doMain(argc, argv);
glutMainLoop();
return 0;
}
static bool updateConnStatus(const std::string& msg, const std::string& server,
OSG::Real32 progress)
{
//Accessed from connection thread, needs lock if accesses member/global
variables
printf("%s %s: %f\n", msg.c_str(), server.c_str(), progress);
return true;
}
static void threadfunc(void* arg)
{
m_syncBarrier->enter(2);
m_appThread->getChangeList()->applyAndClear();
m_syncBarrier->enter(2);
m_connThread->getChangeList()->clear();
try
{
OSG::ClusterWindow::ConnectionCB updateConnStatusCB =
boost::bind(&updateConnStatus, _1, _2, _3);
if (!_cluster_win->initAsync(updateConnStatusCB))
{
_cluster_win = 0;
SLOG << "Connection was cancelled." << OSG::endLog;
}
}
catch (OSG_STDEXCEPTION_NAMESPACE::exception& e)
{
_cluster_win = 0;
SLOG << e.what() << OSG::endLog;
}
OSG::commitChanges();
m_syncBarrier->enter(2);
m_syncBarrier->enter(2);
}
void poll()
{
if (!m_syncBarrier)
return;
if(m_syncBarrier->getNumWaiting() > 0)
{
m_syncBarrier->enter(2);
m_connThread->getChangeList()->applyAndClear();
m_syncBarrier->enter(2);
OSG::Thread::join(m_connThread);
OSG::Thread::getCurrentChangeList()->commitChangesAndClear();
OSG::Thread::getCurrentChangeList()->fillFromCurrentState();
m_connThread = NULL;
m_appThread = NULL;
m_syncBarrier = NULL;
//glutIdleFunc(NULL);
glutPostRedisplay();
}
}
static void connectCluster(void)
{
if(_cluster_win != NULL)
return;
OSG::Viewport *clientvp = _client_win->getPort(0);
// create the viewports for the cluster just a simple one ...
OSG::ViewportUnrecPtr vp = OSG::Viewport::create();
vp->setCamera (_mgr->getCamera());
vp->setBackground(clientvp->getBackground());
vp->setRoot (clientvp->getRoot());
vp->setSize (0,0, 1,1);
// the connection between this client and the servers
_cluster_win = OSG::MultiDisplayWindow::create();
for(OSG::UInt32 i=0;i<_pipenames.size();++i)
_cluster_win->editMFServers()->push_back(_pipenames[i]);
// dummy size for navigator
_cluster_win->setSize(300,300);
_cluster_win->addPort(vp);
bool isGlobal = false;
m_syncBarrier = OSG::Barrier::get("CAVEManager.sync", isGlobal);
m_appThread =
dynamic_cast<OSG::Thread*>(OSG::ThreadManager::getAppThread());
m_connThread =
OSG::dynamic_pointer_cast<OSG::Thread>(OSG::ThreadManager::the()->getThread("CAVEManager.connection",
isGlobal));
m_lock = OSG::Lock::get("CAVEManager.lock", isGlobal);
OSG::commitChanges();
m_connThread->runFunction(threadfunc,
OSG::Thread::getCurrentAspect()+1, NULL); //create a new thread working on a
different aspect as the one on the main thread
m_syncBarrier->enter(2);
m_syncBarrier->enter(2);
}
static void disconnectCluster(void)
{
_cluster_win = NULL;
}
//
// GLUT callback functions
//
// redraw the window
void display(void)
{
// redraw the client window
_mgr->redraw();
OSG::commitChanges();
try
{
if(_cluster_win != NULL)
{
// redraw the server windows
_cluster_win->render(_mgr->getRenderAction());
}
}
catch(OSG_STDEXCEPTION_NAMESPACE::exception &)
{
//printf("error: '%s'\n", e.what());
printf("ClusterServer was killed!\n");
_cluster_win = NULL;
}
OSG::commitChanges();
OSG::clearChangeList();
}
// react to size changes
void reshape(int w, int h)
{
glutPostRedisplay();
}
// react to mouse button presses
void mouse(int button, int state, int x, int y)
{
if (state)
_mgr->mouseButtonRelease(button, x, y);
else
_mgr->mouseButtonPress(button, x, y);
glutPostRedisplay();
}
// react to mouse motions with pressed buttons
void motion(int x, int y)
{
_mgr->mouseMove(x, y);
glutPostRedisplay();
}
// react to keys
void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 27:
{
_mgr = NULL;
_client_win = NULL;
_cluster_win = NULL;
_root = NULL;
OSG::osgExit();
exit(0);
}
case 'n':
while(_root->getNChildren() > 0)
_root->subChild(_root->getChild(0));
glutPostRedisplay();
break;
case 'l':
{
OSG::NodeUnrecPtr scene =
OSG::SceneFileHandler::the()->read("tie.wrl", NULL);
if(scene != NULL)
{
_root->addChild(scene);
_mgr->showAll();
glutPostRedisplay();
}
}
break;
case 't':
{
OSG::NodeUnrecPtr scene = OSG::makeTorus(.5, 2, 16, 16);
_root->addChild(scene);
_mgr->showAll();
glutPostRedisplay();
}
break;
case 'c':
connectCluster();
break;
case 'd':
disconnectCluster();
break;
}
}
// setup the GLUT library which handles the windows for us
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
int winid = glutCreateWindow("OpenSG");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
glutIdleFunc(poll);
return winid;
}------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users