From 300d4608f2504e3e4a02a13b6c6000b52c436975 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 6 Nov 2009 05:50:05 +0000 Subject: [PATCH] got rid of CheckForShutdown, replaced some thread-unsafe wxWidgets calls, Linux fixes, socket send MSG_NOSIGNAL, bind INADDR_ANY, works reliably on Linux now except if wxMessageBox is used in a thread other than the GUI thread git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@33 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 2 +- irc.cpp | 9 ++- main.cpp | 67 +++++++++++------- main.h | 2 +- net.cpp | 193 ++++++++++++++++++++++++++------------------------ net.h | 2 +- ui.cpp | 63 ++++++++++++---- ui.h | 3 +- uibase.cpp | 60 ++-------------- uiproject.fbp | 68 +++++++++--------- util.cpp | 12 ++-- util.h | 14 +++- 12 files changed, 260 insertions(+), 235 deletions(-) diff --git a/db.cpp b/db.cpp index b702b0cba..123559263 100644 --- a/db.cpp +++ b/db.cpp @@ -550,7 +550,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); //printf(" %12I64d %s %s %s\n", // wtx.vout[0].nValue, - // DateTimeStr(wtx.nTime).c_str(), + // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(), // wtx.hashBlock.ToString().substr(0,14).c_str(), // wtx.mapValue["message"].c_str()); } diff --git a/irc.cpp b/irc.cpp index 4d4ed0f41..3b232caea 100644 --- a/irc.cpp +++ b/irc.cpp @@ -167,9 +167,12 @@ void ThreadIRCSeed(void* parg) while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); - struct hostent* phostent = gethostbyname("chat.freenode.net"); - if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) - addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + if (!(fUseProxy && addrProxy.port == htons(9050))) + { + struct hostent* phostent = gethostbyname("chat.freenode.net"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + } SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) diff --git a/main.cpp b/main.cpp index 2119495e6..cc22bad67 100644 --- a/main.cpp +++ b/main.cpp @@ -1361,15 +1361,24 @@ bool ScanMessageStart(Stream& s) bool CheckDiskSpace(int64 nAdditionalBytes) { - wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) - { - printf("ERROR: wxGetDiskSpace() failed\n"); +#ifdef __WXMSW__ + uint64 nFreeBytesAvailable = 0; // bytes available to caller + uint64 nTotalNumberOfBytes = 0; // bytes on disk + uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk + if (!GetDiskFreeSpaceEx(GetDataDir().c_str(), + (PULARGE_INTEGER)&nFreeBytesAvailable, + (PULARGE_INTEGER)&nTotalNumberOfBytes, + (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + { + printf("ERROR: GetDiskFreeSpaceEx() failed\n"); return true; } +#else + uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; +#endif // Check for 15MB because database could create another 10MB log file at any time - if (nFreeBytesAvailable.GetValue() < (int64)15000000 + nAdditionalBytes) + if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); @@ -1546,7 +1555,7 @@ void PrintBlockTree() pindex->nFile, pindex->nBlockPos, block.GetHash().ToString().substr(0,14).c_str(), - DateTimeStr(block.nTime).c_str(), + DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(), block.vtx.size()); CRITICAL_BLOCK(cs_mapWallet) @@ -1673,20 +1682,24 @@ bool ProcessMessages(CNode* pfrom) bool fRet = false; try { - CheckForShutdown(2); CRITICAL_BLOCK(cs_main) fRet = ProcessMessage(pfrom, strCommand, vMsg); - CheckForShutdown(2); + if (fShutdown) + return true; } - catch (std::ios_base::failure& e) { + catch (std::ios_base::failure& e) + { if (strstr(e.what(), "CDataStream::read() : end of data")) { // Allow exceptions from underlength message on vRecv printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } else + { PrintException(&e, "ProcessMessage()"); - } catch (std::exception& e) { + } + } + catch (std::exception& e) { PrintException(&e, "ProcessMessage()"); } catch (...) { PrintException(NULL, "ProcessMessage()"); @@ -2093,7 +2106,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) bool SendMessages(CNode* pto) { - CheckForShutdown(2); CRITICAL_BLOCK(cs_main) { // Don't send anything until we get their version message @@ -2223,12 +2235,10 @@ void GenerateBitcoins(bool fGenerate) void ThreadBitcoinMiner(void* parg) { - vnThreadsRunning[3]++; - CheckForShutdown(3); try { - bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n", fRet ? "true" : "false"); + vnThreadsRunning[3]++; + BitcoinMiner(); vnThreadsRunning[3]--; } catch (std::exception& e) { @@ -2238,6 +2248,8 @@ void ThreadBitcoinMiner(void* parg) vnThreadsRunning[3]--; PrintException(NULL, "ThreadBitcoinMiner()"); } + + printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]); } int FormatHashBlocks(void* pbuffer, unsigned int len) @@ -2285,7 +2297,7 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) } -bool BitcoinMiner() +void BitcoinMiner() { printf("BitcoinMiner started\n"); @@ -2296,11 +2308,13 @@ bool BitcoinMiner() { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); Sleep(50); - CheckForShutdown(3); + if (fShutdown) + return; while (vNodes.empty()) { Sleep(1000); - CheckForShutdown(3); + if (fShutdown) + return; } unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; @@ -2324,7 +2338,7 @@ bool BitcoinMiner() // auto_ptr pblock(new CBlock()); if (!pblock.get()) - return false; + return; // Add our coinbase tx as first transaction pblock->vtx.push_back(txNew); @@ -2433,7 +2447,7 @@ bool BitcoinMiner() { // Save key if (!AddKey(key)) - return false; + return; key.MakeNewKey(); // Process this block the same as if we had received it from another node @@ -2450,7 +2464,12 @@ bool BitcoinMiner() // Update nTime every few seconds if ((++tmp.block.nNonce & 0xffff) == 0) { - CheckForShutdown(3); + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) + return; if (tmp.block.nNonce == 0) break; if (pindexPrev != pindexBest) @@ -2459,16 +2478,10 @@ bool BitcoinMiner() break; if (vNodes.empty()) break; - if (!fGenerateBitcoins) - return true; - if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) - return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } } - - return true; } diff --git a/main.h b/main.h index 6d8f0ed87..16b8c6a3d 100644 --- a/main.h +++ b/main.h @@ -68,7 +68,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); -bool BitcoinMiner(); +void BitcoinMiner(); diff --git a/net.cpp b/net.cpp index c14061e7d..44a75a177 100644 --- a/net.cpp +++ b/net.cpp @@ -48,6 +48,10 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); bool fProxy = (fUseProxy && fRoutable); @@ -68,7 +72,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) char* pszSocks4 = pszSocks4IP; int nSize = sizeof(pszSocks4IP); - int ret = send(hSocket, pszSocks4, nSize, 0); + int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); if (ret != nSize) { closesocket(hSocket); @@ -100,7 +104,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha if (!ConnectSocket(addrConnect, hSocket)) return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); - send(hSocket, pszGet, strlen(pszGet), 0); + send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); string strLine; while (RecvLine(hSocket, strLine)) @@ -124,7 +128,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha if (strLine.find("<")) strLine = strLine.substr(0, strLine.find("<")); strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); - strLine = wxString(strLine).Trim(); + while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) + strLine.resize(strLine.size()-1); CAddress addr(strLine.c_str()); printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable()) @@ -492,24 +497,26 @@ void ThreadSocketHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); - loop + try { vnThreadsRunning[0]++; - CheckForShutdown(0); - try - { - ThreadSocketHandler2(parg); - vnThreadsRunning[0]--; - } - catch (std::exception& e) { - vnThreadsRunning[0]--; - PrintException(&e, "ThreadSocketHandler()"); - } catch (...) { - vnThreadsRunning[0]--; - PrintException(NULL, "ThreadSocketHandler()"); - } - Sleep(5000); + ThreadSocketHandler2(parg); + vnThreadsRunning[0]--; } + catch (std::exception& e) { + vnThreadsRunning[0]--; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[0]--; + PrintException(NULL, "ThreadSocketHandler()"); + } + + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + + printf("ThreadSocketHandler exiting\n"); } void ThreadSocketHandler2(void* parg) @@ -600,7 +607,8 @@ void ThreadSocketHandler2(void* parg) vnThreadsRunning[0]--; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); vnThreadsRunning[0]++; - CheckForShutdown(0); + if (fShutdown) + return; if (nSelect == SOCKET_ERROR) { int nErr = WSAGetLastError(); @@ -659,7 +667,8 @@ void ThreadSocketHandler2(void* parg) vNodesCopy = vNodes; foreach(CNode* pnode, vNodesCopy) { - CheckForShutdown(0); + if (fShutdown) + return; SOCKET hSocket = pnode->hSocket; // @@ -708,7 +717,7 @@ void ThreadSocketHandler2(void* parg) CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), 0); + int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); @@ -747,24 +756,21 @@ void ThreadOpenConnections(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); - loop + try { vnThreadsRunning[1]++; - CheckForShutdown(1); - try - { - ThreadOpenConnections2(parg); - vnThreadsRunning[1]--; - } - catch (std::exception& e) { - vnThreadsRunning[1]--; - PrintException(&e, "ThreadOpenConnections()"); - } catch (...) { - vnThreadsRunning[1]--; - PrintException(NULL, "ThreadOpenConnections()"); - } - Sleep(5000); + ThreadOpenConnections2(parg); + vnThreadsRunning[1]--; + } + catch (std::exception& e) { + vnThreadsRunning[1]--; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[1]--; + PrintException(NULL, "ThreadOpenConnections()"); } + + printf("ThreadOpenConnections exiting\n"); } void ThreadOpenConnections2(void* parg) @@ -778,7 +784,8 @@ void ThreadOpenConnections2(void* parg) for (int i = 0; i < 10; i++) { Sleep(1000); - CheckForShutdown(1); + if (fShutdown) + return; } } @@ -792,7 +799,8 @@ void ThreadOpenConnections2(void* parg) { OpenNetworkConnection(addr); Sleep(1000); - CheckForShutdown(1); + if (fShutdown) + return; } } } @@ -806,11 +814,13 @@ void ThreadOpenConnections2(void* parg) const int nMaxConnections = 15; while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { - CheckForShutdown(1); + if (fShutdown) + return; Sleep(2000); } vnThreadsRunning[1]++; - CheckForShutdown(1); + if (fShutdown) + return; // // Choose an address to connect to based on most recently seen @@ -869,14 +879,16 @@ bool OpenNetworkConnection(const CAddress& addrConnect) // // Initiate outbound network connection // - CheckForShutdown(1); + if (fShutdown) + return false; if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) return false; vnThreadsRunning[1]--; CNode* pnode = ConnectNode(addrConnect); vnThreadsRunning[1]++; - CheckForShutdown(1); + if (fShutdown) + return false; if (!pnode) return false; pnode->fNetworkNode = true; @@ -914,24 +926,21 @@ void ThreadMessageHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); - loop + try { vnThreadsRunning[2]++; - CheckForShutdown(2); - try - { - ThreadMessageHandler2(parg); - vnThreadsRunning[2]--; - } - catch (std::exception& e) { - vnThreadsRunning[2]--; - PrintException(&e, "ThreadMessageHandler()"); - } catch (...) { - vnThreadsRunning[2]--; - PrintException(NULL, "ThreadMessageHandler()"); - } - Sleep(5000); + ThreadMessageHandler2(parg); + vnThreadsRunning[2]--; + } + catch (std::exception& e) { + vnThreadsRunning[2]--; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[2]--; + PrintException(NULL, "ThreadMessageHandler()"); } + + printf("ThreadMessageHandler exiting\n"); } void ThreadMessageHandler2(void* parg) @@ -951,10 +960,14 @@ void ThreadMessageHandler2(void* parg) // Receive messages TRY_CRITICAL_BLOCK(pnode->cs_vRecv) ProcessMessages(pnode); + if (fShutdown) + return; // Send messages TRY_CRITICAL_BLOCK(pnode->cs_vSend) SendMessages(pnode); + if (fShutdown) + return; pnode->Release(); } @@ -963,7 +976,8 @@ void ThreadMessageHandler2(void* parg) vnThreadsRunning[2]--; Sleep(100); vnThreadsRunning[2]++; - CheckForShutdown(2); + if (fShutdown) + return; } } @@ -996,7 +1010,7 @@ bool StartNode(string& strError) // Get local host ip char pszHostName[255]; - if (gethostname(pszHostName, 255) == SOCKET_ERROR) + if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) { strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); @@ -1009,9 +1023,16 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } - addrLocalHost = CAddress(*(long*)(phostent->h_addr_list[0]), - DEFAULT_PORT, - nLocalServices); + + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + break; + } printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Create socket for listening for incoming connections @@ -1022,6 +1043,10 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif // Set to nonblocking, incoming connections will also inherit this #ifdef __WXMSW__ @@ -1038,19 +1063,22 @@ bool StartNode(string& strError) // The sockaddr_in structure specifies the address family, // IP address, and port for the socket that is being bound - int nRetryLimit = 15; - struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer + sockaddr.sin_port = DEFAULT_PORT; if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str()); + strError = strprintf("Error: Unable to bind to port %d on this computer. The program is probably already running.", ntohs(sockaddr.sin_port)); else - strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr); + strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); return false; } - printf("bound to addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + printf("bound to port %d\n", ntohs(sockaddr.sin_port)); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) @@ -1065,6 +1093,7 @@ bool StartNode(string& strError) { // Proxies can't take incoming connections addrLocalHost.ip = CAddress("0.0.0.0").ip; + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); } else { @@ -1115,17 +1144,17 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3]) + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) { if (GetTime() - nStart > 15) break; Sleep(20); } - if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n"); - if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n"); - if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n"); - if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n"); - while (vnThreadsRunning[2]) + if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); + while (vnThreadsRunning[2] > 0) Sleep(20); Sleep(50); @@ -1135,21 +1164,3 @@ bool StopNode() #endif return true; } - -void CheckForShutdown(int n) -{ - if (fShutdown) - { - if (n != -1) - if (--vnThreadsRunning[n] < 0) - vnThreadsRunning[n] = 0; - if (n == 0) - { - foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - closesocket(hListenSocket); - } - printf("Thread %d exiting\n", n); - _endthread(); - } -} diff --git a/net.h b/net.h index 275a4cb88..024e7336e 100644 --- a/net.h +++ b/net.h @@ -30,7 +30,6 @@ void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); bool StartNode(string& strError=REF(string())); bool StopNode(); -void CheckForShutdown(int n); @@ -268,6 +267,7 @@ public: struct sockaddr_in GetSockAddr() const { struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = ip; sockaddr.sin_port = port; diff --git a/ui.cpp b/ui.cpp index 212548199..92e1d59ce 100644 --- a/ui.cpp +++ b/ui.cpp @@ -65,11 +65,13 @@ bool Is24HourTime() string DateStr(int64 nTime) { + // Can only be used safely here in the UI return (string)wxDateTime((time_t)nTime).FormatDate(); } string DateTimeStr(int64 nTime) { + // Can only be used safely here in the UI wxDateTime datetime((time_t)nTime); if (Is24HourTime()) return (string)datetime.Format("%x %H:%M"); @@ -283,6 +285,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fRefreshListCtrl = false; fRefreshListCtrlRunning = false; fOnSetFocusAddress = false; + fRefresh = false; m_choiceFilter->SetSelection(0); m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -350,7 +353,7 @@ void Shutdown(void* parg) StopNode(); DBFlush(true); - printf("Bitcoin exiting\n"); + printf("Bitcoin exiting\n\n"); exit(0); } } @@ -391,6 +394,30 @@ void CMainFrame::OnListColBeginDrag(wxListEvent& event) event.Veto(); } +int CMainFrame::GetSortIndex(const string& strSort) +{ +#ifdef __WXMSW__ + return 0; +#else + // The wx generic listctrl implementation used on GTK doesn't sort, + // so we have to do it ourselves. Remember, we sort in reverse order. + // In the wx generic implementation, they store the list of items + // in a vector, so indexed lookups are fast, but inserts are slower + // the closer they are to the top. + int low = 0; + int high = m_listCtrl->GetItemCount(); + while (low < high) + { + int mid = low + ((high - low) / 2); + if (strSort.compare(m_listCtrl->GetItemText(mid).c_str()) >= 0) + high = mid; + else + low = mid + 1; + } + return low; +#endif +} + void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) { string str0 = strSort; @@ -407,7 +434,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo // fNew is for blind insert, only use if you're sure it's new if (fNew || nIndex == -1) { - nIndex = m_listCtrl->InsertItem(0, str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); } else { @@ -415,7 +442,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo if (GetItemText(m_listCtrl, nIndex, 0) != str0) { m_listCtrl->DeleteItem(nIndex); - nIndex = m_listCtrl->InsertItem(0, str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); } } @@ -826,6 +853,11 @@ void CMainFrame::RefreshStatusColumn() void CMainFrame::OnPaint(wxPaintEvent& event) { + if (fRefresh) + { + fRefresh = false; + Refresh(); + } event.Skip(); } @@ -846,7 +878,7 @@ void ThreadDelayedRepaint(void* parg) { printf("DelayedRepaint\n"); wxPaintEvent event; - pframeMain->Refresh(); + pframeMain->fRefresh = true; pframeMain->AddPendingEvent(event); } } @@ -871,7 +903,7 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; - pframeMain->Refresh(); + pframeMain->fRefresh = true; pframeMain->AddPendingEvent(event); } } @@ -907,7 +939,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } vWalletUpdated.clear(); if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) - m_listCtrl->ScrollList(0, INT_MAX); + m_listCtrl->ScrollList(0, INT_MIN/2); } } @@ -943,9 +975,10 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); -#ifdef __WXMSW__ - m_listCtrl->OnPaint(event); -#endif + // Pass through to listctrl to actually do the paint, we're just hooking the message + m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); + m_listCtrl->GetEventHandler()->ProcessEvent(event); + m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrame::OnPaintListCtrl), NULL, this); } @@ -3331,7 +3364,11 @@ bool CMyApp::OnInit2() g_isPainting = 10000; #endif wxImage::AddHandler(new wxPNGHandler); +#ifdef __WXMSW__ SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); +#endif ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) @@ -3355,7 +3392,10 @@ bool CMyApp::OnInit2() // Limit to single instance per user // Required to protect the database files if we're going to keep deleting log.* // - wxString strMutexName = wxString("Bitcoin.") + getenv("HOMEPATH"); +#ifdef __WXMSW__ + // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file + // maybe should go by whether successfully bind port 8333 instead + wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); for (int i = 0; i < strMutexName.size(); i++) if (!isalnum(strMutexName[i])) strMutexName[i] = '.'; @@ -3367,7 +3407,6 @@ bool CMyApp::OnInit2() loop { // TODO: find out how to do this in Linux, or replace with wxWidgets commands -#ifdef __WXMSW__ // Show the previous instance and exit HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -3377,7 +3416,6 @@ bool CMyApp::OnInit2() SetForegroundWindow(hwndPrev); return false; } -#endif if (GetTime() > nStart + 60) return false; @@ -3390,6 +3428,7 @@ bool CMyApp::OnInit2() break; } } +#endif // // Parameters diff --git a/ui.h b/ui.h index 47839e81e..1d0491f10 100644 --- a/ui.h +++ b/ui.h @@ -32,7 +32,6 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); -extern string DateTimeStr(int64 nTime); extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); @@ -84,8 +83,10 @@ public: bool fRefreshListCtrlRunning; bool fOnSetFocusAddress; unsigned int nListViewUpdated; + bool fRefresh; void OnCrossThreadCall(wxCommandEvent& event); + int GetSortIndex(const string& strSort); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); bool DeleteLine(uint256 hashKey); bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); diff --git a/uibase.cpp b/uibase.cpp index bb564e996..9a6199952 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -84,7 +84,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_staticText32->Wrap( -1 ); bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 250,-1 ), wxTE_READONLY ); + m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); @@ -143,7 +143,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer157; bSizer157 = new wxBoxSizer( wxVERTICAL ); - m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB ); + m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); m_panel7->SetSizer( bSizer157 ); @@ -343,7 +343,7 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con wxBoxSizer* bSizer65; bSizer65 = new wxBoxSizer( wxVERTICAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer65->Add( m_buttonOK, 0, wxALL, 5 ); bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); @@ -520,17 +520,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer58; bSizer58 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonApply->SetMinSize( wxSize( 85,25 ) ); - bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); @@ -622,7 +618,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); @@ -767,13 +763,10 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_buttonSend->SetMinSize( wxSize( 85,25 ) ); bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer23->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); @@ -833,13 +826,10 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonOK->Enable( false ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -887,28 +877,19 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonRename->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonNew->SetMinSize( wxSize( 110,25 ) ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCopy->SetMinSize( wxSize( 120,25 ) ); - bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonCancel->Hide(); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); @@ -969,28 +950,18 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonEdit->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNew->SetMinSize( wxSize( 110,25 ) ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonDelete->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -1389,18 +1360,12 @@ CEditProductDialogBase::CEditProductDialogBase( wxWindow* parent, wxWindowID id, bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonPreview->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1605,18 +1570,13 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonBack->Enable( false ); - m_buttonBack->SetMinSize( wxSize( 85,25 ) ); bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNext->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1662,8 +1622,6 @@ CViewOrderDialogBase::CViewOrderDialogBase( wxWindow* parent, wxWindowID id, con bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1720,13 +1678,9 @@ CEditReviewDialogBase::CEditReviewDialogBase( wxWindow* parent, wxWindowID id, c bSizer113 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonSubmit->SetMinSize( wxSize( 85,25 ) ); - bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); @@ -1951,13 +1905,9 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer80->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); diff --git a/uiproject.fbp b/uiproject.fbp index 7bce7349f..17656b56a 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -70,7 +70,7 @@ - + 240,240,240 1 @@ -225,7 +225,7 @@ - + 20,20 @@ -439,7 +439,7 @@ m_textCtrlAddress protected - 250,-1 + 340,-1 wxTE_READONLY @@ -944,7 +944,7 @@ - wxALWAYS_SHOW_SB + wxVSCROLL @@ -1648,7 +1648,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -3031,7 +3031,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -3079,7 +3079,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -3131,7 +3131,7 @@ wxID_APPLY &Apply - 85,25 + -1,-1 m_buttonApply protected @@ -3493,7 +3493,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -4485,7 +4485,7 @@ wxID_BUTTONSEND &Send - 85,25 + -1,-1 m_buttonSend protected @@ -4537,7 +4537,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -4775,7 +4775,7 @@ wxID_ANY OK - 85,25 + -1,-1 m_buttonOK protected @@ -4827,7 +4827,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -5089,7 +5089,7 @@ wxID_BUTTONRENAME &Edit... - 85,25 + -1,-1 m_buttonRename protected @@ -5141,7 +5141,7 @@ wxID_BUTTONNEW &New Address... - 110,25 + -1,-1 m_buttonNew protected @@ -5193,7 +5193,7 @@ wxID_BUTTONCOPY &Copy to Clipboard - 120,25 + -1,-1 m_buttonCopy protected @@ -5245,7 +5245,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -5297,7 +5297,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -5559,7 +5559,7 @@ wxID_BUTTONEDIT &Edit... - 85,25 + -1,-1 m_buttonEdit protected @@ -5611,7 +5611,7 @@ wxID_BUTTONNEW &New Address... - 110,25 + -1,-1 m_buttonNew protected @@ -5663,7 +5663,7 @@ wxID_BUTTONDELETE &Delete - 85,25 + -1,-1 m_buttonDelete protected @@ -5715,7 +5715,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -5767,7 +5767,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel public @@ -10225,7 +10225,7 @@ wxID_BUTTONSEND &Send - 85,25 + -1,-1 m_buttonOK protected @@ -10277,7 +10277,7 @@ wxID_BUTTONPREVIEW &Preview - 85,25 + -1,-1 m_buttonPreview protected @@ -10329,7 +10329,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -10798,7 +10798,7 @@ wxID_BUTTONBACK < &Back - 85,25 + -1,-1 m_buttonBack protected @@ -10850,7 +10850,7 @@ wxID_BUTTONNEXT &Next > - 85,25 + -1,-1 m_buttonNext protected @@ -10902,7 +10902,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -11087,7 +11087,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -11488,7 +11488,7 @@ wxID_SUBMIT &Submit - 85,25 + -1,-1 m_buttonSubmit protected @@ -11540,7 +11540,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -12907,7 +12907,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -12959,7 +12959,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected diff --git a/util.cpp b/util.cpp index d2e624d67..5efb579bf 100644 --- a/util.cpp +++ b/util.cpp @@ -96,12 +96,7 @@ void RandAddSeedPerfmon() hash = 0; memset(pdata, 0, nSize); - time_t nTime; - time(&nTime); - struct tm* ptmTime = gmtime(&nTime); - char pszTime[200]; - strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); + printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str(), nSize); } #endif } @@ -350,7 +345,9 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); #else - const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + // might not be thread safe, uses wxString + //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + const char* pszModule = "bitcoin"; #endif if (pex) snprintf(pszMessage, 1000, @@ -425,7 +422,6 @@ void GetDataDir(char* pszDir) } strlcpy(pszDir, pszCachedDir, MAX_PATH); } - } string GetDataDir() diff --git a/util.h b/util.h index 3bc7c798a..8fcfcd0dc 100644 --- a/util.h +++ b/util.h @@ -84,6 +84,10 @@ inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PRO #define THREAD_PRIORITY_NORMAL 0 #define THREAD_PRIORITY_ABOVE_NORMAL 0 #endif +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + @@ -379,6 +383,14 @@ inline int64 GetTimeMillis() return wxGetLocalTimeMillis().GetValue(); } +inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) +{ + time_t n = nTime; + struct tm* ptmTime = gmtime(&n); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); + return pszTime; +} @@ -400,7 +412,7 @@ inline void heapchk() { \ static char nLoops; \ if (nLoops <= 0) \ - nLoops = GetRand(50) + 1; \ + nLoops = GetRand(20) + 1; \ if (nLoops-- > 1) \ { \ ThreadFn; \