fixed setConfig() to disconnect secondary screens that aren't

in the new configuration.
This commit is contained in:
crs 2002-05-31 18:09:43 +00:00
parent 71c374b6cd
commit 1e8a5d7fa9
3 changed files with 66 additions and 12 deletions

View File

@ -110,13 +110,49 @@ void CServer::quit()
m_primary->stop(); m_primary->stop();
} }
void CServer::setConfig(const CConfig& config) bool CServer::setConfig(const CConfig& config)
{ {
CLock lock(&m_mutex); typedef std::vector<CThread> CThreads;
// FIXME -- must disconnect screens no longer listed CThreads threads;
// (that may include warping back to server's screen) {
// FIXME -- server screen must be in new map or map is rejected CLock lock(&m_mutex);
m_config = config;
// refuse configuration if it doesn't include the primary screen
if (m_primaryInfo != NULL &&
!config.isScreen(m_primaryInfo->m_name)) {
return false;
}
// get the set of screens that are connected but are being
// dropped from the configuration. don't add the primary
// screen.
for (CScreenList::const_iterator index = m_screens.begin();
index != m_screens.end(); ++index) {
if (!config.isScreen(index->first) &&
index->second != m_primaryInfo) {
threads.push_back(index->second->m_thread);
}
}
// cancel the old secondary screen threads
for (CThreads::iterator index = threads.begin();
index != threads.end(); ++index) {
index->cancel();
}
// cut over
m_config = config;
}
// wait for old secondary screen threads to disconnect. must
// not hold lock while we do this so those threads can finish
// any calls to this object.
for (CThreads::iterator index = threads.begin();
index != threads.end(); ++index) {
index->wait();
}
return true;
} }
CString CServer::getPrimaryScreenName() const CString CServer::getPrimaryScreenName() const
@ -137,14 +173,22 @@ UInt32 CServer::getActivePrimarySides() const
{ {
UInt32 sides = 0; UInt32 sides = 0;
CLock lock(&m_mutex); CLock lock(&m_mutex);
if (!m_config.getNeighbor("primary", CConfig::kLeft).empty()) if (!m_config.getNeighbor(getPrimaryScreenName(),
CConfig::kLeft).empty()) {
sides |= CConfig::kLeftMask; sides |= CConfig::kLeftMask;
if (!m_config.getNeighbor("primary", CConfig::kRight).empty()) }
if (!m_config.getNeighbor(getPrimaryScreenName(),
CConfig::kRight).empty()) {
sides |= CConfig::kRightMask; sides |= CConfig::kRightMask;
if (!m_config.getNeighbor("primary", CConfig::kTop).empty()) }
if (!m_config.getNeighbor(getPrimaryScreenName(),
CConfig::kTop).empty()) {
sides |= CConfig::kTopMask; sides |= CConfig::kTopMask;
if (!m_config.getNeighbor("primary", CConfig::kBottom).empty()) }
if (!m_config.getNeighbor(getPrimaryScreenName(),
CConfig::kBottom).empty()) {
sides |= CConfig::kBottomMask; sides |= CConfig::kBottomMask;
}
return sides; return sides;
} }
@ -1234,6 +1278,8 @@ CServer::CScreenInfo* CServer::addConnection(
throw XDuplicateClient(name); throw XDuplicateClient(name);
} }
// FIXME -- throw if the name is not in our map
// save screen info // save screen info
CScreenInfo* newScreen = new CScreenInfo(name, protocol); CScreenInfo* newScreen = new CScreenInfo(name, protocol);
m_screens.insert(std::make_pair(name, newScreen)); m_screens.insert(std::make_pair(name, newScreen));
@ -1314,6 +1360,7 @@ CServer::CConnectionNote::~CConnectionNote()
CServer::CScreenInfo::CScreenInfo(const CString& name, CServer::CScreenInfo::CScreenInfo(const CString& name,
IServerProtocol* protocol) : IServerProtocol* protocol) :
m_thread(CThread::getCurrentThread()),
m_name(name), m_name(name),
m_protocol(protocol), m_protocol(protocol),
m_width(0), m_height(0), m_width(0), m_height(0),

View File

@ -8,6 +8,7 @@
#include "CClipboard.h" #include "CClipboard.h"
#include "CMutex.h" #include "CMutex.h"
#include "CString.h" #include "CString.h"
#include "CThread.h"
#include "XBase.h" #include "XBase.h"
#include <list> #include <list>
#include <map> #include <map>
@ -32,8 +33,9 @@ public:
// tell server to exit gracefully // tell server to exit gracefully
void quit(); void quit();
// update screen map // update screen map. returns true iff the new configuration was
void setConfig(const CConfig&); // accepted.
bool setConfig(const CConfig&);
// handle events on server's screen. onMouseMovePrimary() returns // handle events on server's screen. onMouseMovePrimary() returns
// true iff the mouse enters a jump zone and jumps. // true iff the mouse enters a jump zone and jumps.
@ -105,6 +107,7 @@ private:
~CScreenInfo(); ~CScreenInfo();
public: public:
CThread m_thread;
CString m_name; CString m_name;
IServerProtocol* m_protocol; IServerProtocol* m_protocol;
SInt32 m_width, m_height; SInt32 m_width, m_height;

View File

@ -5,6 +5,7 @@
#include "ProtocolTypes.h" #include "ProtocolTypes.h"
#include "IInputStream.h" #include "IInputStream.h"
#include "CLog.h" #include "CLog.h"
#include "CThread.h"
#include <string.h> #include <string.h>
// //
@ -27,9 +28,12 @@ void CServerProtocol1_0::run()
{ {
// handle messages until the client hangs up // handle messages until the client hangs up
for (;;) { for (;;) {
CThread::testCancel();
// wait for a message // wait for a message
UInt8 code[4]; UInt8 code[4];
UInt32 n = getInputStream()->read(code, 4); UInt32 n = getInputStream()->read(code, 4);
CThread::testCancel();
// verify we got an entire code // verify we got an entire code
if (n == 0) { if (n == 0) {