From 70cfc74ce16c58f775811dd98f88c0da02369248 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Tue, 1 Jun 2010 21:29:38 +0000 Subject: [PATCH] Improve fix for issue 479 --- lib/arch/CArch.cpp | 6 ++++ lib/arch/CArch.h | 1 + lib/arch/CArchAppUtil.cpp | 1 + lib/arch/CArchAppUtil.h | 4 +++ lib/arch/CArchAppUtilWindows.cpp | 56 ++++++++++++++++---------------- lib/arch/CArchAppUtilWindows.h | 19 +++++++---- lib/arch/IArchAppUtil.h | 1 + lib/synergy/CApp.cpp | 2 ++ lib/synergy/CClientApp.cpp | 19 ++++++++--- 9 files changed, 69 insertions(+), 40 deletions(-) diff --git a/lib/arch/CArch.cpp b/lib/arch/CArch.cpp index 7d31bf3e..823d2d7e 100644 --- a/lib/arch/CArch.cpp +++ b/lib/arch/CArch.cpp @@ -670,3 +670,9 @@ CArch::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceive { return m_appUtil->run(argc, argv, createTaskBarReceiver); } + +void +CArch::beforeAppExit() +{ + m_appUtil->beforeAppExit(); +} diff --git a/lib/arch/CArch.h b/lib/arch/CArch.h index a7bcf935..9eda5863 100644 --- a/lib/arch/CArch.h +++ b/lib/arch/CArch.h @@ -188,6 +188,7 @@ public: virtual void adoptApp(CApp* app); virtual CApp& app() const; virtual int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver); + virtual void beforeAppExit(); private: static CArch* s_instance; diff --git a/lib/arch/CArchAppUtil.cpp b/lib/arch/CArchAppUtil.cpp index ec8b072a..2ccf1d7d 100644 --- a/lib/arch/CArchAppUtil.cpp +++ b/lib/arch/CArchAppUtil.cpp @@ -37,6 +37,7 @@ CArchAppUtil::parseArg(const int& argc, const char* const* argv, int& i) void CArchAppUtil::adoptApp(CApp* app) { + app->m_bye = &exitAppStatic; m_app = app; } diff --git a/lib/arch/CArchAppUtil.h b/lib/arch/CArchAppUtil.h index 5b74f648..7e2b6ba0 100644 --- a/lib/arch/CArchAppUtil.h +++ b/lib/arch/CArchAppUtil.h @@ -15,6 +15,7 @@ #pragma once #include "IArchAppUtil.h" +#include "XSynergy.h" class CArchAppUtil : public IArchAppUtil { public: @@ -24,8 +25,11 @@ public: virtual bool parseArg(const int& argc, const char* const* argv, int& i); virtual void adoptApp(CApp* app); CApp& app() const; + virtual void exitApp(int code) { throw XExitApp(code); } static CArchAppUtil& instance(); + static void exitAppStatic(int code) { instance().exitApp(code); } + virtual void beforeAppExit() {} private: CApp* m_app; diff --git a/lib/arch/CArchAppUtilWindows.cpp b/lib/arch/CArchAppUtilWindows.cpp index e3567d0e..06089a07 100644 --- a/lib/arch/CArchAppUtilWindows.cpp +++ b/lib/arch/CArchAppUtilWindows.cpp @@ -26,7 +26,8 @@ #include #include -CArchAppUtilWindows::CArchAppUtilWindows() +CArchAppUtilWindows::CArchAppUtilWindows() : +m_exitMode(kExitModeNormal) { } @@ -67,13 +68,6 @@ CArchAppUtilWindows::parseArg(const int& argc, const char* const* argv, int& i) return true; } -void -CArchAppUtilWindows::adoptApp(CApp* app) -{ - app->m_bye = &exitPause; - CArchAppUtil::adoptApp(app); -} - CString CArchAppUtilWindows::getServiceArgs() const { @@ -176,23 +170,6 @@ CArchAppUtilWindows::stopService() LOG((CLOG_INFO "service '%s' stopping asyncronously", app().daemonName())); } -void -exitPause(int code) -{ - CString name; - CArchMiscWindows::getParentProcessName(name); - - // if the user did not launch from the command prompt (i.e. it was launched - // by double clicking, or through a debugger), allow user to read any error - // messages (instead of the window closing automatically). - if (name != "cmd.exe") { - std::cout << std::endl << "Press any key to exit..." << std::endl; - int c = _getch(); - } - - throw XExitApp(code); -} - static int mainLoopStatic() @@ -210,9 +187,17 @@ CArchAppUtilWindows::daemonNTMainLoop(int argc, const char** argv) } void -CArchAppUtilWindows::byeThrow(int x) +CArchAppUtilWindows::exitApp(int code) { - CArchMiscWindows::daemonFailed(x); + switch (m_exitMode) { + + case kExitModeDaemon: + CArchMiscWindows::daemonFailed(code); + break; + + default: + throw XExitApp(code); + } } int daemonNTMainLoopStatic(int argc, const char** argv) @@ -224,7 +209,7 @@ int CArchAppUtilWindows::daemonNTStartup(int, char**) { CSystemLogger sysLogger(app().daemonName(), false); - app().m_bye = &byeThrow; + m_exitMode = kExitModeDaemon; return ARCH->daemonize(app().daemonName(), daemonNTMainLoopStatic); } @@ -242,6 +227,21 @@ foregroundStartupStatic(int argc, char** argv) return CArchAppUtil::instance().app().foregroundStartup(argc, argv); } +void +CArchAppUtilWindows::beforeAppExit() +{ + CString name; + CArchMiscWindows::getParentProcessName(name); + + // if the user did not launch from the command prompt (i.e. it was launched + // by double clicking, or through a debugger), allow user to read any error + // messages (instead of the window closing automatically). + if (name != "cmd.exe") { + std::cout << std::endl << "Press any key to exit..." << std::endl; + int c = _getch(); + } +} + int CArchAppUtilWindows::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver) { diff --git a/lib/arch/CArchAppUtilWindows.h b/lib/arch/CArchAppUtilWindows.h index 81d1b0d1..b4dc3d52 100644 --- a/lib/arch/CArchAppUtilWindows.h +++ b/lib/arch/CArchAppUtilWindows.h @@ -21,6 +21,11 @@ #define ARCH_APPUTIL CArchAppUtilWindows +enum AppExitMode { + kExitModeNormal, + kExitModeDaemon +}; + class CArchAppUtilWindows : public CArchAppUtil { public: CArchAppUtilWindows(); @@ -44,9 +49,7 @@ public: // Will install, uninstall, start, or stop the service depending on arg. void handleServiceArg(const char* serviceAction); - bool parseArg(const int& argc, const char* const* argv, int& i); - - void adoptApp(CApp* app); + bool parseArg(const int& argc, const char* const* argv, int& i); int daemonNTStartup(int, char**); @@ -54,10 +57,12 @@ public: int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver); - static void byeThrow(int x); + void exitApp(int code); + + void beforeAppExit(); static CArchAppUtilWindows& instance(); -}; -// TODO: move to class -void exitPause(int code); +private: + AppExitMode m_exitMode; +}; diff --git a/lib/arch/IArchAppUtil.h b/lib/arch/IArchAppUtil.h index 8b79c86f..a43220c7 100644 --- a/lib/arch/IArchAppUtil.h +++ b/lib/arch/IArchAppUtil.h @@ -26,4 +26,5 @@ public: virtual void adoptApp(CApp* app) = 0; virtual CApp& app() const = 0; virtual int run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver) = 0; + virtual void beforeAppExit() = 0; }; diff --git a/lib/synergy/CApp.cpp b/lib/synergy/CApp.cpp index 998ab0cd..6b03c303 100644 --- a/lib/synergy/CApp.cpp +++ b/lib/synergy/CApp.cpp @@ -255,6 +255,8 @@ CApp::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver } delete CLOG; + + ARCH->beforeAppExit(); return result; } diff --git a/lib/synergy/CClientApp.cpp b/lib/synergy/CClientApp.cpp index fb92dbc2..5d4edec8 100644 --- a/lib/synergy/CClientApp.cpp +++ b/lib/synergy/CClientApp.cpp @@ -605,12 +605,21 @@ CClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFun // through the task bar. s_taskBarReceiver = createTaskBarReceiver(logBuffer); - // run - int result = startup(argc, argv); + int result; + try + { + // run + result = startup(argc, argv); + } + catch (...) + { + // done with task bar receiver + delete s_taskBarReceiver; - // done with task bar receiver - delete s_taskBarReceiver; + delete args().m_serverAddress; + + throw; + } - delete args().m_serverAddress; return result; }