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:
crs 2002-07-31 12:39:34 +00:00
parent f5795a6630
commit 5e40de48f9
18 changed files with 141 additions and 59 deletions

View File

@ -3,6 +3,7 @@
#include "CPlatform.h"
#include "ProtocolTypes.h"
#include "Version.h"
#include "XScreen.h"
#include "CNetwork.h"
#include "CNetworkAddress.h"
#include "CTCPSocketFactory.h"
@ -125,7 +126,8 @@ realMain(CMutex* mutex)
s_client->setStreamFilterFactory(NULL);
// open client
if (s_client->open()) {
try {
s_client->open();
opened = true;
// run client
@ -139,31 +141,33 @@ realMain(CMutex* mutex)
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
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
if (s_restartable) {
CThread::sleep(3.0);
CThread::sleep(e.getRetryTime());
}
else {
result = kExitFailed;
}
}
catch (...) {
// rethrow thread exceptions
RETHROW_XTHREAD
// don't try to restart and fail
s_restartable = false;
result = kExitFailed;
}
// clean up
delete s_client;

View File

@ -4,6 +4,7 @@
#include "CPlatform.h"
#include "ProtocolTypes.h"
#include "Version.h"
#include "XScreen.h"
#include "CNetwork.h"
#include "CTCPSocketFactory.h"
#include "XSocket.h"
@ -156,7 +157,8 @@ realMain(CMutex* mutex)
s_server->setStreamFilterFactory(NULL);
// open server
if (s_server->open()) {
try {
s_server->open();
opened = true;
// run server (unlocked)
@ -173,15 +175,23 @@ realMain(CMutex* mutex)
// clean up
s_server->close();
}
else {
// wait a few seconds before retrying
catch (XScreenUnavailable& e) {
// wait before retrying if we're going to retry
if (s_restartable) {
CThread::sleep(3.0);
CThread::sleep(e.getRetryTime());
}
else {
result = kExitFailed;
}
}
catch (...) {
// rethrow thread exceptions
RETHROW_XTHREAD
// don't try to restart and fail
s_restartable = false;
result = kExitFailed;
}
// clean up
delete s_server;

View File

@ -149,19 +149,18 @@ CClient::onClipboardChanged(ClipboardID, const CString&)
// ignore -- we'll check the clipboard when we leave
}
bool
void
CClient::open()
{
// open the screen
try {
log((CLOG_INFO "opening screen"));
openSecondaryScreen();
return true;
}
catch (XScreenOpenFailure&) {
// can't open screen yet. wait a few seconds to retry.
// can't open screen
log((CLOG_INFO "failed to open screen"));
return false;
throw;
}
}
@ -368,7 +367,6 @@ void
CClient::openSecondaryScreen()
{
assert(m_screen == NULL);
assert(m_screenFactory != NULL);
// not active
m_active = false;
@ -381,7 +379,9 @@ CClient::openSecondaryScreen()
// create screen
log((CLOG_DEBUG1 "creating secondary screen"));
if (m_screenFactory != NULL) {
m_screen = m_screenFactory->create(this);
}
if (m_screen == NULL) {
throw XScreenOpenFailure();
}
@ -402,13 +402,13 @@ CClient::openSecondaryScreen()
void
CClient::closeSecondaryScreen()
{
assert(m_screen != NULL);
// close the secondary screen
try {
if (m_screen != NULL) {
log((CLOG_DEBUG1 "closing secondary screen"));
m_screen->close();
}
}
catch (...) {
// ignore
}

View File

@ -98,7 +98,7 @@ public:
virtual void onClipboardChanged(ClipboardID, const CString&);
// IClient overrides
virtual bool open();
virtual void open();
virtual void mainLoop();
virtual void close();
virtual void enter(SInt32 xAbs, SInt32 yAbs,

View File

@ -229,7 +229,7 @@ CXWindowsSecondaryScreen::createWindow()
int majorOpcode, firstEvent, firstError;
if (!XQueryExtension(display, XTestExtensionName,
&majorOpcode, &firstEvent, &firstError)) {
// FIXME -- subclass exception for more info?
log((CLOG_ERR "XTEST extension not available"));
throw XScreenOpenFailure();
}

View File

@ -197,7 +197,7 @@ CXWindowsScreen::open()
log((CLOG_DEBUG "XOpenDisplay(\"%s\")", display));
m_display = XOpenDisplay(display);
if (m_display == NULL) {
throw XScreenOpenFailure();
throw XScreenUnavailable(60.0);
}
// get root window

View File

@ -43,7 +43,7 @@ public:
//@}
// IClient overrides
virtual bool open() = 0;
virtual void open() = 0;
virtual void mainLoop() = 0;
virtual void close() = 0;
virtual void enter(SInt32 xAbs, SInt32 yAbs,

View File

@ -29,7 +29,7 @@ CClientProxy1_0::~CClientProxy1_0()
// do nothing
}
bool
void
CClientProxy1_0::open()
{
// send request
@ -55,8 +55,6 @@ CClientProxy1_0::open()
// handle reply
recvInfo(false);
return true;
}
void

View File

@ -14,7 +14,7 @@ public:
~CClientProxy1_0();
// IClient overrides
virtual bool open();
virtual void open();
virtual void mainLoop();
virtual void close();
virtual void enter(SInt32 xAbs, SInt32 yAbs,

View File

@ -399,6 +399,7 @@ CMSWindowsPrimaryScreen::onPreOpen()
// initialize hook library
m_threadID = GetCurrentThreadId();
if (m_init(m_threadID) == 0) {
log((CLOG_ERR "cannot initialize hook library"));
throw XScreenOpenFailure();
}
}

View File

@ -1,6 +1,7 @@
#include "CPrimaryClient.h"
#include "IPrimaryScreenFactory.h"
#include "IServer.h"
#include "XScreen.h"
#include "XSynergy.h"
#include "CPrimaryScreen.h"
#include "CClipboard.h"
@ -19,11 +20,15 @@ CPrimaryClient::CPrimaryClient(IPrimaryScreenFactory* screenFactory,
m_seqNum(0)
{
assert(m_server != NULL);
assert(screenFactory != NULL);
// create screen
log((CLOG_DEBUG1 "creating primary screen"));
if (screenFactory != NULL) {
m_screen = screenFactory->create(this, receiver);
}
if (m_screen == NULL) {
throw XScreenOpenFailure();
}
}
CPrimaryClient::~CPrimaryClient()
@ -100,7 +105,7 @@ CPrimaryClient::onClipboardChanged(ClipboardID id, const CString& data)
m_server->onClipboardChanged(id, m_seqNum, data);
}
bool
void
CPrimaryClient::open()
{
// all clipboards are clean
@ -110,8 +115,6 @@ CPrimaryClient::open()
// now open the screen
m_screen->open();
return true;
}
void

View File

@ -20,8 +20,9 @@ treated as if it was on a client.
class CPrimaryClient : public IScreenReceiver, public IClient {
public:
/*!
\c name is the name of the server. the caller retains ownership of
\c factory.
\c name is the name of the server. The caller retains ownership of
\c factory. Throws XScreenOpenFailure or whatever the factory can
throw if the screen cannot be created.
*/
CPrimaryClient(IPrimaryScreenFactory* factory, IServer*,
IPrimaryScreenReceiver*, const CString& name);
@ -75,7 +76,7 @@ public:
virtual void onClipboardChanged(ClipboardID, const CString&);
// IClient overrides
virtual bool open();
virtual void open();
virtual void mainLoop();
virtual void close();
virtual void enter(SInt32 xAbs, SInt32 yAbs,

View File

@ -53,24 +53,23 @@ CServer::~CServer()
delete m_streamFilterFactory;
}
bool
void
CServer::open()
{
// open the screen
try {
log((CLOG_INFO "opening screen"));
openPrimaryScreen();
return true;
}
catch (XScreenOpenFailure&) {
// can't open screen yet. wait a few seconds to retry.
catch (XScreen&) {
// can't open screen
log((CLOG_INFO "failed to open screen"));
return false;
throw;
}
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()));
return false;
throw;
}
}
@ -1529,7 +1528,6 @@ void
CServer::openPrimaryScreen()
{
assert(m_primaryClient == NULL);
assert(m_screenFactory != NULL);
// reset sequence number
m_seqNum = 0;

View File

@ -39,9 +39,12 @@ public:
//! 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
/*!

View File

@ -19,9 +19,11 @@ public:
//! 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
/*!

View File

@ -19,7 +19,9 @@ public:
//! 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;

View File

@ -9,3 +9,31 @@ XScreenOpenFailure::getWhat() const throw()
{
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");
}

View File

@ -15,4 +15,36 @@ protected:
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