summaryrefslogtreecommitdiff
path: root/cpp/demo
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2005-04-13 08:48:35 +0000
committerMatthew Newhook <matthew@zeroc.com>2005-04-13 08:48:35 +0000
commitd4ed5d38a15c1ad0fdd93e7af23ecedaf5315f7c (patch)
treeb709522dc8c2bb51fb54574c9726a0533b6cb877 /cpp/demo
parentFixed race condition in Thread_opVoid class. (diff)
downloadice-d4ed5d38a15c1ad0fdd93e7af23ecedaf5315f7c.tar.bz2
ice-d4ed5d38a15c1ad0fdd93e7af23ecedaf5315f7c.tar.xz
ice-d4ed5d38a15c1ad0fdd93e7af23ecedaf5315f7c.zip
added session demo.
Diffstat (limited to 'cpp/demo')
-rw-r--r--cpp/demo/Ice/bidir/config2
-rwxr-xr-xcpp/demo/Ice/session/Client.cpp211
-rw-r--r--cpp/demo/Ice/session/HelloSession.ice25
-rwxr-xr-xcpp/demo/Ice/session/HelloSessionManagerI.cpp76
-rwxr-xr-xcpp/demo/Ice/session/HelloSessionManagerI.h21
-rw-r--r--cpp/demo/Ice/session/README0
-rw-r--r--cpp/demo/Ice/session/Server.cpp62
-rw-r--r--cpp/demo/Ice/session/Session.ice55
-rwxr-xr-xcpp/demo/Ice/session/SessionManagerI.cpp168
-rwxr-xr-xcpp/demo/Ice/session/SessionManagerI.h68
-rw-r--r--cpp/demo/Ice/session/config17
-rwxr-xr-xcpp/demo/Ice/session/sessionC.dsp196
-rwxr-xr-xcpp/demo/Ice/session/sessionC.plg33
13 files changed, 933 insertions, 1 deletions
diff --git a/cpp/demo/Ice/bidir/config b/cpp/demo/Ice/bidir/config
index d194f5d3765..6697c74e963 100644
--- a/cpp/demo/Ice/bidir/config
+++ b/cpp/demo/Ice/bidir/config
@@ -2,6 +2,6 @@ Callback.Client.CallbackServer=sender:tcp -p 10000
Callback.Client.Endpoints=
Callback.Server.Endpoints=tcp -p 10000
-#Ice.Trace.Network=1
+Ice.Trace.Network=0
#Ice.Trace.Protocol=1
Ice.Warn.Connections=1
diff --git a/cpp/demo/Ice/session/Client.cpp b/cpp/demo/Ice/session/Client.cpp
new file mode 100755
index 00000000000..3283d55c1f7
--- /dev/null
+++ b/cpp/demo/Ice/session/Client.cpp
@@ -0,0 +1,211 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <IceUtil/Thread.h>
+#include <HelloSession.h>
+
+using namespace std;
+using namespace Demo;
+
+//
+// This thread pings the session object with the given timeout frequency.
+//
+class SessionRefreshThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ SessionRefreshThread(const Ice::LoggerPtr& logger, const SessionPrx& session,
+ const IceUtil::Time& timeout) :
+ _logger(logger),
+ _session(session),
+ _destroy(false),
+ _timeout(timeout)
+ {
+ }
+
+ virtual void
+ run()
+ {
+ Lock sync(*this);
+ while(!_destroy)
+ {
+ timedWait(_timeout);
+ if(_destroy)
+ {
+ break;
+ }
+ //
+ // If the refresh fails we're done.
+ //
+ try
+ {
+ _session->refresh();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ Ice::Warning warn(_logger);
+ warn << "SessionRefreshThread: " << ex;
+ break;
+ }
+ }
+ }
+
+ void
+ destroy()
+ {
+ Lock sync(*this);
+ _destroy = true;
+ notify();
+ }
+
+private:
+
+ const Ice::LoggerPtr _logger;
+ const SessionPrx _session;
+ bool _destroy;
+ const IceUtil::Time _timeout;
+};
+typedef IceUtil::Handle<SessionRefreshThread> SessionRefreshThreadPtr;
+
+void
+menu()
+{
+ cout <<
+ "usage:\n"
+ "h: send greeting\n"
+ "s: shutdown server\n"
+ "x: exit\n"
+ "?: help\n";
+}
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ Ice::PropertiesPtr properties = communicator->getProperties();
+ const char* proxyProperty = "SessionManager.Proxy";
+ string proxy = properties->getProperty(proxyProperty);
+ if(proxy.empty())
+ {
+ cerr << argv[0] << ": property `" << proxyProperty << "' not set" << endl;
+ return EXIT_FAILURE;
+ }
+
+ //
+ // Get the session manager object, and create a session.
+ //
+ Ice::ObjectPrx base = communicator->stringToProxy(proxy);
+ SessionManagerPrx manager = SessionManagerPrx::checkedCast(base);
+ if(!manager)
+ {
+ cerr << argv[0] << ": invalid proxy" << endl;
+ return EXIT_FAILURE;
+ }
+
+ HelloSessionPrx hello = HelloSessionPrx::uncheckedCast(manager->create());
+ if(!hello)
+ {
+ cerr << argv[0] << ": invalid proxy" << endl;
+ return EXIT_FAILURE;
+ }
+
+ //
+ // Create a thread to ping the object at regular intervals.
+ //
+ SessionRefreshThreadPtr refresh = new SessionRefreshThread(
+ communicator->getLogger(), hello, IceUtil::Time::seconds(5));
+ refresh->start();
+
+ menu();
+
+ try
+ {
+ do
+ {
+ cout << "==> ";
+ char c;
+ cin >> c;
+ if(c == 'h')
+ {
+ hello->sayHello();
+ }
+ else if(c == 's')
+ {
+ manager->shutdown();
+ }
+ else if(c == 'x')
+ {
+ break;
+ }
+ else if(c == '?')
+ {
+ menu();
+ }
+ else
+ {
+ cout << "unknown command `" << c << "'" << endl;
+ menu();
+ }
+ }
+ while(cin.good());
+
+ //
+ // Destroy the session before we finish.
+ //
+ hello->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ }
+
+ //
+ // Destroy the ping thread, and join with it to ensure that it
+ // actually completes.
+ //
+ refresh->destroy();
+ refresh->getThreadControl().join();
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ Ice::PropertiesPtr properties = Ice::createProperties();
+ properties->load("config");
+ communicator = Ice::initializeWithProperties(argc, argv, properties);
+ status = run(argc, argv, communicator);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ try
+ {
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/demo/Ice/session/HelloSession.ice b/cpp/demo/Ice/session/HelloSession.ice
new file mode 100644
index 00000000000..af3768539dc
--- /dev/null
+++ b/cpp/demo/Ice/session/HelloSession.ice
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef HELLO_SESSION_ICE
+#define HELLO_SESSION_ICE
+
+#include <Session.ice>
+
+module Demo
+{
+
+interface HelloSession extends Session
+{
+ nonmutating void sayHello();
+};
+
+};
+
+#endif
diff --git a/cpp/demo/Ice/session/HelloSessionManagerI.cpp b/cpp/demo/Ice/session/HelloSessionManagerI.cpp
new file mode 100755
index 00000000000..0ad43dec770
--- /dev/null
+++ b/cpp/demo/Ice/session/HelloSessionManagerI.cpp
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <HelloSessionManagerI.h>
+
+#include <HelloSession.h>
+
+using namespace std;
+using namespace Demo;
+
+class HelloSessionI : public HelloSession
+{
+public:
+
+ HelloSessionI(const SessionManagerIPtr& manager) :
+ _manager(manager)
+ {
+ }
+
+ ~HelloSessionI()
+ {
+ }
+
+ virtual void
+ sayHello(const Ice::Current&) const
+ {
+ cout << "Hello World!" << endl;
+ }
+
+ // Common session specific code.
+
+ //
+ // Destroy all session specific state.
+ //
+ virtual void
+ destroyed(const Ice::Current& c)
+ {
+ c.adapter->remove(c.id);
+ }
+
+ //
+ // This method is called by the client to destroy a session. All
+ // it should do is call remove on the session manager. All user
+ // specific cleanup should go in the destroyed() callback.
+ //
+ virtual void
+ destroy(const Ice::Current& c)
+ {
+ _manager->remove(c.id);
+ }
+
+ virtual void
+ refresh(const Ice::Current& c)
+ {
+ _manager->refresh(c.id);
+ }
+
+private:
+
+ const SessionManagerIPtr _manager;
+};
+
+SessionPrx
+HelloSessionManagerI::create(const Ice::Current& c)
+{
+ SessionPrx session = SessionPrx::uncheckedCast(c.adapter->addWithUUID(new HelloSessionI(this)));
+ add(session);
+ return session;
+}
diff --git a/cpp/demo/Ice/session/HelloSessionManagerI.h b/cpp/demo/Ice/session/HelloSessionManagerI.h
new file mode 100755
index 00000000000..5ac5badc408
--- /dev/null
+++ b/cpp/demo/Ice/session/HelloSessionManagerI.h
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef HELLO_SESSION_MANAGER_I_H
+#define HELLO_SESSION_MANAGER_I_H
+
+#include <SessionManagerI.h>
+
+class HelloSessionManagerI : public SessionManagerI
+{
+public:
+ virtual ::Demo::SessionPrx create(const ::Ice::Current&);
+};
+
+#endif
diff --git a/cpp/demo/Ice/session/README b/cpp/demo/Ice/session/README
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/cpp/demo/Ice/session/README
diff --git a/cpp/demo/Ice/session/Server.cpp b/cpp/demo/Ice/session/Server.cpp
new file mode 100644
index 00000000000..156ce0a148f
--- /dev/null
+++ b/cpp/demo/Ice/session/Server.cpp
@@ -0,0 +1,62 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <HelloSessionManagerI.h>
+
+using namespace std;
+using namespace Demo;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("SessionManager");
+ SessionManagerIPtr manager = new HelloSessionManagerI;
+ Ice::ObjectPtr object = new HelloSessionManagerI;
+ adapter->add(object, Ice::stringToIdentity("SessionManager"));
+ adapter->activate();
+ communicator->waitForShutdown();
+ manager->destroy();
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ Ice::PropertiesPtr properties = Ice::createProperties();
+ properties->load("config");
+ communicator = Ice::initializeWithProperties(argc, argv, properties);
+ status = run(argc, argv, communicator);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ try
+ {
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/demo/Ice/session/Session.ice b/cpp/demo/Ice/session/Session.ice
new file mode 100644
index 00000000000..0a687ae651d
--- /dev/null
+++ b/cpp/demo/Ice/session/Session.ice
@@ -0,0 +1,55 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef SESSION_ICE
+#define SESSION_ICE
+
+module Demo
+{
+
+interface Session
+{
+ /**
+ * Refresh a session. If a session is not refreshed on a regular
+ * basis by the client it will be automatically destroyed.
+ *
+ **/
+ void refresh();
+
+ /**
+ * Callback that the session has been destroyed.
+ *
+ **/
+ void destroyed();
+
+ /**
+ * Destroy a session.
+ *
+ **/
+ void destroy();
+};
+
+interface SessionManager
+{
+ /**
+ * Create a new session.
+ *
+ **/
+ Session* create();
+
+ /**
+ * Shutdown the server
+ *
+ **/
+ void shutdown();
+};
+
+};
+
+#endif
diff --git a/cpp/demo/Ice/session/SessionManagerI.cpp b/cpp/demo/Ice/session/SessionManagerI.cpp
new file mode 100755
index 00000000000..076417a95c5
--- /dev/null
+++ b/cpp/demo/Ice/session/SessionManagerI.cpp
@@ -0,0 +1,168 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <HelloSessionManagerI.h>
+
+#include <HelloSession.h>
+
+using namespace std;
+using namespace Demo;
+
+ReapThread::ReapThread(const SessionManagerIPtr& manager, const IceUtil::Time& timeout) :
+ _destroy(false),
+ _timeout(timeout),
+ _manager(manager)
+{
+}
+
+ReapThread::~ReapThread()
+{
+}
+
+void
+ReapThread::run()
+{
+ Lock sync(*this);
+ while(!_destroy)
+ {
+ timedWait(_timeout);
+ if(_destroy)
+ {
+ break;
+ }
+ _manager->reap();
+ }
+}
+
+void
+ReapThread::destroy()
+{
+ Lock sync(*this);
+ _destroy = true;
+ notify();
+}
+
+SessionManagerI::SessionManagerI() :
+ _timeout(IceUtil::Time::seconds(10)),
+ _reapThread(new ReapThread(this, _timeout)),
+ _destroy(false)
+{
+ _reapThread->start();
+}
+
+SessionManagerI::~SessionManagerI()
+{
+ assert(_sessions.size() == 0);
+}
+
+void
+SessionManagerI::shutdown(const Ice::Current& c)
+{
+ cout << "Shutting down..." << endl;
+ c.adapter->getCommunicator()->shutdown();
+}
+
+void
+SessionManagerI::destroy()
+{
+ Lock sync(*this);
+
+ assert(!_destroy);
+ _destroy = true;
+ _reapThread->destroy();
+ _reapThread->getThreadControl().join();
+
+ //
+ // Destroy each session.
+ //
+ for(map<Ice::Identity, pair< IceUtil::Time, SessionPrx> >::iterator p = _sessions.begin();
+ p != _sessions.end();
+ ++p)
+ {
+ try
+ {
+ p->second.second->destroyed();
+ }
+ catch(const Ice::Exception&)
+ {
+ }
+ }
+ _sessions.clear();
+}
+
+void
+SessionManagerI::add(const SessionPrx& session)
+{
+ Lock sync(*this);
+
+ assert(!_destroy);
+ _sessions.insert(make_pair(session->ice_getIdentity(), make_pair(IceUtil::Time::now(), session)));
+}
+
+void
+SessionManagerI::remove(const Ice::Identity& id)
+{
+ Lock sync(*this);
+
+ assert(!_destroy);
+ map<Ice::Identity, pair< IceUtil::Time, SessionPrx> >::iterator p = _sessions.find(id);
+ if(p != _sessions.end())
+ {
+ p->second.second->destroyed();
+ _sessions.erase(p);
+ }
+}
+
+void
+SessionManagerI::refresh(const Ice::Identity& id)
+{
+ Lock sync(*this);
+ map<Ice::Identity, pair< IceUtil::Time, SessionPrx> >::iterator p = _sessions.find(id);
+ if(p != _sessions.end())
+ {
+ p->second.first = IceUtil::Time::now();
+ }
+ // Its possible the code reaches here if a session times out and
+ // is removed at the same time as it calls refresh.
+}
+
+void
+SessionManagerI::reap()
+{
+ Lock sync(*this);
+
+ //
+ // Run through the sessions destroying those which have not
+ // been refreshed in the _timeout interval.
+ //
+ IceUtil::Time now = IceUtil::Time::now();
+ map<Ice::Identity, pair< IceUtil::Time, SessionPrx> >::iterator p = _sessions.begin();
+ while(p != _sessions.end())
+ {
+ if((now - p->second.first) > _timeout)
+ {
+ try
+ {
+ p->second.second->destroyed();
+ }
+ catch(const Ice::Exception&)
+ {
+ }
+ map<Ice::Identity, pair< IceUtil::Time, SessionPrx> >::iterator tmp = p;
+ ++p;
+ _sessions.erase(tmp);
+ }
+ else
+ {
+ ++p;
+ }
+ }
+}
+
diff --git a/cpp/demo/Ice/session/SessionManagerI.h b/cpp/demo/Ice/session/SessionManagerI.h
new file mode 100755
index 00000000000..fa6d58f0f7f
--- /dev/null
+++ b/cpp/demo/Ice/session/SessionManagerI.h
@@ -0,0 +1,68 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef SESSION_MANAGER_I_H
+#define SESSION_MANAGER_I_H
+
+#include <IceUtil/Thread.h>
+#include <Session.h>
+
+class SessionManagerI;
+typedef IceUtil::Handle<SessionManagerI> SessionManagerIPtr;
+
+class ReapThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ ReapThread(const SessionManagerIPtr&, const IceUtil::Time&);
+ ~ReapThread();
+
+ virtual void run();
+ void destroy();
+
+private:
+
+ bool _destroy;
+ const IceUtil::Time _timeout;
+ const SessionManagerIPtr _manager;
+};
+typedef IceUtil::Handle<ReapThread> ReapThreadPtr;
+
+//
+// Users wanting to create their own session manager specialization
+// should inherit off this class and implement create. Create must
+// call add with the creation session proxy.
+//
+class SessionManagerI : public ::Demo::SessionManager, public IceUtil::Mutex
+{
+public:
+
+ SessionManagerI();
+ ~SessionManagerI();
+
+ virtual ::Demo::SessionPrx create(const ::Ice::Current&) = 0;
+ virtual void shutdown(const Ice::Current&);
+
+ void destroy();
+ void add(const ::Demo::SessionPrx&);
+ void remove(const ::Ice::Identity&);
+ void refresh(const ::Ice::Identity&);
+ void reap();
+
+private:
+
+ const IceUtil::Time _timeout;
+ ReapThreadPtr _reapThread;
+ const ::Ice::LoggerPtr _logger;
+ std::map<Ice::Identity, std::pair< IceUtil::Time, ::Demo::SessionPrx> > _sessions;
+ bool _destroy;
+};
+typedef IceUtil::Handle<SessionManagerI> SessionManagerIPtr;
+
+#endif
diff --git a/cpp/demo/Ice/session/config b/cpp/demo/Ice/session/config
new file mode 100644
index 00000000000..9d5e9696eb9
--- /dev/null
+++ b/cpp/demo/Ice/session/config
@@ -0,0 +1,17 @@
+#
+# The client reads this property to create the reference to the
+# "SessionManager" object in the server.
+#
+SessionManager.Proxy=SessionManager:tcp -p 10000:udp -p 10000:ssl -p 10001
+
+#
+# The server creates one single object adapter with the name
+# "SessionManager". The following line sets the endpoints for this
+# adapter.
+#
+SessionManager.Endpoints=tcp -p 10000:udp -p 10000:ssl -p 10001
+
+#
+# Warn about connection exceptions
+#
+Ice.Warn.Connections=1
diff --git a/cpp/demo/Ice/session/sessionC.dsp b/cpp/demo/Ice/session/sessionC.dsp
new file mode 100755
index 00000000000..f45493684c4
--- /dev/null
+++ b/cpp/demo/Ice/session/sessionC.dsp
@@ -0,0 +1,196 @@
+# Microsoft Developer Studio Project File - Name="sessionC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=sessionC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "sessionC.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "sessionC.mak" CFG="sessionC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "sessionC - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "sessionC - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "sessionC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../../include" /I "../../../include/stlport" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Ice.lib IceUtil.lib /nologo /subsystem:console /incremental:yes /machine:I386 /out:"client.exe" /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+
+!ELSEIF "$(CFG)" == "sessionC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../../include" /I "../../../include/stlport" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 Iced.lib IceUtild.lib /nologo /subsystem:console /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+
+!ENDIF
+
+# Begin Target
+
+# Name "sessionC - Win32 Release"
+# Name "sessionC - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\HelloSession.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Session.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\HelloSession.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Session.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\HelloSession.ice
+
+!IF "$(CFG)" == "sessionC - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\HelloSession.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe -I. HelloSession.ice
+
+"HelloSession.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"HelloSession.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "sessionC - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\HelloSession.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe -I. HelloSession.ice
+
+"HelloSession.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"HelloSession.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Session.ice
+
+!IF "$(CFG)" == "sessionC - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\Session.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe Session.ice
+
+"Session.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Session.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "sessionC - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\Session.ice
+
+BuildCmds= \
+ ..\..\..\bin\slice2cpp.exe Session.ice
+
+"Session.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Session.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/demo/Ice/session/sessionC.plg b/cpp/demo/Ice/session/sessionC.plg
new file mode 100755
index 00000000000..6d2f72723f4
--- /dev/null
+++ b/cpp/demo/Ice/session/sessionC.plg
@@ -0,0 +1,33 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: sessionC - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\matthew\LOCALS~1\Temp\RSP2315.tmp" with contents
+[
+/nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../../include" /I "../../../include/stlport" /D "_DEBUG" /D "_CONSOLE" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
+"C:\src\ice\demo\Ice\session\Client.cpp"
+"C:\src\ice\demo\Ice\session\Session.cpp"
+"C:\src\ice\demo\Ice\session\HelloSession.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\matthew\LOCALS~1\Temp\RSP2315.tmp"
+Creating command line "link.exe Iced.lib IceUtild.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/client.pdb" /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"../../../lib" .\Debug\Client.obj .\Debug\Session.obj .\Debug\HelloSession.obj "
+<h3>Output Window</h3>
+Compiling...
+Client.cpp
+Generating Code...
+Skipping... (no relevant changes detected)
+Session.cpp
+HelloSession.cpp
+Linking...
+
+
+
+<h3>Results</h3>
+client.exe - 0 error(s), 0 warning(s)
+</pre>
+</body>
+</html>