Resolved a TODO in Journal::Lock() that Urias reminded me about:
* BFS now uses a transaction listener that flushes the current transaction in case it is idle; before, transactions would always be kept open when they weren't large, so that the block writer could not write back the blocks (they were busy from its POV). * This solves the described problem of the screen resolution not being written back even after minutes of inactivity. * Renamed _TransactionNotify() to _TransactionWritten() to differentiate it a bit more from the new _TransactionListener(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24738 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
16d8ff2dad
commit
3c78c04589
@ -531,8 +531,8 @@ Journal::ReplayLog()
|
||||
the log start pointer as needed. Note, the transactions may not be
|
||||
completed in the order they were written.
|
||||
*/
|
||||
void
|
||||
Journal::_TransactionNotify(int32 transactionID, int32 event, void *_logEntry)
|
||||
/*static*/ void
|
||||
Journal::_TransactionWritten(int32 transactionID, int32 event, void *_logEntry)
|
||||
{
|
||||
LogEntry *logEntry = (LogEntry *)_logEntry;
|
||||
|
||||
@ -577,13 +577,27 @@ Journal::_TransactionNotify(int32 transactionID, int32 event, void *_logEntry)
|
||||
|
||||
status_t status = journal->fVolume->WriteSuperBlock();
|
||||
if (status != B_OK) {
|
||||
FATAL(("_BlockNotify: could not write back super block: %s\n",
|
||||
FATAL(("_TransactionWritten: could not write back super block: %s\n",
|
||||
strerror(status)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Listens to TRANSACTION_IDLE events, and flushes the log when that happens */
|
||||
/*static*/ void
|
||||
Journal::_TransactionListener(int32 transactionID, int32 event, void *_journal)
|
||||
{
|
||||
if (event != TRANSACTION_IDLE)
|
||||
return;
|
||||
|
||||
// The current transaction seems to be idle - flush it
|
||||
|
||||
Journal *journal = (Journal *)_journal;
|
||||
journal->_FlushLog();
|
||||
}
|
||||
|
||||
|
||||
/*! Writes the blocks that are part of current transaction into the log,
|
||||
and ends the current transaction.
|
||||
If the current transaction is too large to fit into the log, it will
|
||||
@ -763,11 +777,11 @@ Journal::_WriteTransactionToLog()
|
||||
|
||||
if (detached) {
|
||||
fTransactionID = cache_detach_sub_transaction(fVolume->BlockCache(),
|
||||
fTransactionID, _TransactionNotify, logEntry);
|
||||
fTransactionID, _TransactionWritten, logEntry);
|
||||
fUnwrittenTransactions = 1;
|
||||
} else {
|
||||
cache_end_transaction(fVolume->BlockCache(), fTransactionID,
|
||||
_TransactionNotify, logEntry);
|
||||
_TransactionWritten, logEntry);
|
||||
fUnwrittenTransactions = 0;
|
||||
}
|
||||
|
||||
@ -775,8 +789,11 @@ Journal::_WriteTransactionToLog()
|
||||
}
|
||||
|
||||
|
||||
/*! Flushes the current log entry to disk. If \a flushBlocks is \c true it will
|
||||
also write back all dirty blocks for this volume.
|
||||
*/
|
||||
status_t
|
||||
Journal::FlushLogAndBlocks()
|
||||
Journal::_FlushLog(bool flushBlocks)
|
||||
{
|
||||
status_t status = fLock.Lock();
|
||||
if (status != B_OK)
|
||||
@ -796,13 +813,24 @@ Journal::FlushLogAndBlocks()
|
||||
FATAL(("writing current log entry failed: %s\n", strerror(status)));
|
||||
}
|
||||
|
||||
status = fVolume->FlushDevice();
|
||||
if (flushBlocks)
|
||||
status = fVolume->FlushDevice();
|
||||
|
||||
fLock.Unlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*! Flushes the current log entry to disk, and also writes back all dirty
|
||||
blocks for this volume (completing all open transactions).
|
||||
*/
|
||||
status_t
|
||||
Journal::FlushLogAndBlocks()
|
||||
{
|
||||
return _FlushLog(true);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Journal::Lock(Transaction *owner)
|
||||
{
|
||||
@ -810,12 +838,6 @@ Journal::Lock(Transaction *owner)
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
/* ToDo:
|
||||
// if the last transaction is older than 2 secs, start a new one
|
||||
if (fTransactionsInEntry != 0 && system_time() - fTimestamp > 2000000L)
|
||||
WriteLogEntry();
|
||||
*/
|
||||
|
||||
if (fLock.OwnerCount() > 1) {
|
||||
// we'll just use the current transaction again
|
||||
return B_OK;
|
||||
@ -842,6 +864,9 @@ Journal::Lock(Transaction *owner)
|
||||
return fTransactionID;
|
||||
}
|
||||
|
||||
cache_add_transaction_listener(fVolume->BlockCache(), fTransactionID,
|
||||
_TransactionListener, this);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -867,7 +892,7 @@ Journal::_TransactionSize() const
|
||||
{
|
||||
int32 count = cache_blocks_in_transaction(fVolume->BlockCache(),
|
||||
fTransactionID);
|
||||
if (count < 0)
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
// take the number of array blocks in this transaction into account
|
||||
|
@ -52,13 +52,17 @@ class Journal {
|
||||
|
||||
private:
|
||||
bool _HasSubTransaction() { return fHasSubtransaction; }
|
||||
status_t _FlushLog(bool flushBlocks = false);
|
||||
uint32 _TransactionSize() const;
|
||||
status_t _WriteTransactionToLog();
|
||||
status_t _CheckRunArray(const run_array *array);
|
||||
status_t _ReplayRunArray(int32 *start);
|
||||
status_t _TransactionDone(bool success);
|
||||
static void _TransactionNotify(int32 transactionID, int32 event,
|
||||
|
||||
static void _TransactionWritten(int32 transactionID, int32 event,
|
||||
void *_logEntry);
|
||||
static void _TransactionListener(int32 transactionID, int32 event,
|
||||
void *_journal);
|
||||
|
||||
Volume *fVolume;
|
||||
RecursiveLock fLock;
|
||||
|
Loading…
Reference in New Issue
Block a user