aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compat.h1
-rw-r--r--src/init.cpp34
-rw-r--r--src/leveldb/util/env_win.cc8
-rw-r--r--src/net.cpp17
-rw-r--r--src/net.h1
-rw-r--r--src/qt/bitcoingui.cpp2
-rw-r--r--src/qt/forms/optionsdialog.ui2
-rw-r--r--src/qt/macdockiconhandler.h4
-rw-r--r--src/qt/macdockiconhandler.mm11
-rw-r--r--src/qt/walletview.cpp19
-rw-r--r--src/util.cpp25
-rw-r--r--src/util.h1
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);
}
diff --git a/src/net.h b/src/net.h
index 32bbbca6dc..df34f5a88d 100644
--- a/src/net.h
+++ b/src/net.h
@@ -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();