fixed setConfig() to disconnect secondary screens that aren't
in the new configuration.
This commit is contained in:
parent
71c374b6cd
commit
1e8a5d7fa9
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue