Browse Source

introduce a new StartShutdown() function, which starts a thread with Shutdown() if no GUI is used and calls uiInterface.QueueShutdown() if a GUI is used / all direct uiInterface.QueueShutdown() calls are replaced with Shutdown() - this ensures a clean GUI shutdown, even when catching a SIGTERM and allows the BitcoinGUI destructor to get called (which fixes a tray-icon issue and keeps the tray-icon until Bitcoin-Qt exits)

0.8
Philip Kaufmann 13 years ago
parent
commit
9247134eab
  1. 14
      src/bitcoinrpc.cpp
  2. 14
      src/init.cpp
  3. 1
      src/init.h
  4. 2
      src/main.cpp
  5. 2
      src/net.cpp
  6. 7
      src/noui.cpp
  7. 1
      src/qt/bitcoin.cpp

14
src/bitcoinrpc.cpp

@ -20,7 +20,7 @@
#include <boost/iostreams/stream.hpp> #include <boost/iostreams/stream.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/asio/ssl.hpp> #include <boost/asio/ssl.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream; typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
@ -436,7 +436,7 @@ Value stop(const Array& params, bool fHelp)
"stop\n" "stop\n"
"Stop Bitcoin server."); "Stop Bitcoin server.");
// Shutdown will take long enough that the response should get back // Shutdown will take long enough that the response should get back
uiInterface.QueueShutdown(); StartShutdown();
return "Bitcoin server stopping"; return "Bitcoin server stopping";
} }
@ -1148,7 +1148,7 @@ Value sendmany(const Array& params, bool fHelp)
CScript scriptPubKey; CScript scriptPubKey;
scriptPubKey.SetDestination(address.Get()); scriptPubKey.SetDestination(address.Get());
int64 nAmount = AmountFromValue(s.value_); int64 nAmount = AmountFromValue(s.value_);
totalAmount += nAmount; totalAmount += nAmount;
vecSend.push_back(make_pair(scriptPubKey, nAmount)); vecSend.push_back(make_pair(scriptPubKey, nAmount));
@ -1524,7 +1524,7 @@ Value listtransactions(const Array& params, bool fHelp)
if ((int)ret.size() >= (nCount+nFrom)) break; if ((int)ret.size() >= (nCount+nFrom)) break;
} }
// ret is newest to oldest // ret is newest to oldest
if (nFrom > (int)ret.size()) if (nFrom > (int)ret.size())
nFrom = ret.size(); nFrom = ret.size();
if ((nFrom + nCount) > (int)ret.size()) if ((nFrom + nCount) > (int)ret.size())
@ -1935,7 +1935,7 @@ Value encryptwallet(const Array& params, bool fHelp)
// BDB seems to have a bad habit of writing old data into // BDB seems to have a bad habit of writing old data into
// slack space in .dat files; that is bad if the old data is // slack space in .dat files; that is bad if the old data is
// unencrypted private keys. So: // unencrypted private keys. So:
uiInterface.QueueShutdown(); StartShutdown();
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet"; return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet";
} }
@ -2682,7 +2682,7 @@ void ThreadRPCServer2(void* parg)
GetConfigFile().string().c_str(), GetConfigFile().string().c_str(),
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
_("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
uiInterface.QueueShutdown(); StartShutdown();
return; return;
} }
@ -2703,7 +2703,7 @@ void ThreadRPCServer2(void* parg)
{ {
uiInterface.ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()), uiInterface.ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
_("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
uiInterface.QueueShutdown(); StartShutdown();
return; return;
} }

14
src/init.cpp

@ -38,6 +38,17 @@ void ExitTimeout(void* parg)
#endif #endif
} }
void StartShutdown()
{
#ifdef QT_GUI
// ensure we leave the Qt main loop for a clean GUI exit (Shutdown() is called in bitcoin.cpp afterwards)
uiInterface.QueueShutdown();
#else
// Without UI, Shutdown() can simply be started in a new thread
CreateThread(Shutdown, NULL);
#endif
}
void Shutdown(void* parg) void Shutdown(void* parg)
{ {
static CCriticalSection cs_Shutdown; static CCriticalSection cs_Shutdown;
@ -66,7 +77,10 @@ void Shutdown(void* parg)
Sleep(50); Sleep(50);
printf("Bitcoin exited\n\n"); printf("Bitcoin exited\n\n");
fExit = true; fExit = true;
#ifndef QT_GUI
// ensure non UI client get's exited here, but let Bitcoin-Qt reach return 0; in bitcoin.cpp
exit(0); exit(0);
#endif
} }
else else
{ {

1
src/init.h

@ -9,6 +9,7 @@
extern CWallet* pwalletMain; extern CWallet* pwalletMain;
void StartShutdown();
void Shutdown(void* parg); void Shutdown(void* parg);
bool AppInit2(); bool AppInit2();
std::string HelpMessage(); std::string HelpMessage();

2
src/main.cpp

@ -1875,7 +1875,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
strMiscWarning = strMessage; strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str()); printf("*** %s\n", strMessage.c_str());
uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
uiInterface.QueueShutdown(); StartShutdown();
return false; return false;
} }
return true; return true;

2
src/net.cpp

@ -1658,7 +1658,7 @@ void ThreadMessageHandler2(void* parg)
vnThreadsRunning[THREAD_MESSAGEHANDLER]--; vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
Sleep(100); Sleep(100);
if (fRequestShutdown) if (fRequestShutdown)
Shutdown(NULL); StartShutdown();
vnThreadsRunning[THREAD_MESSAGEHANDLER]++; vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
if (fShutdown) if (fShutdown)
return; return;

7
src/noui.cpp

@ -20,16 +20,9 @@ static bool noui_ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCapt
return true; return true;
} }
static void noui_QueueShutdown()
{
// Without UI, Shutdown can simply be started in a new thread
CreateThread(Shutdown, NULL);
}
void noui_connect() void noui_connect()
{ {
// Connect bitcoind signal handlers // Connect bitcoind signal handlers
uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox); uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee); uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee);
uiInterface.QueueShutdown.connect(noui_QueueShutdown);
} }

1
src/qt/bitcoin.cpp

@ -290,6 +290,7 @@ int main(int argc, char *argv[])
window.setWalletModel(0); window.setWalletModel(0);
guiref = 0; guiref = 0;
} }
// Shutdown the core and it's threads, but don't exit Bitcoin-Qt here
Shutdown(NULL); Shutdown(NULL);
} }
else else

Loading…
Cancel
Save