fixed problem with opening client and server. in some cases it
would fail to open in such a way that it could never succeed but it'd never stop retrying. now terminating when open fails such that it'll never succeed.
This commit is contained in:
parent
f5795a6630
commit
5e40de48f9
|
@ -3,6 +3,7 @@
|
||||||
#include "CPlatform.h"
|
#include "CPlatform.h"
|
||||||
#include "ProtocolTypes.h"
|
#include "ProtocolTypes.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
#include "XScreen.h"
|
||||||
#include "CNetwork.h"
|
#include "CNetwork.h"
|
||||||
#include "CNetworkAddress.h"
|
#include "CNetworkAddress.h"
|
||||||
#include "CTCPSocketFactory.h"
|
#include "CTCPSocketFactory.h"
|
||||||
|
@ -125,7 +126,8 @@ realMain(CMutex* mutex)
|
||||||
s_client->setStreamFilterFactory(NULL);
|
s_client->setStreamFilterFactory(NULL);
|
||||||
|
|
||||||
// open client
|
// open client
|
||||||
if (s_client->open()) {
|
try {
|
||||||
|
s_client->open();
|
||||||
opened = true;
|
opened = true;
|
||||||
|
|
||||||
// run client
|
// run client
|
||||||
|
@ -139,31 +141,33 @@ realMain(CMutex* mutex)
|
||||||
mutex->lock();
|
mutex->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get client status
|
|
||||||
if (s_client->wasRejected()) {
|
|
||||||
// wait a while before retrying. we don't want
|
|
||||||
// to bother the server very often if it doesn't
|
|
||||||
// want us.
|
|
||||||
if (s_restartable) {
|
|
||||||
CThread::sleep(60.0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = kExitFailed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
s_client->close();
|
s_client->close();
|
||||||
|
|
||||||
|
// get client status
|
||||||
|
if (s_client->wasRejected()) {
|
||||||
|
// try again later. we don't want to bother
|
||||||
|
// the server very often if it doesn't want us.
|
||||||
|
throw XScreenUnavailable(60.0);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
catch (XScreenUnavailable& e) {
|
||||||
// wait a few seconds before retrying
|
// wait a few seconds before retrying
|
||||||
if (s_restartable) {
|
if (s_restartable) {
|
||||||
CThread::sleep(3.0);
|
CThread::sleep(e.getRetryTime());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = kExitFailed;
|
result = kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (...) {
|
||||||
|
// rethrow thread exceptions
|
||||||
|
RETHROW_XTHREAD
|
||||||
|
|
||||||
|
// don't try to restart and fail
|
||||||
|
s_restartable = false;
|
||||||
|
result = kExitFailed;
|
||||||
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
delete s_client;
|
delete s_client;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "CPlatform.h"
|
#include "CPlatform.h"
|
||||||
#include "ProtocolTypes.h"
|
#include "ProtocolTypes.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
#include "XScreen.h"
|
||||||
#include "CNetwork.h"
|
#include "CNetwork.h"
|
||||||
#include "CTCPSocketFactory.h"
|
#include "CTCPSocketFactory.h"
|
||||||
#include "XSocket.h"
|
#include "XSocket.h"
|
||||||
|
@ -156,7 +157,8 @@ realMain(CMutex* mutex)
|
||||||
s_server->setStreamFilterFactory(NULL);
|
s_server->setStreamFilterFactory(NULL);
|
||||||
|
|
||||||
// open server
|
// open server
|
||||||
if (s_server->open()) {
|
try {
|
||||||
|
s_server->open();
|
||||||
opened = true;
|
opened = true;
|
||||||
|
|
||||||
// run server (unlocked)
|
// run server (unlocked)
|
||||||
|
@ -173,15 +175,23 @@ realMain(CMutex* mutex)
|
||||||
// clean up
|
// clean up
|
||||||
s_server->close();
|
s_server->close();
|
||||||
}
|
}
|
||||||
else {
|
catch (XScreenUnavailable& e) {
|
||||||
// wait a few seconds before retrying
|
// wait before retrying if we're going to retry
|
||||||
if (s_restartable) {
|
if (s_restartable) {
|
||||||
CThread::sleep(3.0);
|
CThread::sleep(e.getRetryTime());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = kExitFailed;
|
result = kExitFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (...) {
|
||||||
|
// rethrow thread exceptions
|
||||||
|
RETHROW_XTHREAD
|
||||||
|
|
||||||
|
// don't try to restart and fail
|
||||||
|
s_restartable = false;
|
||||||
|
result = kExitFailed;
|
||||||
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
delete s_server;
|
delete s_server;
|
||||||
|
|
|
@ -149,19 +149,18 @@ CClient::onClipboardChanged(ClipboardID, const CString&)
|
||||||
// ignore -- we'll check the clipboard when we leave
|
// ignore -- we'll check the clipboard when we leave
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
CClient::open()
|
CClient::open()
|
||||||
{
|
{
|
||||||
// open the screen
|
// open the screen
|
||||||
try {
|
try {
|
||||||
log((CLOG_INFO "opening screen"));
|
log((CLOG_INFO "opening screen"));
|
||||||
openSecondaryScreen();
|
openSecondaryScreen();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch (XScreenOpenFailure&) {
|
catch (XScreenOpenFailure&) {
|
||||||
// can't open screen yet. wait a few seconds to retry.
|
// can't open screen
|
||||||
log((CLOG_INFO "failed to open screen"));
|
log((CLOG_INFO "failed to open screen"));
|
||||||
return false;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +367,6 @@ void
|
||||||
CClient::openSecondaryScreen()
|
CClient::openSecondaryScreen()
|
||||||
{
|
{
|
||||||
assert(m_screen == NULL);
|
assert(m_screen == NULL);
|
||||||
assert(m_screenFactory != NULL);
|
|
||||||
|
|
||||||
// not active
|
// not active
|
||||||
m_active = false;
|
m_active = false;
|
||||||
|
@ -381,7 +379,9 @@ CClient::openSecondaryScreen()
|
||||||
|
|
||||||
// create screen
|
// create screen
|
||||||
log((CLOG_DEBUG1 "creating secondary screen"));
|
log((CLOG_DEBUG1 "creating secondary screen"));
|
||||||
|
if (m_screenFactory != NULL) {
|
||||||
m_screen = m_screenFactory->create(this);
|
m_screen = m_screenFactory->create(this);
|
||||||
|
}
|
||||||
if (m_screen == NULL) {
|
if (m_screen == NULL) {
|
||||||
throw XScreenOpenFailure();
|
throw XScreenOpenFailure();
|
||||||
}
|
}
|
||||||
|
@ -402,13 +402,13 @@ CClient::openSecondaryScreen()
|
||||||
void
|
void
|
||||||
CClient::closeSecondaryScreen()
|
CClient::closeSecondaryScreen()
|
||||||
{
|
{
|
||||||
assert(m_screen != NULL);
|
|
||||||
|
|
||||||
// close the secondary screen
|
// close the secondary screen
|
||||||
try {
|
try {
|
||||||
|
if (m_screen != NULL) {
|
||||||
log((CLOG_DEBUG1 "closing secondary screen"));
|
log((CLOG_DEBUG1 "closing secondary screen"));
|
||||||
m_screen->close();
|
m_screen->close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ public:
|
||||||
virtual void onClipboardChanged(ClipboardID, const CString&);
|
virtual void onClipboardChanged(ClipboardID, const CString&);
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual bool open();
|
virtual void open();
|
||||||
virtual void mainLoop();
|
virtual void mainLoop();
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -229,7 +229,7 @@ CXWindowsSecondaryScreen::createWindow()
|
||||||
int majorOpcode, firstEvent, firstError;
|
int majorOpcode, firstEvent, firstError;
|
||||||
if (!XQueryExtension(display, XTestExtensionName,
|
if (!XQueryExtension(display, XTestExtensionName,
|
||||||
&majorOpcode, &firstEvent, &firstError)) {
|
&majorOpcode, &firstEvent, &firstError)) {
|
||||||
// FIXME -- subclass exception for more info?
|
log((CLOG_ERR "XTEST extension not available"));
|
||||||
throw XScreenOpenFailure();
|
throw XScreenOpenFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,7 @@ CXWindowsScreen::open()
|
||||||
log((CLOG_DEBUG "XOpenDisplay(\"%s\")", display));
|
log((CLOG_DEBUG "XOpenDisplay(\"%s\")", display));
|
||||||
m_display = XOpenDisplay(display);
|
m_display = XOpenDisplay(display);
|
||||||
if (m_display == NULL) {
|
if (m_display == NULL) {
|
||||||
throw XScreenOpenFailure();
|
throw XScreenUnavailable(60.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get root window
|
// get root window
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual bool open() = 0;
|
virtual void open() = 0;
|
||||||
virtual void mainLoop() = 0;
|
virtual void mainLoop() = 0;
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -29,7 +29,7 @@ CClientProxy1_0::~CClientProxy1_0()
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
CClientProxy1_0::open()
|
CClientProxy1_0::open()
|
||||||
{
|
{
|
||||||
// send request
|
// send request
|
||||||
|
@ -55,8 +55,6 @@ CClientProxy1_0::open()
|
||||||
|
|
||||||
// handle reply
|
// handle reply
|
||||||
recvInfo(false);
|
recvInfo(false);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
~CClientProxy1_0();
|
~CClientProxy1_0();
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual bool open();
|
virtual void open();
|
||||||
virtual void mainLoop();
|
virtual void mainLoop();
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -399,6 +399,7 @@ CMSWindowsPrimaryScreen::onPreOpen()
|
||||||
// initialize hook library
|
// initialize hook library
|
||||||
m_threadID = GetCurrentThreadId();
|
m_threadID = GetCurrentThreadId();
|
||||||
if (m_init(m_threadID) == 0) {
|
if (m_init(m_threadID) == 0) {
|
||||||
|
log((CLOG_ERR "cannot initialize hook library"));
|
||||||
throw XScreenOpenFailure();
|
throw XScreenOpenFailure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CPrimaryClient.h"
|
#include "CPrimaryClient.h"
|
||||||
#include "IPrimaryScreenFactory.h"
|
#include "IPrimaryScreenFactory.h"
|
||||||
#include "IServer.h"
|
#include "IServer.h"
|
||||||
|
#include "XScreen.h"
|
||||||
#include "XSynergy.h"
|
#include "XSynergy.h"
|
||||||
#include "CPrimaryScreen.h"
|
#include "CPrimaryScreen.h"
|
||||||
#include "CClipboard.h"
|
#include "CClipboard.h"
|
||||||
|
@ -19,11 +20,15 @@ CPrimaryClient::CPrimaryClient(IPrimaryScreenFactory* screenFactory,
|
||||||
m_seqNum(0)
|
m_seqNum(0)
|
||||||
{
|
{
|
||||||
assert(m_server != NULL);
|
assert(m_server != NULL);
|
||||||
assert(screenFactory != NULL);
|
|
||||||
|
|
||||||
// create screen
|
// create screen
|
||||||
log((CLOG_DEBUG1 "creating primary screen"));
|
log((CLOG_DEBUG1 "creating primary screen"));
|
||||||
|
if (screenFactory != NULL) {
|
||||||
m_screen = screenFactory->create(this, receiver);
|
m_screen = screenFactory->create(this, receiver);
|
||||||
|
}
|
||||||
|
if (m_screen == NULL) {
|
||||||
|
throw XScreenOpenFailure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPrimaryClient::~CPrimaryClient()
|
CPrimaryClient::~CPrimaryClient()
|
||||||
|
@ -100,7 +105,7 @@ CPrimaryClient::onClipboardChanged(ClipboardID id, const CString& data)
|
||||||
m_server->onClipboardChanged(id, m_seqNum, data);
|
m_server->onClipboardChanged(id, m_seqNum, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
CPrimaryClient::open()
|
CPrimaryClient::open()
|
||||||
{
|
{
|
||||||
// all clipboards are clean
|
// all clipboards are clean
|
||||||
|
@ -110,8 +115,6 @@ CPrimaryClient::open()
|
||||||
|
|
||||||
// now open the screen
|
// now open the screen
|
||||||
m_screen->open();
|
m_screen->open();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -20,8 +20,9 @@ treated as if it was on a client.
|
||||||
class CPrimaryClient : public IScreenReceiver, public IClient {
|
class CPrimaryClient : public IScreenReceiver, public IClient {
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
\c name is the name of the server. the caller retains ownership of
|
\c name is the name of the server. The caller retains ownership of
|
||||||
\c factory.
|
\c factory. Throws XScreenOpenFailure or whatever the factory can
|
||||||
|
throw if the screen cannot be created.
|
||||||
*/
|
*/
|
||||||
CPrimaryClient(IPrimaryScreenFactory* factory, IServer*,
|
CPrimaryClient(IPrimaryScreenFactory* factory, IServer*,
|
||||||
IPrimaryScreenReceiver*, const CString& name);
|
IPrimaryScreenReceiver*, const CString& name);
|
||||||
|
@ -75,7 +76,7 @@ public:
|
||||||
virtual void onClipboardChanged(ClipboardID, const CString&);
|
virtual void onClipboardChanged(ClipboardID, const CString&);
|
||||||
|
|
||||||
// IClient overrides
|
// IClient overrides
|
||||||
virtual bool open();
|
virtual void open();
|
||||||
virtual void mainLoop();
|
virtual void mainLoop();
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
virtual void enter(SInt32 xAbs, SInt32 yAbs,
|
||||||
|
|
|
@ -53,24 +53,23 @@ CServer::~CServer()
|
||||||
delete m_streamFilterFactory;
|
delete m_streamFilterFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
CServer::open()
|
CServer::open()
|
||||||
{
|
{
|
||||||
// open the screen
|
// open the screen
|
||||||
try {
|
try {
|
||||||
log((CLOG_INFO "opening screen"));
|
log((CLOG_INFO "opening screen"));
|
||||||
openPrimaryScreen();
|
openPrimaryScreen();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch (XScreenOpenFailure&) {
|
catch (XScreen&) {
|
||||||
// can't open screen yet. wait a few seconds to retry.
|
// can't open screen
|
||||||
log((CLOG_INFO "failed to open screen"));
|
log((CLOG_INFO "failed to open screen"));
|
||||||
return false;
|
throw;
|
||||||
}
|
}
|
||||||
catch (XUnknownClient& e) {
|
catch (XUnknownClient& e) {
|
||||||
// can't open screen yet. wait a few seconds to retry.
|
// can't open screen
|
||||||
log((CLOG_CRIT "unknown screen name `%s'", e.getName().c_str()));
|
log((CLOG_CRIT "unknown screen name `%s'", e.getName().c_str()));
|
||||||
return false;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1529,7 +1528,6 @@ void
|
||||||
CServer::openPrimaryScreen()
|
CServer::openPrimaryScreen()
|
||||||
{
|
{
|
||||||
assert(m_primaryClient == NULL);
|
assert(m_primaryClient == NULL);
|
||||||
assert(m_screenFactory != NULL);
|
|
||||||
|
|
||||||
// reset sequence number
|
// reset sequence number
|
||||||
m_seqNum = 0;
|
m_seqNum = 0;
|
||||||
|
|
|
@ -39,9 +39,12 @@ public:
|
||||||
|
|
||||||
//! Open server
|
//! Open server
|
||||||
/*!
|
/*!
|
||||||
Open the server and return true iff successful.
|
Open the server. Throws XScreenUnavailable if the server's
|
||||||
|
screen cannot be opened but might be available after some time.
|
||||||
|
Otherwise throws some other exception if the server's screen or
|
||||||
|
the server cannot be opened and retrying won't help.
|
||||||
*/
|
*/
|
||||||
bool open();
|
void open();
|
||||||
|
|
||||||
//! Server main loop
|
//! Server main loop
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -19,9 +19,11 @@ public:
|
||||||
|
|
||||||
//! Open client
|
//! Open client
|
||||||
/*!
|
/*!
|
||||||
Open the client and return true iff successful.
|
Open the client. Throw if the client cannot be opened. If the
|
||||||
|
screen cannot be opened but retrying later may succeed then throw
|
||||||
|
XScreenUnavailable.
|
||||||
*/
|
*/
|
||||||
virtual bool open() = 0;
|
virtual void open() = 0;
|
||||||
|
|
||||||
//! Client main loop
|
//! Client main loop
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -19,7 +19,9 @@ public:
|
||||||
|
|
||||||
//! Open screen
|
//! Open screen
|
||||||
/*!
|
/*!
|
||||||
Called to open and initialize the screen.
|
Called to open and initialize the screen. Throw XScreenUnavailable
|
||||||
|
if the screen cannot be opened but retrying later may succeed.
|
||||||
|
Otherwise throw some other XScreenOpenFailure exception.
|
||||||
*/
|
*/
|
||||||
virtual void open() = 0;
|
virtual void open() = 0;
|
||||||
|
|
||||||
|
|
|
@ -9,3 +9,31 @@ XScreenOpenFailure::getWhat() const throw()
|
||||||
{
|
{
|
||||||
return format("XScreenOpenFailure", "unable to open screen");
|
return format("XScreenOpenFailure", "unable to open screen");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// XScreenUnavailable
|
||||||
|
//
|
||||||
|
|
||||||
|
XScreenUnavailable::XScreenUnavailable(double timeUntilRetry) :
|
||||||
|
m_timeUntilRetry(timeUntilRetry)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
XScreenUnavailable::~XScreenUnavailable()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
XScreenUnavailable::getRetryTime() const
|
||||||
|
{
|
||||||
|
return m_timeUntilRetry;
|
||||||
|
}
|
||||||
|
|
||||||
|
CString
|
||||||
|
XScreenUnavailable::getWhat() const throw()
|
||||||
|
{
|
||||||
|
return format("XScreenUnavailable", "unable to open screen");
|
||||||
|
}
|
||||||
|
|
|
@ -15,4 +15,36 @@ protected:
|
||||||
virtual CString getWhat() const throw();
|
virtual CString getWhat() const throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Screen unavailable exception
|
||||||
|
/*!
|
||||||
|
Thrown when a screen cannot be opened or initialized but retrying later
|
||||||
|
may be successful.
|
||||||
|
*/
|
||||||
|
class XScreenUnavailable : public XScreenOpenFailure {
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
\c timeUntilRetry is the suggested time the caller should wait until
|
||||||
|
trying to open the screen again.
|
||||||
|
*/
|
||||||
|
XScreenUnavailable(double timeUntilRetry);
|
||||||
|
virtual ~XScreenUnavailable();
|
||||||
|
|
||||||
|
//! @name manipulators
|
||||||
|
//@{
|
||||||
|
|
||||||
|
//! Get retry time
|
||||||
|
/*!
|
||||||
|
Returns the suggested time to wait until retrying to open the screen.
|
||||||
|
*/
|
||||||
|
double getRetryTime() const;
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual CString getWhat() const throw();
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_timeUntilRetry;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue