Gavin Andresen: multiple instance check, -testnet use port 18333

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@170 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
s_nakamoto 2010-10-20 16:12:23 +00:00
parent 2ea5fa0710
commit d9c6b09ac4
5 changed files with 27 additions and 21 deletions

View File

@ -12,12 +12,8 @@ WINDOWS BUILD NOTES
Compilers Supported Compilers Supported
------------------- -------------------
MinGW GCC (recommended) MinGW GCC (recommended)
http://tdm-gcc.tdragon.net/ has an easy installer. Go back a few versions
MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support for a little older gcc like gcc 4.4.?.
for MSVC 6.0 after that. However, they didn't add Asio until 1.35.
You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by
unpacking boost_asio_*.zip into the boost directory:
http://sourceforge.net/projects/asio/files/asio
MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of
linking to runtime DLLs that are not installed on XP by default. linking to runtime DLLs that are not installed on XP by default.

View File

@ -70,6 +70,7 @@
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp> #include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp> #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp> #include <boost/date_time/gregorian/gregorian_types.hpp>

View File

@ -244,8 +244,7 @@ bool AppInit2(int argc, char* argv[])
// Required to protect the database files if we're going to keep deleting log.* // Required to protect the database files if we're going to keep deleting log.*
// //
#if defined(__WXMSW__) && defined(GUI) #if defined(__WXMSW__) && defined(GUI)
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file // wxSingleInstanceChecker doesn't work on Linux
// maybe should go by whether successfully bind port 8333 instead
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
for (int i = 0; i < strMutexName.size(); i++) for (int i = 0; i < strMutexName.size(); i++)
if (!isalnum(strMutexName[i])) if (!isalnum(strMutexName[i]))
@ -257,7 +256,6 @@ bool AppInit2(int argc, char* argv[])
unsigned int nStart = GetTime(); unsigned int nStart = GetTime();
loop loop
{ {
// TODO: find out how to do this in Linux, or replace with wxWidgets commands
// Show the previous instance and exit // Show the previous instance and exit
HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
if (hwndPrev) if (hwndPrev)
@ -281,8 +279,18 @@ bool AppInit2(int argc, char* argv[])
} }
#endif #endif
// Make sure only a single bitcoin process is using the data directory.
string strLockFile = GetDataDir() + "/.lock";
FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
fclose(file);
static boost::interprocess::file_lock lock(strLockFile.c_str());
if (!lock.try_lock())
{
wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
return false;
}
// Bind to the port early so we can tell if another instance is already running. // Bind to the port early so we can tell if another instance is already running.
// This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
string strErrors; string strErrors;
if (!BindListenPort(strErrors)) if (!BindListenPort(strErrors))
{ {

13
net.cpp
View File

@ -20,7 +20,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect);
// //
bool fClient = false; bool fClient = false;
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CAddress addrLocalHost(0, 0, nLocalServices);
CNode* pnodeLocalHost = NULL; CNode* pnodeLocalHost = NULL;
uint64 nLocalHostNonce = 0; uint64 nLocalHostNonce = 0;
array<int, 10> vnThreadsRunning; array<int, 10> vnThreadsRunning;
@ -1006,7 +1006,7 @@ void ThreadOpenConnections2(void* parg)
// Randomize the order in a deterministic way, putting the standard port first // Randomize the order in a deterministic way, putting the standard port first
int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60); int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
if (addr.port != DEFAULT_PORT) if (addr.port != GetDefaultPort())
nRandomizer += 2 * 60 * 60; nRandomizer += 2 * 60 * 60;
// Last seen Base retry frequency // Last seen Base retry frequency
@ -1185,6 +1185,7 @@ bool BindListenPort(string& strError)
{ {
strError = ""; strError = "";
int nOne = 1; int nOne = 1;
addrLocalHost.port = GetDefaultPort();
#ifdef __WXMSW__ #ifdef __WXMSW__
// Initialize Windows Sockets // Initialize Windows Sockets
@ -1236,12 +1237,12 @@ bool BindListenPort(string& strError)
memset(&sockaddr, 0, sizeof(sockaddr)); memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET; sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
sockaddr.sin_port = DEFAULT_PORT; sockaddr.sin_port = GetDefaultPort();
if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
{ {
int nErr = WSAGetLastError(); int nErr = WSAGetLastError();
if (nErr == WSAEADDRINUSE) if (nErr == WSAEADDRINUSE)
strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port)); strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
else else
strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), 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()); printf("%s\n", strError.c_str());
@ -1278,7 +1279,7 @@ void StartNode(void* parg)
printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); 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++) for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
{ {
CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
if (addr.IsValid() && addr.GetByte(3) != 127) if (addr.IsValid() && addr.GetByte(3) != 127)
{ {
addrLocalHost = addr; addrLocalHost = addr;
@ -1306,7 +1307,7 @@ void StartNode(void* parg)
printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP); printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
// Take the first IP that isn't loopback 127.x.x.x // Take the first IP that isn't loopback 127.x.x.x
CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices); CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
if (addr.IsValid() && addr.GetByte(3) != 127) if (addr.IsValid() && addr.GetByte(3) != 127)
{ {
addrLocalHost = addr; addrLocalHost = addr;

10
net.h
View File

@ -12,7 +12,7 @@ extern int nBestHeight;
static const unsigned short DEFAULT_PORT = 0x8d20; // htons(8333) inline unsigned short GetDefaultPort() { return fTestNet ? htons(18333) : htons(8333); }
static const unsigned int PUBLISH_HOPS = 5; static const unsigned int PUBLISH_HOPS = 5;
enum enum
{ {
@ -150,11 +150,11 @@ public:
Init(); Init();
} }
CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK) CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK)
{ {
Init(); Init();
ip = ipIn; ip = ipIn;
port = portIn; port = (portIn == 0 ? GetDefaultPort() : portIn);
nServices = nServicesIn; nServices = nServicesIn;
} }
@ -185,7 +185,7 @@ public:
nServices = NODE_NETWORK; nServices = NODE_NETWORK;
memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = INADDR_NONE; ip = INADDR_NONE;
port = DEFAULT_PORT; port = GetDefaultPort();
nTime = GetAdjustedTime(); nTime = GetAdjustedTime();
nLastTry = 0; nLastTry = 0;
} }
@ -193,7 +193,7 @@ public:
bool SetAddress(const char* pszIn) bool SetAddress(const char* pszIn)
{ {
ip = INADDR_NONE; ip = INADDR_NONE;
port = DEFAULT_PORT; port = GetDefaultPort();
char psz[100]; char psz[100];
strlcpy(psz, pszIn, sizeof(psz)); strlcpy(psz, pszIn, sizeof(psz));
unsigned int a=0, b=0, c=0, d=0, e=0; unsigned int a=0, b=0, c=0, d=0, e=0;