Changed server to fail with an error if in can't bind() the listen
socket for any reason other than it's in use.
This commit is contained in:
parent
586a5a81ab
commit
1d7f3d2aaf
|
@ -46,6 +46,7 @@ const SInt32 CServer::s_httpMaxSimultaneousRequests = 3;
|
|||
|
||||
CServer::CServer(const CString& serverName) :
|
||||
m_name(serverName),
|
||||
m_error(false),
|
||||
m_bindTimeout(5.0 * 60.0),
|
||||
m_screenFactory(NULL),
|
||||
m_socketFactory(NULL),
|
||||
|
@ -161,6 +162,12 @@ CServer::mainLoop()
|
|||
throw;
|
||||
}
|
||||
#undef FINALLY
|
||||
|
||||
// throw if there was an error
|
||||
if (m_error) {
|
||||
LOG((CLOG_DEBUG "forwarding child thread exception"));
|
||||
throw XServerRethrow();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -169,6 +176,16 @@ CServer::exitMainLoop()
|
|||
m_primaryClient->exitMainLoop();
|
||||
}
|
||||
|
||||
void
|
||||
CServer::exitMainLoopWithError()
|
||||
{
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
m_error = true;
|
||||
}
|
||||
exitMainLoop();
|
||||
}
|
||||
|
||||
void
|
||||
CServer::close()
|
||||
{
|
||||
|
@ -1186,7 +1203,7 @@ CServer::acceptClients(void*)
|
|||
listen->bind(m_config.getSynergyAddress());
|
||||
break;
|
||||
}
|
||||
catch (XSocketBind& e) {
|
||||
catch (XSocketAddressInUse& e) {
|
||||
LOG((CLOG_WARN "bind failed: %s", e.getErrstr()));
|
||||
|
||||
// give up if we've waited too long
|
||||
|
@ -1220,7 +1237,7 @@ CServer::acceptClients(void*)
|
|||
catch (XBase& e) {
|
||||
LOG((CLOG_ERR "cannot listen for clients: %s", e.what()));
|
||||
delete listen;
|
||||
exitMainLoop();
|
||||
exitMainLoopWithError();
|
||||
}
|
||||
catch (...) {
|
||||
delete listen;
|
||||
|
@ -1505,7 +1522,7 @@ CServer::acceptHTTPClients(void*)
|
|||
catch (XBase& e) {
|
||||
LOG((CLOG_ERR "cannot listen for HTTP clients: %s", e.what()));
|
||||
delete listen;
|
||||
exitMainLoop();
|
||||
exitMainLoopWithError();
|
||||
}
|
||||
catch (...) {
|
||||
delete listen;
|
||||
|
@ -1691,6 +1708,17 @@ CServer::removeConnection(const CString& name)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// CServer::CClipboardInfo
|
||||
//
|
||||
|
||||
CString
|
||||
CServer::XServerRethrow::getWhat() const throw()
|
||||
{
|
||||
return format("XServerRethrow", "child thread failed");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CServer::CClipboardInfo
|
||||
//
|
||||
|
|
|
@ -157,6 +157,14 @@ protected:
|
|||
*/
|
||||
bool onCommandKey(KeyID, KeyModifierMask, bool down);
|
||||
|
||||
//! Exit event loop and note an error condition
|
||||
/*!
|
||||
Force mainLoop() to return by throwing an exception. This call
|
||||
can return before mainLoop() does (i.e. asynchronously). This
|
||||
may only be called between a successful open() and close().
|
||||
*/
|
||||
void exitMainLoopWithError();
|
||||
|
||||
private:
|
||||
typedef std::list<CThread> CThreadList;
|
||||
|
||||
|
@ -230,6 +238,12 @@ private:
|
|||
void removeConnection(const CString& name);
|
||||
|
||||
private:
|
||||
class XServerRethrow : public XBase {
|
||||
protected:
|
||||
// XBase overrides
|
||||
virtual CString getWhat() const throw();
|
||||
};
|
||||
|
||||
class CClipboardInfo {
|
||||
public:
|
||||
CClipboardInfo();
|
||||
|
@ -246,6 +260,14 @@ private:
|
|||
// the name of the primary screen
|
||||
CString m_name;
|
||||
|
||||
// true if we should exit the main loop by throwing an exception.
|
||||
// this is used to propagate an exception from one of our threads
|
||||
// to the mainLoop() thread. but, since we can't make a copy of
|
||||
// the original exception, we return an arbitrary, unique
|
||||
// exception type. the caller of mainLoop() cannot catch this
|
||||
// exception except through XBase or ....
|
||||
bool m_error;
|
||||
|
||||
// how long to wait to bind our socket until we give up
|
||||
double m_bindTimeout;
|
||||
|
||||
|
|
Loading…
Reference in New Issue