StartupCache::~StartupCache() { if (mTimer) { mTimer->Cancel(); } // Generally, the in-memory table should be empty here, // but an early shutdown means either mTimer didn't run // or the write thread is still running. WaitOnWriteThread(); // If we shutdown quickly timer wont have fired. Instead of writing // it on the main thread and block the shutdown we simply wont update // the startup cache. Always do this if the file doesn't exist since // we use it part of the packge step. if (!mArchive) { WriteToDisk(); } gStartupCache = nullptr; (void)::NS_UnregisterMemoryReporter(mMappingMemoryReporter); (void)::NS_UnregisterMemoryReporter(mDataMemoryReporter); mMappingMemoryReporter = nullptr; mDataMemoryReporter = nullptr; }
//***************************************************************************** // For cached writes, flush the cache to the data store. //***************************************************************************** HRESULT StgIO::FlushCache() { ULONG cbWritten; HRESULT hr; if (m_cbBuff) { if (FAILED(hr = WriteToDisk(m_rgBuff, m_cbBuff, &cbWritten))) return (hr); m_cbBuff = 0; } return (S_OK); }
//***************************************************************************** // Write to disk. This function will cache up to a page of data in a buffer // and peridocially flush it on overflow and explicit request. This makes it // safe to do lots of small writes without too much performance overhead. //***************************************************************************** HRESULT StgIO::Write( // true/false. const void *pbBuff, // Data to write. ULONG cbWrite, // How much data to write. ULONG *pcbWritten) // How much did get written. { ULONG cbWriteIn=cbWrite; // Track amount written. ULONG cbCopy; HRESULT hr = S_OK; _ASSERTE(m_rgBuff != 0); _ASSERTE(cbWrite); while (cbWrite) { // In the case where the buffer is already huge, write the whole thing // and avoid the cache. if (m_cbBuff == 0 && cbWrite >= (ULONG) m_iPageSize) { if (SUCCEEDED(hr = WriteToDisk(pbBuff, cbWrite, pcbWritten))) m_cbOffset += cbWrite; break; } // Otherwise cache as much as we can and flush. else { // Determine how much data goes into the cache buffer. cbCopy = m_iPageSize - m_cbBuff; cbCopy = min(cbCopy, cbWrite); // Copy the data into the cache and adjust counts. memcpy(&m_rgBuff[m_cbBuff], pbBuff, cbCopy); pbBuff = (void *) ((DWORD_PTR)pbBuff + cbCopy); m_cbBuff += cbCopy; m_cbOffset += cbCopy; cbWrite -= cbCopy; // If there is enough data, then flush it to disk and reset count. if (m_cbBuff >= (ULONG) m_iPageSize) { if (FAILED(hr = FlushCache())) break; } } } // Return value for caller. if (SUCCEEDED(hr) && pcbWritten) *pcbWritten = cbWriteIn; return (hr); }
StartupCache::~StartupCache() { if (mTimer) { mTimer->Cancel(); } // Generally, the in-memory table should be empty here, // but an early shutdown means either mTimer didn't run // or the write thread is still running. WaitOnWriteThread(); WriteToDisk(); gStartupCache = nullptr; (void)::NS_UnregisterMemoryReporter(mMappingMemoryReporter); (void)::NS_UnregisterMemoryReporter(mDataMemoryReporter); mMappingMemoryReporter = nullptr; mDataMemoryReporter = nullptr; }
FileHandle::~FileHandle() { WriteToDisk(); FileInfo* fp = first_file_; while (fp != NULL) { FileInfo* fpn = fp->GetNext(); BlockInfo* bp = fp->GetFirstBlock(); while (bp != NULL) { BlockInfo* bpn = bp->GetNext(); delete bp; bp = bpn; } delete fp; fp = fpn; } }
INT_PTR CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l) { switch (m) { case WM_TIMER: { // update the recording/playback counter char text[30]=""; if (rchan) // recording sprintf(text,"%d",reclen-44); else if (chan) { if (BASS_ChannelIsActive(chan)) // playing sprintf(text,"%I64d / %I64d",BASS_ChannelGetPosition(chan,BASS_POS_BYTE),BASS_ChannelGetLength(chan,BASS_POS_BYTE)); else sprintf(text,"%I64d",BASS_ChannelGetLength(chan,BASS_POS_BYTE)); } MESS(20,WM_SETTEXT,0,text); } break; case WM_COMMAND: switch (LOWORD(w)) { case IDCANCEL: DestroyWindow(h); break; case 10: if (!rchan) StartRecording(); else StopRecording(); break; case 11: BASS_ChannelPlay(chan,TRUE); // play the recorded data break; case 12: WriteToDisk(); break; case 13: if (HIWORD(w)==CBN_SELCHANGE) { // input selection changed int i; input=MESS(13,CB_GETCURSEL,0,0); // get the selection // enable the selected input for (i=0;BASS_RecordSetInput(i,BASS_INPUT_OFF,-1);i++) ; // 1st disable all inputs, then... BASS_RecordSetInput(input,BASS_INPUT_ON,-1); // enable the selected UpdateInputInfo(); } break; case 16: if (HIWORD(w)==CBN_SELCHANGE) { // device selection changed int i=MESS(16,CB_GETCURSEL,0,0); // get the selection // initialize the selected device if (InitDevice(i)) { if (rchan) { // continue recording on the new device... HRECORD newrchan=BASS_RecordStart(FREQ,CHANS,0,RecordingCallback,0); if (!newrchan) Error("Couldn't start recording"); else rchan=newrchan; } } } break; } break; case WM_HSCROLL: if (l) { // set input source level float level=SendMessage((HWND)l,TBM_GETPOS,0,0)/100.f; if (!BASS_RecordSetInput(input,0,level)) // failed to set input level BASS_RecordSetInput(-1,0,level); // try master level instead } break; case WM_INITDIALOG: win=h; MESS(14,TBM_SETRANGE,FALSE,MAKELONG(0,100)); { // get list of recording devices int c,def; BASS_DEVICEINFO di; for (c=0;BASS_RecordGetDeviceInfo(c,&di);c++) { MESS(16,CB_ADDSTRING,0,di.name); if (di.flags&BASS_DEVICE_DEFAULT) { // got the default device MESS(16,CB_SETCURSEL,c,0); def=c; } } InitDevice(def); // initialize default recording device } SetTimer(h,0,200,0); // timer to update the position display return 1; case WM_DESTROY: // release all BASS stuff BASS_RecordFree(); BASS_Free(); break; } return 0; }
BOOL CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l) { switch (m) { case WM_TIMER: { // update the recording/playback counter char text[30]=""; if (rchan) // recording sprintf(text,"%I64d",BASS_ChannelGetPosition(rchan,BASS_POS_BYTE)); else if (chan) { if (BASS_ChannelIsActive(chan)) // playing sprintf(text,"%I64d / %I64d",BASS_ChannelGetPosition(chan,BASS_POS_BYTE),BASS_ChannelGetLength(chan,BASS_POS_BYTE)); else sprintf(text,"%I64d",BASS_ChannelGetLength(chan,BASS_POS_BYTE)); } MESS(20,WM_SETTEXT,0,text); } break; case WM_COMMAND: switch (LOWORD(w)) { case IDCANCEL: DestroyWindow(h); break; case 10: if (!rchan) StartRecording(); else StopRecording(); break; case 11: BASS_ChannelPlay(chan,TRUE); // play the recorded data break; case 12: WriteToDisk(); break; case 13: if (HIWORD(w)==CBN_SELCHANGE) { // input selection changed int i; input=MESS(13,CB_GETCURSEL,0,0); // get the selection // enable the selected input for (i=0;BASS_RecordSetInput(i,BASS_INPUT_OFF,-1);i++) ; // 1st disable all inputs, then... BASS_RecordSetInput(input,BASS_INPUT_ON,-1); // enable the selected UpdateInputInfo(); // update info } break; } break; case WM_HSCROLL: if (l) { // set input source level float level=SendMessage((HWND)l,TBM_GETPOS,0,0)/100.f; if (!BASS_RecordSetInput(input,0,level)) // failed to set input level BASS_RecordSetInput(-1,0,level); // try master level instead } break; case WM_INITDIALOG: win=h; // setup recording device (using default device) if (!BASS_RecordInit(-1)) { Error("Can't initialize recording device"); DestroyWindow(win); } else { // get list of inputs int c; const char *i; MESS(14,TBM_SETRANGE,FALSE,MAKELONG(0,100)); // initialize input level slider for (c=0;i=BASS_RecordGetInputName(c);c++) { MESS(13,CB_ADDSTRING,0,i); if (!(BASS_RecordGetInput(c,NULL)&BASS_INPUT_OFF)) { // this 1 is currently "on" input=c; MESS(13,CB_SETCURSEL,input,0); UpdateInputInfo(); // display info } } SetTimer(h,0,200,0); // timer to update the position display return 1; } break; case WM_DESTROY: // release all BASS stuff BASS_RecordFree(); BASS_Free(); break; } return 0; }
Bookkeeper::~Bookkeeper() { WriteToDisk(); }
bool CBlock::AcceptBlock() { AssertLockHeld(cs_main); if (nVersion > CURRENT_VERSION) return DoS(100, error("AcceptBlock() : reject unknown block version %d", nVersion)); // Check for duplicate uint256 hash = GetHash(); if (mapBlockIndex.count(hash)) return error("AcceptBlock() : block already in mapBlockIndex"); // Get prev block index map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); if (mi == mapBlockIndex.end()) return DoS(10, error("AcceptBlock() : prev block not found")); CBlockIndex* pindexPrev = (*mi).second; int nHeight = pindexPrev->nHeight+1; if (IsProofOfStake() && nHeight < Params().FirstPOSBlock()) return DoS(100, error("AcceptBlock() : reject proof-of-stake at height <= %d", nHeight)); // Check coinbase timestamp if (GetBlockTime() > FutureDrift((int64_t)vtx[0].nTime, IsProofOfStake())) return DoS(50, error("AcceptBlock() : coinbase timestamp is too early")); // Check coinstake timestamp if (IsProofOfStake() && !CheckCoinStakeTimestamp(nHeight, GetBlockTime(), (int64_t)vtx[1].nTime)) return DoS(50, error("AcceptBlock() : coinstake timestamp violation nTimeBlock=%d nTimeTx=%u", GetBlockTime(), vtx[1].nTime)); // Check proof-of-work or proof-of-stake if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); // Check timestamp against prev LogPrintf("GetBlockTime(): %d, <=? pindexPrev->GetPastTimeLimit(): %d\nFutureDrift(GetBlockTime()): %d, <?pindexPrev->GetBlockTime(): %d\n",GetBlockTime(),pindexPrev->GetPastTimeLimit(),FutureDrift(GetBlockTime()),pindexPrev->GetBlockTime()); if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime(), IsProofOfStake()) < pindexPrev->GetBlockTime()) return error("AcceptBlock() : block's timestamp is too early"); // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, vtx) if (!IsFinalTx(tx, nHeight, GetBlockTime())) return DoS(10, error("AcceptBlock() : contains a non-final transaction")); // Check that the block chain matches the known block chain up to a checkpoint if (!Checkpoints::CheckHardened(nHeight, hash)) return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight)); uint256 hashProof; // Verify hash target and signature of coinstake tx if (IsProofOfStake()) { uint256 targetProofOfStake; if (!CheckProofOfStake(pindexPrev, vtx[1], nBits, hashProof, targetProofOfStake)) { return error("AcceptBlock() : check proof-of-stake failed for block %s", hash.ToString()); } } // PoW is checked in CheckBlock() if (IsProofOfWork()) { hashProof = GetPoWHash(); } // Check that the block satisfies synchronized checkpoint if (!Checkpoints::CheckSync(nHeight)) return error("AcceptBlock() : rejected by synchronized checkpoint"); // Enforce rule that the coinbase starts with serialized block height CScript expect = CScript() << nHeight; if (vtx[0].vin[0].scriptSig.size() < expect.size() || !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) return DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); // Write block to history file if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) return error("AcceptBlock() : out of disk space"); unsigned int nFile = -1; unsigned int nBlockPos = 0; if (!WriteToDisk(nFile, nBlockPos)) return error("AcceptBlock() : WriteToDisk failed"); if (!AddToBlockIndex(nFile, nBlockPos, hashProof)) return error("AcceptBlock() : AddToBlockIndex failed"); // Relay inventory, but don't relay old inventory during initial block download int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); if (hashBestChain == hash) { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hash)); }