aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2009-11-18 19:19:41 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2009-11-18 19:19:41 +0000
commitc5c7911dab8732861affbe66849a100da62f7464 (patch)
treebfbb16bc8fbcb4911a24a5e32f9f4c3c280f392c
parentb349e3dca89dfff5fe70669f9fd3f3a1ec60a498 (diff)
bugfix Db::open/close and zombie sockets bugs fix double-close of socket handle,
keep databases open, close db cursors, initial block download in batches of 500 blocks, fix misc warnings, subver linux-test8 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@40 1a98c847-1fd6-4fd8-948a-caf3550aa51b
-rw-r--r--build-unix.txt16
-rw-r--r--db.cpp130
-rw-r--r--db.h17
-rw-r--r--irc.cpp14
-rw-r--r--main.cpp87
-rw-r--r--main.h10
-rw-r--r--makefile.unix7
-rw-r--r--net.cpp110
-rw-r--r--net.h16
-rw-r--r--serialize.h1
-rw-r--r--ui.cpp27
-rw-r--r--util.cpp10
-rw-r--r--util.h23
-rw-r--r--xpm/addressbook16.xpm2
-rw-r--r--xpm/addressbook20.xpm2
-rw-r--r--xpm/bitcoin16.xpm2
-rw-r--r--xpm/bitcoin20.xpm2
-rw-r--r--xpm/bitcoin32.xpm2
-rw-r--r--xpm/bitcoin48.xpm2
-rw-r--r--xpm/check.xpm2
-rw-r--r--xpm/send16.xpm2
-rw-r--r--xpm/send16noshadow.xpm2
-rw-r--r--xpm/send20.xpm2
23 files changed, 304 insertions, 184 deletions
diff --git a/build-unix.txt b/build-unix.txt
index ceb61ad545..f863b6a98c 100644
--- a/build-unix.txt
+++ b/build-unix.txt
@@ -13,18 +13,18 @@ UNIX BUILD NOTES
Dependencies
------------
-Install the dev files for the shared libraries:
apt-get install build-essential
apt-get install libgtk2.0-dev
apt-get install libssl-dev
+apt-get install libdb4.7-dev
+apt-get install libdb4.7++-dev
+apt-get install libboost-dev
Libraries you need to obtain separately and build:
default path download
wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
-Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
-Boost \boost http://www.boost.org/users/download/
-Their licenses:
+Licenses:
wxWidgets LGPL 2.1 with very liberal exceptions
Berkeley DB New BSD license with additional requirement that linked software must be free open source
Boost MIT-like license
@@ -59,15 +59,9 @@ make install
ldconfig
-Berkeley DB
------------
-cd /usr/local/db-4.7.25.NC/build_unix
-../dist/configure --enable-cxx
-make
-
-
Boost
-----
+If you download and build Boost yourself
cd /usr/local/boost_1_40_0
su
./bootstrap.sh
diff --git a/db.cpp b/db.cpp
index a9c42880ab..947aed2970 100644
--- a/db.cpp
+++ b/db.cpp
@@ -20,6 +20,7 @@ static CCriticalSection cs_db;
static bool fDbEnvInit = false;
DbEnv dbenv(0);
static map<string, int> mapFileUseCount;
+static map<string, Db*> mapDb;
class CDBInit
{
@@ -39,21 +40,17 @@ public:
instance_of_cdbinit;
-CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
+CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
{
int ret;
if (pszFile == NULL)
return;
+ fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
bool fCreate = strchr(pszMode, 'c');
- bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
unsigned int nFlags = DB_THREAD;
if (fCreate)
nFlags |= DB_CREATE;
- else if (fReadOnly)
- nFlags |= DB_RDONLY;
- if (!fReadOnly || fTxn)
- nFlags |= DB_AUTO_COMMIT;
CRITICAL_BLOCK(cs_db)
{
@@ -72,7 +69,7 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
dbenv.set_lk_max_locks(10000);
dbenv.set_lk_max_objects(10000);
dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug
- ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption
+ dbenv.set_flags(DB_AUTO_COMMIT, 1);
ret = dbenv.open(strDataDir.c_str(),
DB_CREATE |
DB_INIT_LOCK |
@@ -90,31 +87,39 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
strFile = pszFile;
++mapFileUseCount[strFile];
- }
-
- pdb = new Db(&dbenv, 0);
+ pdb = mapDb[strFile];
+ if (pdb == NULL)
+ {
+ pdb = new Db(&dbenv, 0);
- ret = pdb->open(NULL, // Txn pointer
- pszFile, // Filename
- "main", // Logical db name
- DB_BTREE, // Database type
- nFlags, // Flags
- 0);
+ ret = pdb->open(NULL, // Txn pointer
+ pszFile, // Filename
+ "main", // Logical db name
+ DB_BTREE, // Database type
+ nFlags, // Flags
+ 0);
- if (ret > 0)
- {
- delete pdb;
- pdb = NULL;
- CRITICAL_BLOCK(cs_db)
- --mapFileUseCount[strFile];
- strFile = "";
- throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
- }
+ if (ret > 0)
+ {
+ delete pdb;
+ pdb = NULL;
+ CRITICAL_BLOCK(cs_db)
+ --mapFileUseCount[strFile];
+ strFile = "";
+ throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
+ }
- if (fCreate && !Exists(string("version")))
- WriteVersion(VERSION);
+ if (fCreate && !Exists(string("version")))
+ {
+ bool fTmp = fReadOnly;
+ fReadOnly = false;
+ WriteVersion(VERSION);
+ fReadOnly = fTmp;
+ }
- RandAddSeed();
+ mapDb[strFile] = pdb;
+ }
+ }
}
void CDB::Close()
@@ -124,8 +129,6 @@ void CDB::Close()
if (!vTxn.empty())
vTxn.front()->abort();
vTxn.clear();
- pdb->close(0);
- delete pdb;
pdb = NULL;
dbenv.txn_checkpoint(0, 0, 0);
@@ -135,6 +138,21 @@ void CDB::Close()
RandAddSeed();
}
+void CloseDb(const string& strFile)
+{
+ CRITICAL_BLOCK(cs_db)
+ {
+ if (mapDb[strFile] != NULL)
+ {
+ // Close the database handle
+ Db* pdb = mapDb[strFile];
+ pdb->close(0);
+ delete pdb;
+ mapDb[strFile] = NULL;
+ }
+ }
+}
+
void DBFlush(bool fShutdown)
{
// Flush log data to the actual data file
@@ -144,14 +162,18 @@ void DBFlush(bool fShutdown)
return;
CRITICAL_BLOCK(cs_db)
{
- dbenv.txn_checkpoint(0, 0, 0);
map<string, int>::iterator mi = mapFileUseCount.begin();
while (mi != mapFileUseCount.end())
{
string strFile = (*mi).first;
int nRefCount = (*mi).second;
+ printf("%s refcount=%d\n", strFile.c_str(), nRefCount);
if (nRefCount == 0)
{
+ // Move log data to the dat file
+ CloseDb(strFile);
+ dbenv.txn_checkpoint(0, 0, 0);
+ printf("%s flush\n", strFile.c_str());
dbenv.lsn_reset(strFile.c_str(), 0);
mapFileUseCount.erase(mi++);
}
@@ -238,7 +260,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
+ {
+ pcursor->close();
return false;
+ }
// Unserialize
string strType;
@@ -255,9 +280,14 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
{
vtx.resize(vtx.size()+1);
if (!vtx.back().ReadFromDisk(pos))
+ {
+ pcursor->close();
return false;
+ }
}
}
+
+ pcursor->close();
return true;
}
@@ -379,6 +409,7 @@ bool CTxDB::LoadBlockIndex()
break;
}
}
+ pcursor->close();
if (!ReadHashBestChain(hashBestChain))
{
@@ -391,7 +422,7 @@ bool CTxDB::LoadBlockIndex()
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
pindexBest = mapBlockIndex[hashBestChain];
nBestHeight = pindexBest->nHeight;
- printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
+ printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
return true;
}
@@ -456,6 +487,7 @@ bool CAddrDB::LoadAddresses()
mapAddresses.insert(make_pair(addr.GetKey(), addr));
}
}
+ pcursor->close();
printf("Loaded %d addresses\n", mapAddresses.size());
@@ -558,7 +590,7 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
//printf(" %12I64d %s %s %s\n",
// wtx.vout[0].nValue,
// DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(),
- // wtx.hashBlock.ToString().substr(0,14).c_str(),
+ // wtx.hashBlock.ToString().substr(0,16).c_str(),
// wtx.mapValue["message"].c_str());
}
else if (strType == "key")
@@ -596,6 +628,7 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
}
}
+ pcursor->close();
}
printf("fShowGenerated = %d\n", fShowGenerated);
@@ -655,6 +688,8 @@ void ThreadFlushWalletDB(void* parg)
if (fOneThread)
return;
fOneThread = true;
+ if (mapArgs.count("-noflushwallet"))
+ return;
unsigned int nLastSeen = nWalletDBUpdated;
unsigned int nLastFlushed = nWalletDBUpdated;
@@ -669,24 +704,37 @@ void ThreadFlushWalletDB(void* parg)
nLastWalletUpdate = GetTime();
}
- if (nLastFlushed != nWalletDBUpdated && nLastWalletUpdate < GetTime() - 1)
+ if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
{
TRY_CRITICAL_BLOCK(cs_db)
{
- string strFile = "wallet.dat";
- map<string, int>::iterator mi = mapFileUseCount.find(strFile);
- if (mi != mapFileUseCount.end())
+ // Don't do this if any databases are in use
+ int nRefCount = 0;
+ map<string, int>::iterator mi = mapFileUseCount.begin();
+ while (mi != mapFileUseCount.end())
{
- int nRefCount = (*mi).second;
- if (nRefCount == 0 && !fShutdown)
+ nRefCount += (*mi).second;
+ mi++;
+ }
+
+ if (nRefCount == 0 && !fShutdown)
+ {
+ string strFile = "wallet.dat";
+ map<string, int>::iterator mi = mapFileUseCount.find(strFile);
+ if (mi != mapFileUseCount.end())
{
- // Flush wallet.dat so it's self contained
+ printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ printf("Flushing wallet.dat\n");
nLastFlushed = nWalletDBUpdated;
int64 nStart = GetTimeMillis();
+
+ // Flush wallet.dat so it's self contained
+ CloseDb(strFile);
dbenv.txn_checkpoint(0, 0, 0);
dbenv.lsn_reset(strFile.c_str(), 0);
- printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
+
mapFileUseCount.erase(mi++);
+ printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
}
}
}
diff --git a/db.h b/db.h
index d11b397eba..d32d2d5d2f 100644
--- a/db.h
+++ b/db.h
@@ -32,8 +32,9 @@ protected:
Db* pdb;
string strFile;
vector<DbTxn*> vTxn;
+ bool fReadOnly;
- explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false);
+ explicit CDB(const char* pszFile, const char* pszMode="r+");
~CDB() { Close(); }
public:
void Close();
@@ -77,6 +78,8 @@ protected:
{
if (!pdb)
return false;
+ if (fReadOnly)
+ assert(("Write called on database in read-only mode", false));
// Key
CDataStream ssKey(SER_DISK);
@@ -104,6 +107,8 @@ protected:
{
if (!pdb)
return false;
+ if (fReadOnly)
+ assert(("Erase called on database in read-only mode", false));
// Key
CDataStream ssKey(SER_DISK);
@@ -254,7 +259,7 @@ public:
class CTxDB : public CDB
{
public:
- CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { }
+ CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { }
private:
CTxDB(const CTxDB&);
void operator=(const CTxDB&);
@@ -283,7 +288,7 @@ public:
class CReviewDB : public CDB
{
public:
- CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { }
+ CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { }
private:
CReviewDB(const CReviewDB&);
void operator=(const CReviewDB&);
@@ -309,7 +314,7 @@ public:
class CMarketDB : public CDB
{
public:
- CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { }
+ CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { }
private:
CMarketDB(const CMarketDB&);
void operator=(const CMarketDB&);
@@ -322,7 +327,7 @@ private:
class CAddrDB : public CDB
{
public:
- CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { }
+ CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
private:
CAddrDB(const CAddrDB&);
void operator=(const CAddrDB&);
@@ -341,7 +346,7 @@ bool LoadAddresses();
class CWalletDB : public CDB
{
public:
- CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
+ CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { }
private:
CWalletDB(const CWalletDB&);
void operator=(const CWalletDB&);
diff --git a/irc.cpp b/irc.cpp
index 8432c6d145..8ac38380eb 100644
--- a/irc.cpp
+++ b/irc.cpp
@@ -159,15 +159,12 @@ void ThreadIRCSeed(void* parg)
SetThreadPriority(THREAD_PRIORITY_NORMAL);
int nErrorWait = 10;
int nRetryWait = 10;
-
- // IRC server blocks TOR users
- if (fUseProxy && addrProxy.port == htons(9050))
- return;
+ bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
while (!fShutdown)
{
CAddress addrConnect("216.155.130.130:6667");
- if (!(fUseProxy && addrProxy.port == htons(9050)))
+ if (!fTOR)
{
struct hostent* phostent = gethostbyname("chat.freenode.net");
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
@@ -188,6 +185,7 @@ void ThreadIRCSeed(void* parg)
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
{
closesocket(hSocket);
+ hSocket = INVALID_SOCKET;
nErrorWait = nErrorWait * 11 / 10;
if (Wait(nErrorWait += 60))
continue;
@@ -208,6 +206,7 @@ void ThreadIRCSeed(void* parg)
if (!RecvUntil(hSocket, " 004 "))
{
closesocket(hSocket);
+ hSocket = INVALID_SOCKET;
nErrorWait = nErrorWait * 11 / 10;
if (Wait(nErrorWait += 60))
continue;
@@ -269,6 +268,11 @@ void ThreadIRCSeed(void* parg)
}
}
closesocket(hSocket);
+ hSocket = INVALID_SOCKET;
+
+ // IRC usually blocks TOR, so only try once
+ if (fTOR)
+ return;
if (GetTime() - nStart > 20 * 60)
{
diff --git a/main.cpp b/main.cpp
index 13a9f9b72a..89b42f76e0 100644
--- a/main.cpp
+++ b/main.cpp
@@ -760,7 +760,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
bnNew = bnProofOfWorkLimit;
/// debug print
- printf("\n\n\nGetNextWorkRequired RETARGET *****\n");
+ printf("GetNextWorkRequired RETARGET\n");
printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
@@ -1013,7 +1013,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
{
- printf("*** REORGANIZE ***\n");
+ printf("REORGANIZE\n");
// Find the fork
CBlockIndex* pfork = pindexBest;
@@ -1114,7 +1114,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
// Check for duplicate
uint256 hash = GetHash();
if (mapBlockIndex.count(hash))
- return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str());
+ return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str());
// Construct new block index object
CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
@@ -1174,7 +1174,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
pindexBest = pindexNew;
nBestHeight = pindexBest->nHeight;
nTransactionsUpdated++;
- printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
+ printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
}
txdb.TxnCommit();
@@ -1294,9 +1294,9 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
// Check for duplicate
uint256 hash = pblock->GetHash();
if (mapBlockIndex.count(hash))
- return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str());
+ return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,16).c_str());
if (mapOrphanBlocks.count(hash))
- return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str());
+ return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,16).c_str());
// Preliminary checks
if (!pblock->CheckBlock())
@@ -1308,7 +1308,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
// If don't already have its previous block, shunt it off to holding area until we get it
if (!mapBlockIndex.count(pblock->hashPrevBlock))
{
- printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str());
+ printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,16).c_str());
mapOrphanBlocks.insert(make_pair(hash, pblock));
mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
@@ -1503,11 +1503,11 @@ bool LoadBlockIndex(bool fAllowNew)
// vMerkleTree: 4a5e1e
// Genesis block
- char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
+ const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
CTransaction txNew;
txNew.vin.resize(1);
txNew.vout.resize(1);
- txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp));
+ txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
CBlock block;
@@ -1519,7 +1519,7 @@ bool LoadBlockIndex(bool fAllowNew)
block.nBits = 0x1d00ffff;
block.nNonce = 2083236893;
- //// debug print, delete this later
+ //// debug print
printf("%s\n", block.GetHash().ToString().c_str());
printf("%s\n", block.hashMerkleRoot.ToString().c_str());
printf("%s\n", hashGenesisBlock.ToString().c_str());
@@ -1592,7 +1592,7 @@ void PrintBlockTree()
pindex->nHeight,
pindex->nFile,
pindex->nBlockPos,
- block.GetHash().ToString().substr(0,14).c_str(),
+ block.GetHash().ToString().substr(0,16).c_str(),
DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(),
block.vtx.size());
@@ -1912,6 +1912,18 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CBlock block;
block.ReadFromDisk((*mi).second, !pfrom->fClient);
pfrom->PushMessage("block", block);
+
+ // Trigger them to send a getblocks request for the next batch of inventory
+ if (inv.hash == pfrom->hashContinue)
+ {
+ // Bypass PushInventory, this must send even if redundant,
+ // and we want it right after the last block so they don't
+ // wait for other stuff first.
+ vector<CInv> vInv;
+ vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
+ pfrom->PushMessage("inv", vInv);
+ pfrom->hashContinue = 0;
+ }
}
}
else if (inv.IsKnownType())
@@ -1948,25 +1960,23 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Send the rest of the chain
if (pindex)
pindex = pindex->pnext;
- printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str());
+ printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str());
+ int nLimit = 500;
for (; pindex; pindex = pindex->pnext)
{
if (pindex->GetBlockHash() == hashStop)
{
- printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str());
+ printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str());
break;
}
-
- // Bypass setInventoryKnown in case an inventory message got lost
- CRITICAL_BLOCK(pfrom->cs_inventory)
+ pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
+ if (--nLimit <= 0)
{
- CInv inv(MSG_BLOCK, pindex->GetBlockHash());
- // returns true if wasn't already contained in the set
- if (pfrom->setInventoryKnown2.insert(inv).second)
- {
- pfrom->setInventoryKnown.erase(inv);
- pfrom->vInventoryToSend.push_back(inv);
- }
+ // When this block is requested, we'll send an inv that'll make them
+ // getblocks the next batch of inventory.
+ printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str());
+ pfrom->hashContinue = pindex->GetBlockHash();
+ break;
}
}
}
@@ -2049,7 +2059,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vRecv >> *pblock;
//// debug print
- printf("received block:\n"); pblock->print();
+ if (false)
+ {
+ printf("received block:\n");
+ pblock->print();
+ }
+ else
+ printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str());
CInv inv(MSG_BLOCK, pblock->GetHash());
pfrom->AddInventoryKnown(inv);
@@ -2175,9 +2191,13 @@ bool SendMessages(CNode* pto)
if (pto->nVersion == 0)
return true;
+ // Keep-alive ping
+ if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty())
+ pto->PushMessage("ping");
+
// Address refresh broadcast
static int64 nLastRebroadcast;
- if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours
+ if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours
{
nLastRebroadcast = GetTime();
CRITICAL_BLOCK(cs_vNodes)
@@ -2194,9 +2214,16 @@ bool SendMessages(CNode* pto)
}
}
- // Keep-alive ping
- if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty())
- pto->PushMessage("ping");
+ // Clear inventory known periodically in case an inv message was missed,
+ // although usually they would just get it from another node.
+ static int64 nLastInventoryKnownClear;
+ if (GetTime() - nLastInventoryKnownClear > 2 * 60 * 60) // every 2 hours
+ {
+ nLastInventoryKnownClear = GetTime();
+ CRITICAL_BLOCK(cs_vNodes)
+ foreach(CNode* pnode, vNodes)
+ pnode->setInventoryKnown.clear();
+ }
//
@@ -2243,7 +2270,6 @@ bool SendMessages(CNode* pto)
}
}
pto->vInventoryToSend.clear();
- pto->setInventoryKnown2.clear();
}
if (!vInventoryToSend.empty())
pto->PushMessage("inv", vInventoryToSend);
@@ -2817,8 +2843,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key)
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
- // maybe makes sense; please don't do it anywhere else. Keeping databases
- // open longer than necessary can create deadlocks.
+ // maybe makes sense; please don't do it anywhere else.
CWalletDB walletdb("r");
// Add the change's private key to wallet
diff --git a/main.h b/main.h
index 8bb1e19e8a..79f14c6861 100644
--- a/main.h
+++ b/main.h
@@ -1009,9 +1009,9 @@ public:
void print() const
{
printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
- GetHash().ToString().substr(0,14).c_str(),
+ GetHash().ToString().substr(0,16).c_str(),
nVersion,
- hashPrevBlock.ToString().substr(0,14).c_str(),
+ hashPrevBlock.ToString().substr(0,16).c_str(),
hashMerkleRoot.ToString().substr(0,6).c_str(),
nTime, nBits, nNonce,
vtx.size());
@@ -1159,7 +1159,7 @@ public:
return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
pprev, pnext, nFile, nBlockPos, nHeight,
hashMerkleRoot.ToString().substr(0,6).c_str(),
- GetBlockHash().ToString().substr(0,14).c_str());
+ GetBlockHash().ToString().substr(0,16).c_str());
}
void print() const
@@ -1229,8 +1229,8 @@ public:
str += CBlockIndex::ToString();
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
GetBlockHash().ToString().c_str(),
- hashPrev.ToString().substr(0,14).c_str(),
- hashNext.ToString().substr(0,14).c_str());
+ hashPrev.ToString().substr(0,16).c_str(),
+ hashNext.ToString().substr(0,16).c_str());
return str;
}
diff --git a/makefile.unix b/makefile.unix
index 24aa8bfe4f..c0d0ee1d00 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -17,24 +17,21 @@ endif
INCLUDEPATHS= \
-I"/usr/include" \
- -I"/usr/local/boost_1_40_0" \
- -I"/usr/local/db-4.7.25.NC/build_unix" \
-I"/usr/local/include/wx-2.8" \
-I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8"
LIBPATHS= \
-L"/usr/lib" \
-L"/usr/local/lib" \
- -L"/usr/local/db-4.7.25.NC/build_unix"
LIBS= \
- -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \
+ -Wl,-Bstatic -l boost_system -l boost_filesystem -Wl,-Bdynamic \
-Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \
-l crypto \
-l gtk-x11-2.0 -l gthread-2.0 -l SM
WXDEFS=-D__WXGTK__ -DNOPCH
-CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
+CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
diff --git a/net.cpp b/net.cpp
index 71295d5dee..9f4060b9da 100644
--- a/net.cpp
+++ b/net.cpp
@@ -148,8 +148,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
bool GetMyExternalIP(unsigned int& ipRet)
{
CAddress addrConnect;
- char* pszGet;
- char* pszKeyword;
+ const char* pszGet;
+ const char* pszKeyword;
if (fUseProxy)
return false;
@@ -463,14 +463,21 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
}
}
-void CNode::DoDisconnect()
+void CNode::CloseSocketDisconnect()
{
- if (fDebug)
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- printf("disconnecting node %s\n", addr.ToStringLog().c_str());
-
- closesocket(hSocket);
+ fDisconnect = true;
+ if (hSocket != INVALID_SOCKET)
+ {
+ if (fDebug)
+ printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ printf("disconnecting node %s\n", addr.ToStringLog().c_str());
+ closesocket(hSocket);
+ hSocket = INVALID_SOCKET;
+ }
+}
+void CNode::Cleanup()
+{
// All of a nodes broadcasts and subscriptions are automatically torn down
// when it goes down, so a node has to stay up to keep its broadcast going.
@@ -540,11 +547,12 @@ void ThreadSocketHandler2(void* parg)
// remove from vNodes
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
- // close socket
- pnode->DoDisconnect();
+ // close socket and cleanup
+ pnode->CloseSocketDisconnect();
+ pnode->Cleanup();
// hold in disconnected pool until all refs are released
- pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);
+ pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
if (pnode->fNetworkNode || pnode->fInbound)
pnode->Release();
vNodesDisconnected.push_back(pnode);
@@ -599,6 +607,8 @@ void ThreadSocketHandler2(void* parg)
{
foreach(CNode* pnode, vNodes)
{
+ if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
+ continue;
FD_SET(pnode->hSocket, &fdsetRecv);
FD_SET(pnode->hSocket, &fdsetError);
hSocketMax = max(hSocketMax, pnode->hSocket);
@@ -659,17 +669,22 @@ void ThreadSocketHandler2(void* parg)
//
vector<CNode*> vNodesCopy;
CRITICAL_BLOCK(cs_vNodes)
+ {
vNodesCopy = vNodes;
+ foreach(CNode* pnode, vNodesCopy)
+ pnode->AddRef();
+ }
foreach(CNode* pnode, vNodesCopy)
{
if (fShutdown)
return;
- SOCKET hSocket = pnode->hSocket;
//
// Receive
//
- if (FD_ISSET(hSocket, &fdsetRecv) || FD_ISSET(hSocket, &fdsetError))
+ if (pnode->hSocket == INVALID_SOCKET)
+ continue;
+ if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
{
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
{
@@ -678,7 +693,7 @@ void ThreadSocketHandler2(void* parg)
// typical socket buffer is 8K-64K
char pchBuf[0x10000];
- int nBytes = recv(hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
+ int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
if (nBytes > 0)
{
vRecv.resize(nPos + nBytes);
@@ -690,7 +705,7 @@ void ThreadSocketHandler2(void* parg)
// socket closed gracefully
if (!pnode->fDisconnect)
printf("socket closed\n");
- pnode->fDisconnect = true;
+ pnode->CloseSocketDisconnect();
}
else if (nBytes < 0)
{
@@ -700,7 +715,7 @@ void ThreadSocketHandler2(void* parg)
{
if (!pnode->fDisconnect)
printf("socket recv error %d\n", nErr);
- pnode->fDisconnect = true;
+ pnode->CloseSocketDisconnect();
}
}
}
@@ -709,14 +724,16 @@ void ThreadSocketHandler2(void* parg)
//
// Send
//
- if (FD_ISSET(hSocket, &fdsetSend))
+ if (pnode->hSocket == INVALID_SOCKET)
+ continue;
+ if (FD_ISSET(pnode->hSocket, &fdsetSend))
{
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
{
CDataStream& vSend = pnode->vSend;
if (!vSend.empty())
{
- int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
+ int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
if (nBytes > 0)
{
vSend.erase(vSend.begin(), vSend.begin() + nBytes);
@@ -729,7 +746,7 @@ void ThreadSocketHandler2(void* parg)
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
{
printf("socket send error %d\n", nErr);
- pnode->fDisconnect = true;
+ pnode->CloseSocketDisconnect();
}
}
}
@@ -760,18 +777,12 @@ void ThreadSocketHandler2(void* parg)
}
}
}
-
-
- //// debug heartbeat
- static int64 nHeartbeat1;
- if (GetTime() - nHeartbeat1 >= 5 * 60)
+ CRITICAL_BLOCK(cs_vNodes)
{
- printf("%s sendrecv\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- nHeartbeat1 = GetTime();
- fDebug = true;
+ foreach(CNode* pnode, vNodesCopy)
+ pnode->Release();
}
-
nThreadSocketHandlerHeartbeat = GetTime();
Sleep(10);
}
@@ -812,18 +823,21 @@ void ThreadOpenConnections2(void* parg)
printf("ThreadOpenConnections started\n");
// Connect to specific addresses
- while (mapArgs.count("-connect"))
+ if (mapArgs.count("-connect"))
{
- foreach(string strAddr, mapMultiArgs["-connect"])
+ for (int64 nLoop = 0;; nLoop++)
{
- CAddress addr(strAddr, NODE_NETWORK);
- if (addr.IsValid())
- OpenNetworkConnection(addr);
- for (int i = 0; i < 10; i++)
+ foreach(string strAddr, mapMultiArgs["-connect"])
{
- Sleep(1000);
- if (fShutdown)
- return;
+ CAddress addr(strAddr, NODE_NETWORK);
+ if (addr.IsValid())
+ OpenNetworkConnection(addr);
+ for (int i = 0; i < 10 && i < nLoop; i++)
+ {
+ Sleep(500);
+ if (fShutdown)
+ return;
+ }
}
}
}
@@ -837,7 +851,7 @@ void ThreadOpenConnections2(void* parg)
if (addr.IsValid())
{
OpenNetworkConnection(addr);
- Sleep(1000);
+ Sleep(500);
if (fShutdown)
return;
}
@@ -898,7 +912,7 @@ void ThreadOpenConnections2(void* parg)
// 30 days 27 hours
// 90 days 46 hours
// 365 days 93 hours
- int64 nDelay = 3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer;
+ int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer);
// Fast reconnect for one hour after last seen
if (nSinceLastSeen < 60 * 60)
@@ -1013,11 +1027,13 @@ void ThreadMessageHandler2(void* parg)
// Poll the connected nodes for messages
vector<CNode*> vNodesCopy;
CRITICAL_BLOCK(cs_vNodes)
+ {
vNodesCopy = vNodes;
+ foreach(CNode* pnode, vNodesCopy)
+ pnode->AddRef();
+ }
foreach(CNode* pnode, vNodesCopy)
{
- pnode->AddRef();
-
// Receive messages
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
ProcessMessages(pnode);
@@ -1029,8 +1045,11 @@ void ThreadMessageHandler2(void* parg)
SendMessages(pnode);
if (fShutdown)
return;
-
- pnode->Release();
+ }
+ CRITICAL_BLOCK(cs_vNodes)
+ {
+ foreach(CNode* pnode, vNodesCopy)
+ pnode->Release();
}
// Wait and allow messages to bunch up
@@ -1257,8 +1276,7 @@ void StartNode(void* parg)
if (!fGot)
{
printf("*** closing socket\n");
- closesocket(pnode->hSocket);
- pnode->fDisconnect = true;
+ pnode->CloseSocketDisconnect();
}
}
}
@@ -1292,7 +1310,7 @@ bool StopNode()
int64 nStart = GetTime();
while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0)
{
- if (GetTime() - nStart > 15)
+ if (GetTime() - nStart > 20)
break;
Sleep(20);
}
diff --git a/net.h b/net.h
index 65bbb96077..7d71be49da 100644
--- a/net.h
+++ b/net.h
@@ -414,7 +414,7 @@ public:
string ToString() const
{
- return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str());
+ return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,16).c_str());
}
void print() const
@@ -504,6 +504,7 @@ public:
int64 nReleaseTime;
map<uint256, CRequestTracker> mapRequests;
CCriticalSection cs_mapRequests;
+ uint256 hashContinue;
// flood
vector<CAddress> vAddrToSend;
@@ -512,7 +513,6 @@ public:
// inventory based relay
set<CInv> setInventoryKnown;
- set<CInv> setInventoryKnown2;
vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
multimap<int64, CInv> mapAskFor;
@@ -541,6 +541,7 @@ public:
fDisconnect = false;
nRefCount = 0;
nReleaseTime = 0;
+ hashContinue = 0;
fGetAddr = false;
vfSubscribe.assign(256, false);
@@ -550,13 +551,16 @@ public:
CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
- PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string("test5"));
+ PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string(pszSubVer));
}
~CNode()
{
if (hSocket != INVALID_SOCKET)
+ {
closesocket(hSocket);
+ hSocket = INVALID_SOCKET;
+ }
}
private:
@@ -570,12 +574,13 @@ public:
return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
}
- void AddRef(int64 nTimeout=0)
+ CNode* AddRef(int64 nTimeout=0)
{
if (nTimeout != 0)
nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
else
nRefCount++;
+ return this;
}
void Release()
@@ -899,7 +904,8 @@ public:
bool IsSubscribed(unsigned int nChannel);
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
void CancelSubscribe(unsigned int nChannel);
- void DoDisconnect();
+ void CloseSocketDisconnect();
+ void Cleanup();
};
diff --git a/serialize.h b/serialize.h
index 9b20e2a0f6..aae821b6d2 100644
--- a/serialize.h
+++ b/serialize.h
@@ -20,6 +20,7 @@ class CDataStream;
class CAutoFile;
static const int VERSION = 106;
+static const char* pszSubVer = " linux-test8";
diff --git a/ui.cpp b/ui.cpp
index 9d7556cb57..aaa26adf00 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -1664,7 +1664,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
{
- m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Beta", VERSION/100, VERSION%100));
+ m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100));
// Workaround until upgrade to wxWidgets supporting UTF-8
wxString str = m_staticTextMain->GetLabel();
@@ -2030,7 +2030,7 @@ void CSendingDialog::StartTransfer()
// We may have connected already for product details
if (!Status("Connecting..."))
return;
- CNode* pnode = ConnectNode(addr, 5 * 60);
+ CNode* pnode = ConnectNode(addr, 15 * 60);
if (!pnode)
{
Error("Unable to connect");
@@ -2075,14 +2075,6 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
return;
}
- // Should already be connected
- CNode* pnode = ConnectNode(addr, 5 * 60);
- if (!pnode)
- {
- Error("Lost connection");
- return;
- }
-
// Pause to give the user a chance to cancel
while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000))
{
@@ -2112,6 +2104,14 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
return;
}
+ // Make sure we're still connected
+ CNode* pnode = ConnectNode(addr, 2 * 60 * 60);
+ if (!pnode)
+ {
+ Error("Lost connection, transaction cancelled");
+ return;
+ }
+
// Last chance to cancel
Sleep(50);
if (!Status())
@@ -3495,12 +3495,14 @@ bool CMyApp::OnInit2()
if (mapArgs.count("-debug"))
fDebug = true;
+ if (strstr(pszSubVer, "test"))
+ fDebug = true;
if (mapArgs.count("-printtodebugger"))
fPrintToDebugger = true;
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str());
+ printf("Bitcoin version %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str());
if (mapArgs.count("-loadblockindextest"))
{
@@ -3843,9 +3845,8 @@ void SetStartOnSystemStartup(bool fAutoStart)
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
- HRESULT hres = NULL;
IShellLink* psl = NULL;
- hres = CoCreateInstance(CLSID_ShellLink, NULL,
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
diff --git a/util.cpp b/util.cpp
index 7a947730ce..305db5ceeb 100644
--- a/util.cpp
+++ b/util.cpp
@@ -56,9 +56,11 @@ public:
// Close sockets
foreach(CNode* pnode, vNodes)
- closesocket(pnode->hSocket);
- if (closesocket(hListenSocket) == SOCKET_ERROR)
- printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
+ if (pnode->hSocket != INVALID_SOCKET)
+ closesocket(pnode->hSocket);
+ if (hListenSocket != INVALID_SOCKET)
+ if (closesocket(hListenSocket) == SOCKET_ERROR)
+ printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
#ifdef __WXMSW__
// Shutdown Windows Sockets
@@ -348,7 +350,7 @@ void ParseParameters(int argc, char* argv[])
{
char psz[10000];
strlcpy(psz, argv[i], sizeof(psz));
- char* pszValue = "";
+ char* pszValue = (char*)"";
if (strchr(psz, '='))
{
pszValue = strchr(psz, '=');
diff --git a/util.h b/util.h
index ddac449441..9366e66e93 100644
--- a/util.h
+++ b/util.h
@@ -57,9 +57,11 @@ inline T& REF(const T& val)
#ifdef __WXMSW__
#define MSG_NOSIGNAL 0
#define MSG_DONTWAIT 0
+#ifndef UINT64_MAX
#define UINT64_MAX _UI64_MAX
#define INT64_MAX _I64_MAX
#define INT64_MIN _I64_MIN
+#endif
#else
#define WSAGetLastError() errno
#define WSAEWOULDBLOCK EWOULDBLOCK
@@ -67,7 +69,7 @@ inline T& REF(const T& val)
#define WSAEINTR EINTR
#define WSAEINPROGRESS EINPROGRESS
#define WSAEADDRINUSE EADDRINUSE
-#define closesocket(s) close(s)
+#define WSAENOTSOCK EBADF
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR -1
typedef u_int SOCKET;
@@ -80,6 +82,23 @@ typedef u_int SOCKET;
#define Beep(n1,n2) (0)
#endif
+inline int myclosesocket(SOCKET& hSocket)
+{
+ if (hSocket == INVALID_SOCKET)
+ return WSAENOTSOCK;
+#ifdef __WXMSW__
+ int ret = closesocket(hSocket);
+#else
+ int ret = close(hSocket);
+#endif
+ hSocket = INVALID_SOCKET;
+ return ret;
+}
+#define closesocket(s) myclosesocket(s)
+
+
+
+
@@ -149,7 +168,7 @@ public:
bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; }
#endif
public:
- char* pszFile;
+ const char* pszFile;
int nLine;
};
diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm
index 471f700c70..e00944ef7a 100644
--- a/xpm/addressbook16.xpm
+++ b/xpm/addressbook16.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * addressbook16_xpm[] = {
+static const char * addressbook16_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 256 2",
" c #FFFFFF",
diff --git a/xpm/addressbook20.xpm b/xpm/addressbook20.xpm
index 48df12d801..7ebd73fb2f 100644
--- a/xpm/addressbook20.xpm
+++ b/xpm/addressbook20.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * addressbook20_xpm[] = {
+static const char * addressbook20_xpm[] = {
/* columns rows colors chars-per-pixel */
"20 20 256 2",
" c #FFFFFF",
diff --git a/xpm/bitcoin16.xpm b/xpm/bitcoin16.xpm
index 8bec142c8b..a1397522a5 100644
--- a/xpm/bitcoin16.xpm
+++ b/xpm/bitcoin16.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * bitcoin16_xpm[] = {
+static const char * bitcoin16_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 181 2",
" c #775605",
diff --git a/xpm/bitcoin20.xpm b/xpm/bitcoin20.xpm
index 2dd61a59dc..93b34ba70c 100644
--- a/xpm/bitcoin20.xpm
+++ b/xpm/bitcoin20.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * bitcoin20_xpm[] = {
+static const char * bitcoin20_xpm[] = {
/* columns rows colors chars-per-pixel */
"20 20 200 2",
" c #7B5500",
diff --git a/xpm/bitcoin32.xpm b/xpm/bitcoin32.xpm
index 25da102f6a..0ac49f61a9 100644
--- a/xpm/bitcoin32.xpm
+++ b/xpm/bitcoin32.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * bitcoin32_xpm[] = {
+static const char * bitcoin32_xpm[] = {
/* columns rows colors chars-per-pixel */
"32 32 185 2",
" c #715103",
diff --git a/xpm/bitcoin48.xpm b/xpm/bitcoin48.xpm
index 788e855ddd..bc388bdcb7 100644
--- a/xpm/bitcoin48.xpm
+++ b/xpm/bitcoin48.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * bitcoin48_xpm[] = {
+static const char * bitcoin48_xpm[] = {
/* columns rows colors chars-per-pixel */
"48 48 224 2",
" c #715103",
diff --git a/xpm/check.xpm b/xpm/check.xpm
index 8f0b9d28ec..e62b656961 100644
--- a/xpm/check.xpm
+++ b/xpm/check.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * check_xpm[] = {
+static const char * check_xpm[] = {
/* columns rows colors chars-per-pixel */
"32 32 3 1",
" c #008000",
diff --git a/xpm/send16.xpm b/xpm/send16.xpm
index 1eeceb4ec7..7da44d9c56 100644
--- a/xpm/send16.xpm
+++ b/xpm/send16.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * send16_xpm[] = {
+static const char * send16_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 256 2",
" c #ADF7AD",
diff --git a/xpm/send16noshadow.xpm b/xpm/send16noshadow.xpm
index d1b482ef97..f6cef45e0d 100644
--- a/xpm/send16noshadow.xpm
+++ b/xpm/send16noshadow.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * send16noshadow_xpm[] = {
+static const char * send16noshadow_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 256 2",
" c #ADF7AD",
diff --git a/xpm/send20.xpm b/xpm/send20.xpm
index 597ea146d1..68e7b1379a 100644
--- a/xpm/send20.xpm
+++ b/xpm/send20.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * send20_xpm[] = {
+static const char * send20_xpm[] = {
/* columns rows colors chars-per-pixel */
"20 20 256 2",
" c #CEFFCE",