diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compat.h | 1 | ||||
-rw-r--r-- | src/init.cpp | 34 | ||||
-rw-r--r-- | src/leveldb/util/env_win.cc | 8 | ||||
-rw-r--r-- | src/net.cpp | 17 | ||||
-rw-r--r-- | src/net.h | 1 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 2 | ||||
-rw-r--r-- | src/qt/forms/optionsdialog.ui | 2 | ||||
-rw-r--r-- | src/qt/macdockiconhandler.h | 4 | ||||
-rw-r--r-- | src/qt/macdockiconhandler.mm | 11 | ||||
-rw-r--r-- | src/qt/walletview.cpp | 19 | ||||
-rw-r--r-- | src/util.cpp | 25 | ||||
-rw-r--r-- | src/util.h | 1 |
12 files changed, 89 insertions, 36 deletions
diff --git a/src/compat.h b/src/compat.h index 79ebb9323a..706221692b 100644 --- a/src/compat.h +++ b/src/compat.h @@ -11,6 +11,7 @@ #ifndef NOMINMAX #define NOMINMAX #endif +#define FD_SETSIZE 1024 // max number of fds in fd_set #include <winsock2.h> #include <mswsock.h> #include <ws2tcpip.h> diff --git a/src/init.cpp b/src/init.cpp index f6485c3b1d..3845cfad81 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -28,6 +28,15 @@ using namespace boost; CWallet* pwalletMain; CClientUIInterface uiInterface; +#ifdef WIN32 +// Win32 LevelDB doesn't use filedescriptors, and the ones used for +// accessing block files, don't count towards to fd_set size limit +// anyway. +#define MIN_CORE_FILEDESCRIPTORS 0 +#else +#define MIN_CORE_FILEDESCRIPTORS 150 +#endif + // Used to pass flags to the Bind() function enum BindFlags { BF_NONE = 0, @@ -349,7 +358,7 @@ std::string HelpMessage() " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n" + " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + "\n" + " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + "\n" + - " -par=<n> " + _("Set the number of script verification threads (1-16, 0=auto, default: 0)") + "\n" + + " -par=N " + _("Set the number of script verification threads (up to 16, 0=auto, negative=leave N CPUs free, default: 0)") + "\n" + "\n" + _("Block creation options:") + "\n" + " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n" + @@ -453,6 +462,14 @@ bool AppInit2(boost::thread_group& threadGroup) typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); + + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR) + { + return InitError(strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret)); + } #endif #ifndef WIN32 umask(077); @@ -510,6 +527,16 @@ bool AppInit2(boost::thread_group& threadGroup) SoftSetBoolArg("-rescan", true); } + // Make sure enough file descriptors are available + int nBind = std::max((int)mapArgs.count("-bind"), 1); + nMaxConnections = GetArg("-maxconnections", 125); + nMaxConnections = std::max(std::min(nMaxConnections, FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS), 0); + int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS); + if (nFD < MIN_CORE_FILEDESCRIPTORS) + return InitError(_("Not enough file descriptors available.")); + if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections) + nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS; + // ********************************************************* Step 3: parameter-to-internal-flags fDebug = GetBoolArg("-debug"); @@ -517,8 +544,8 @@ bool AppInit2(boost::thread_group& threadGroup) // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency nScriptCheckThreads = GetArg("-par", 0); - if (nScriptCheckThreads == 0) - nScriptCheckThreads = boost::thread::hardware_concurrency(); + if (nScriptCheckThreads <= 0) + nScriptCheckThreads += boost::thread::hardware_concurrency(); if (nScriptCheckThreads <= 1) nScriptCheckThreads = 0; else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS) @@ -586,6 +613,7 @@ bool AppInit2(boost::thread_group& threadGroup) printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); printf("Used data directory %s\n", strDataDir.c_str()); + printf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD); std::ostringstream strErrors; if (fDaemon) diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc index f1a7610624..ef2ecae830 100644 --- a/src/leveldb/util/env_win.cc +++ b/src/leveldb/util/env_win.cc @@ -420,7 +420,7 @@ BOOL Win32RandomAccessFile::_Init( LPCWSTR path ) { BOOL bRet = FALSE; if(!_hFile) - _hFile = ::CreateFileW(path,GENERIC_READ,0,NULL,OPEN_EXISTING, + _hFile = ::CreateFileW(path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,NULL); if(!_hFile || _hFile == INVALID_HANDLE_VALUE ) _hFile = NULL; @@ -462,8 +462,8 @@ bool Win32MapFile::_UnmapCurrentRegion() // Defer syncing this data until next Sync() call, if any _pending_sync = true; } - UnmapViewOfFile(_base); - CloseHandle(_base_handle); + if (!UnmapViewOfFile(_base) || !CloseHandle(_base_handle)) + result = false; _file_offset += _limit - _base; _base = NULL; _base_handle = NULL; @@ -971,7 +971,7 @@ Status Win32Env::NewRandomAccessFile( const std::string& fname, RandomAccessFile if(!pFile->isEnable()){ delete pFile; *result = NULL; - sRet = Status::IOError(path,"Could not create random access file."); + sRet = Status::IOError(path, Win32::GetLastErrSz()); }else *result = pFile; return sRet; diff --git a/src/net.cpp b/src/net.cpp index 755312682b..3fa48ae484 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -48,6 +48,7 @@ static CNode* pnodeSync = NULL; uint64 nLocalHostNonce = 0; static std::vector<SOCKET> vhListenSocket; CAddrMan addrman; +int nMaxConnections = 125; vector<CNode*> vNodes; CCriticalSection cs_vNodes; @@ -908,7 +909,7 @@ void ThreadSocketHandler() if (nErr != WSAEWOULDBLOCK) printf("socket error accept failed: %d\n", nErr); } - else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS) + else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) { { LOCK(cs_setservAddNodeAddresses); @@ -1653,18 +1654,6 @@ bool BindListenPort(const CService &addrBind, string& strError) strError = ""; int nOne = 1; -#ifdef WIN32 - // Initialize Windows Sockets - WSADATA wsadata; - int ret = WSAStartup(MAKEWORD(2,2), &wsadata); - if (ret != NO_ERROR) - { - strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); - printf("%s\n", strError.c_str()); - return false; - } -#endif - // Create socket for listening for incoming connections #ifdef USE_IPV6 struct sockaddr_storage sockaddr; @@ -1815,7 +1804,7 @@ void StartNode(boost::thread_group& threadGroup) { if (semOutbound == NULL) { // initialize semaphore - int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125)); + int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); semOutbound = new CSemaphore(nMaxOutbound); } @@ -74,6 +74,7 @@ extern bool fDiscover; extern uint64 nLocalServices; extern uint64 nLocalHostNonce; extern CAddrMan addrman; +extern int nMaxConnections; extern std::vector<CNode*> vNodes; extern CCriticalSection cs_vNodes; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 71db587e04..78a69af8b0 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -153,6 +153,7 @@ BitcoinGUI::~BitcoinGUI() trayIcon->hide(); #ifdef Q_OS_MAC delete appMenuBar; + MacDockIconHandler::instance()->setMainWindow(NULL); #endif } @@ -380,6 +381,7 @@ void BitcoinGUI::createTrayIconMenu() #else // Note: On Mac, the dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); + dockIconHandler->setMainWindow((QMainWindow *)this); trayIconMenu = dockIconHandler->dockMenu(); #endif diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 3771f9de63..bb53021cfd 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -33,7 +33,7 @@ <item> <widget class="QLabel" name="transactionFeeInfoLabel"> <property name="text"> - <string>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</string> + <string>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</string> </property> <property name="textFormat"> <enum>Qt::PlainText</enum> diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 5018456aa1..765b004750 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -2,6 +2,7 @@ #define MACDOCKICONHANDLER_H #include <QObject> +#include <QMainWindow> QT_BEGIN_NAMESPACE class QMenu; @@ -26,7 +27,7 @@ public: QMenu *dockMenu(); void setIcon(const QIcon &icon); - + void setMainWindow(QMainWindow *window); static MacDockIconHandler *instance(); void handleDockIconClickEvent(); @@ -40,6 +41,7 @@ private: DockIconClickEventHandler *m_dockIconClickEventHandler; QWidget *m_dummyWidget; QMenu *m_dockMenu; + QMainWindow *mainWindow; }; #endif // MACDOCKICONCLICKHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index ea868401c0..b6ea8e1d03 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -37,8 +37,9 @@ extern void qt_mac_set_dock_menu(QMenu*); Q_UNUSED(event) Q_UNUSED(replyEvent) - if (dockIconHandler) + if (dockIconHandler) { dockIconHandler->handleDockIconClickEvent(); + } } @end @@ -54,10 +55,15 @@ MacDockIconHandler::MacDockIconHandler() : QObject() [pool release]; } +void MacDockIconHandler::setMainWindow(QMainWindow *window) { + this->mainWindow = window; +} + MacDockIconHandler::~MacDockIconHandler() { [this->m_dockIconClickEventHandler release]; delete this->m_dummyWidget; + this->setMainWindow(NULL); } QMenu *MacDockIconHandler::dockMenu() @@ -94,5 +100,8 @@ MacDockIconHandler *MacDockIconHandler::instance() void MacDockIconHandler::handleDockIconClickEvent() { + this->mainWindow->activateWindow(); + this->mainWindow->show(); + emit this->dockIconClicked(); } diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 727b48ded7..6d44c174b7 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -18,8 +18,8 @@ #include "askpassphrasedialog.h" #include "ui_interface.h" +#include <QHBoxLayout> #include <QVBoxLayout> -#include <QActionGroup> #include <QAction> #include <QDesktopServices> #include <QFileDialog> @@ -39,7 +39,7 @@ WalletView::WalletView(QWidget *parent, BitcoinGUI *_gui): QHBoxLayout *hbox_buttons = new QHBoxLayout(); transactionView = new TransactionView(this); vbox->addWidget(transactionView); - QPushButton *exportButton = new QPushButton("&Export", this); + QPushButton *exportButton = new QPushButton(tr("&Export"), this); exportButton->setToolTip(tr("Export the data in the current tab to a file")); #ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac exportButton->setIcon(QIcon(":/icons/export")); @@ -138,14 +138,10 @@ void WalletView::incomingTransaction(const QModelIndex& parent, int start, int / TransactionTableModel *ttm = walletModel->getTransactionTableModel(); - QString date = ttm->index(start, TransactionTableModel::Date, parent) - .data().toString(); - qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent) - .data(Qt::EditRole).toULongLong(); - QString type = ttm->index(start, TransactionTableModel::Type, parent) - .data().toString(); - QString address = ttm->index(start, TransactionTableModel::ToAddress, parent) - .data().toString(); + QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString(); + qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong(); + QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString(); + QString address = ttm->index(start, TransactionTableModel::ToAddress, parent).data().toString(); gui->incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address); } @@ -227,8 +223,7 @@ void WalletView::encryptWallet(bool status) { if(!walletModel) return; - AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt: - AskPassphraseDialog::Decrypt, this); + AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this); dlg.setModel(walletModel); dlg.exec(); diff --git a/src/util.cpp b/src/util.cpp index 64f8e12983..8b6d8b32c8 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -10,6 +10,7 @@ #endif #include <fcntl.h> #include <sys/stat.h> +#include <sys/resource.h> #endif #include "util.h" @@ -1167,6 +1168,28 @@ bool TruncateFile(FILE *file, unsigned int length) { #endif } + +// this function tries to raise the file descriptor limit to the requested number. +// It returns the actual file descriptor limit (which may be more or less than nMinFD) +int RaiseFileDescriptorLimit(int nMinFD) { +#if defined(WIN32) + return 2048; +#else + struct rlimit limitFD; + if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) { + if (limitFD.rlim_cur < (rlim_t)nMinFD) { + limitFD.rlim_cur = nMinFD; + if (limitFD.rlim_cur > limitFD.rlim_max) + limitFD.rlim_cur = limitFD.rlim_max; + setrlimit(RLIMIT_NOFILE, &limitFD); + getrlimit(RLIMIT_NOFILE, &limitFD); + } + return limitFD.rlim_cur; + } + return nMinFD; // getrlimit failed, assume it's fine +#endif +} + // this function tries to make a particular range of a file allocated (corresponding to disk space) // it is advisory, and the range specified in the arguments will never contain live data void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { @@ -1231,6 +1254,8 @@ void ShrinkDebugFile() fclose(file); } } + else if(file != NULL) + fclose(file); } diff --git a/src/util.h b/src/util.h index 0641c4be7c..3d25364505 100644 --- a/src/util.h +++ b/src/util.h @@ -197,6 +197,7 @@ bool WildcardMatch(const std::string& str, const std::string& mask); void FileCommit(FILE *fileout); int GetFilesize(FILE* file); bool TruncateFile(FILE *file, unsigned int length); +int RaiseFileDescriptorLimit(int nMinFD); void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); boost::filesystem::path GetDefaultDataDir(); |