From c405c58c64d9a78d47b3b0f10e769f9b4de6f711 Mon Sep 17 00:00:00 2001 From: crs Date: Tue, 15 Oct 2002 22:01:41 +0000 Subject: [PATCH] Renamed XThreadUnavailable to XMTThreadUnavailable and derived it from XBase so it can be caught normally. Changed client and server to handle unavailable threads (in main loop, anyway). --- lib/client/CClient.cpp | 9 +++++++++ lib/mt/CThreadRep.cpp | 5 +++-- lib/mt/Makefile.am | 2 ++ lib/mt/XMT.cpp | 25 +++++++++++++++++++++++++ lib/mt/XMT.h | 33 +++++++++++++++++++++++++++++++++ lib/mt/XThread.h | 11 +++++------ lib/server/CServer.cpp | 9 +++++++++ 7 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 lib/mt/XMT.cpp create mode 100644 lib/mt/XMT.h diff --git a/lib/client/CClient.cpp b/lib/client/CClient.cpp index 44076bd0..2238f287 100644 --- a/lib/client/CClient.cpp +++ b/lib/client/CClient.cpp @@ -31,6 +31,7 @@ #include "CLock.h" #include "CThread.h" #include "CTimerThread.h" +#include "XMT.h" #include "XThread.h" #include "CLog.h" #include "CStopwatch.h" @@ -209,6 +210,14 @@ CClient::mainLoop() deleteSession(); LOG((CLOG_NOTE "stopping client \"%s\"", m_name.c_str())); } + catch (XMT& e) { + LOG((CLOG_ERR "client error: %s", e.what())); + + // clean up + deleteSession(); + LOG((CLOG_NOTE "stopping client \"%s\"", m_name.c_str())); + throw; + } catch (XBase& e) { LOG((CLOG_ERR "client error: %s", e.what())); diff --git a/lib/mt/CThreadRep.cpp b/lib/mt/CThreadRep.cpp index a60254b5..56ec0c41 100644 --- a/lib/mt/CThreadRep.cpp +++ b/lib/mt/CThreadRep.cpp @@ -16,6 +16,7 @@ #include "CLock.h" #include "CMutex.h" #include "CThread.h" +#include "XMT.h" #include "XThread.h" #include "CLog.h" #include "IJob.h" @@ -113,7 +114,7 @@ CThreadRep::CThreadRep(IJob* job, void* userData) : status = pthread_create(&m_thread, &attr, threadFunc, (void*)this); pthread_sigmask(SIG_SETMASK, &oldsigset, NULL); if (status != 0) { - throw XThreadUnavailable(); + throw XMTThreadUnavailable(); } #elif WINDOWS_LIKE unsigned int id; @@ -121,7 +122,7 @@ CThreadRep::CThreadRep(IJob* job, void* userData) : threadFunc, (void*)this, 0, &id)); m_id = static_cast(id); if (m_thread == 0) { - throw XThreadUnavailable(); + throw XMTThreadUnavailable(); } #endif diff --git a/lib/mt/Makefile.am b/lib/mt/Makefile.am index 5db01822..baf32d7e 100644 --- a/lib/mt/Makefile.am +++ b/lib/mt/Makefile.am @@ -31,12 +31,14 @@ libmt_a_SOURCES = \ CThread.cpp \ CThreadRep.cpp \ CTimerThread.cpp \ + XMT.cpp \ CCondVar.h \ CLock.h \ CMutex.h \ CThread.h \ CThreadRep.h \ CTimerThread.h \ + XMT.h \ XThread.h \ $(NULL) INCLUDES = \ diff --git a/lib/mt/XMT.cpp b/lib/mt/XMT.cpp new file mode 100644 index 00000000..b10d2d79 --- /dev/null +++ b/lib/mt/XMT.cpp @@ -0,0 +1,25 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "XMT.h" + +// +// XMTThreadUnavailable +// + +CString +XMTThreadUnavailable::getWhat() const throw() +{ + return format("XMTThreadUnavailable", "cannot create thread"); +} diff --git a/lib/mt/XMT.h b/lib/mt/XMT.h new file mode 100644 index 00000000..32ca9aaa --- /dev/null +++ b/lib/mt/XMT.h @@ -0,0 +1,33 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef XMT_H +#define XMT_H + +#include "XBase.h" + +//! Generic multithreading exception +class XMT : public XBase { }; + +//! Thread creation exception +/*! +Thrown when a thread cannot be created. +*/ +class XMTThreadUnavailable : public XMT { +protected: + // XBase overrides + virtual CString getWhat() const throw(); +}; + +#endif diff --git a/lib/mt/XThread.h b/lib/mt/XThread.h index ac820795..b76c9933 100644 --- a/lib/mt/XThread.h +++ b/lib/mt/XThread.h @@ -16,6 +16,11 @@ #define XTHREAD_H //! Generic thread exception +/*! +Exceptions derived from this class are used by the multithreading +library to perform stack unwinding when a thread terminates. These +exceptions must always be rethrown by clients when caught. +*/ class XThread { }; //! Thread exception to exit @@ -41,12 +46,6 @@ must rethrow it if caught (by XThreadCancel, XThread, or ...). */ class XThreadCancel : public XThread { }; -//! Thread creation exception -/*! -Thrown when a thread cannot be created. -*/ -class XThreadUnavailable { }; - /*! \def RETHROW_XTHREAD Convenience macro to rethrow an XThread exception but ignore other diff --git a/lib/server/CServer.cpp b/lib/server/CServer.cpp index 9be9b299..a4d124f0 100644 --- a/lib/server/CServer.cpp +++ b/lib/server/CServer.cpp @@ -31,6 +31,7 @@ #include "CLock.h" #include "CThread.h" #include "CTimerThread.h" +#include "XMT.h" #include "XThread.h" #include "CFunctionJob.h" #include "CLog.h" @@ -130,6 +131,14 @@ CServer::mainLoop() } while (false) FINALLY; } + catch (XMT& e) { + LOG((CLOG_ERR "server error: %s", e.what())); + + // clean up + LOG((CLOG_NOTE "stopping server")); + FINALLY; + throw; + } catch (XBase& e) { LOG((CLOG_ERR "server error: %s", e.what()));