Lines Matching refs:transaction

55 	// a transaction is considered idle after 2 seconds of inactivity
74 // When in a transaction, this contains the original data from before
75 // the transaction.
78 // block in the parent transaction. It may point to current_data if the
79 // contents have been changed only in the parent transaction, or, if the
80 // block has been changed in the current sub transaction already, to a
81 // new block containing the contents changed in the parent transaction.
83 // transaction at all.
99 cache_transaction* transaction;
100 // This is the current active transaction, if any, the block is
103 // This is set to the last transaction that was ended containing this
106 // latter if the block is already being part of another transaction.
107 // There can only be one previous transaction, so when the active
108 // transaction ends, the changes of the previous transaction have to
109 // be written back before that transaction becomes the next previous
110 // transaction.
204 size_t Hash(ValueType* transaction) const;
205 bool Compare(KeyType key, ValueType* transaction) const;
290 cache_transaction* transaction = NULL);
291 bool Add(cache_transaction* transaction,
294 status_t Write(cache_transaction* transaction = NULL,
307 cache_transaction* transaction);
376 if (block->transaction != NULL)
377 fTransactionID = block->transaction->id;
384 out.Print("block cache %p, %s %" B_PRIu64 ", %c%c%c transaction %" B_PRId32
638 cache_transaction* transaction)
641 fTransaction(transaction),
642 fID(transaction->id),
643 fSub(transaction->has_sub_transaction),
644 fNumBlocks(transaction->num_blocks),
645 fSubNumBlocks(transaction->sub_num_blocks)
653 out.Print("block cache %p, %s transaction %p (id %" B_PRId32 ")%s"
670 Detach(block_cache* cache, cache_transaction* transaction,
674 fTransaction(transaction),
675 fID(transaction->id),
676 fSub(transaction->has_sub_transaction),
685 out.Print("block cache %p, detach transaction %p (id %" B_PRId32 ")"
686 "from transaction %p (id %" B_PRId32 ")%s",
702 Abort(block_cache* cache, cache_transaction* transaction)
705 fTransaction(transaction),
706 fID(transaction->id),
709 bool isSub = transaction->has_sub_transaction;
710 fNumBlocks = isSub ? transaction->sub_num_blocks
711 : transaction->num_blocks;
714 cached_block* block = transaction->first_block;
732 out.Print("block cache %p, abort transaction "
781 /*! Checks whether or not this is an event that closes a transaction. */
876 set_notification(cache_transaction* transaction,
880 notification.transaction_id = transaction != NULL ? transaction->id : -1;
935 /*! Notifies all interested listeners of this transaction about the \a event.
941 notify_transaction_listeners(block_cache* cache, cache_transaction* transaction,
944 T(Action("notify", cache, transaction));
949 ListenerList::Iterator iterator = transaction->listeners.GetIterator();
967 transaction.
970 remove_transaction_listeners(block_cache* cache, cache_transaction* transaction)
972 ListenerList::Iterator iterator = transaction->listeners.GetIterator();
983 add_transaction_listener(block_cache* cache, cache_transaction* transaction,
986 ListenerList::Iterator iterator = transaction->listeners.GetIterator();
1001 set_notification(transaction, *listener, events, hookFunction, data);
1002 transaction->listeners.Add(listener);
1007 // #pragma mark - private transaction
1024 delete_transaction(block_cache* cache, cache_transaction* transaction)
1026 if (cache->last_transaction == transaction)
1029 remove_transaction_listeners(cache, transaction);
1030 delete transaction;
1041 size_t TransactionHash::Hash(cache_transaction* transaction) const
1043 return transaction->id;
1047 bool TransactionHash::Compare(int32 key, cache_transaction* transaction) const
1049 return transaction->id == key;
1059 /*! Writes back any changes made to blocks in \a transaction that are still
1064 cache_transaction* transaction)
1068 cached_block* block = transaction->first_block;
1088 || (transaction == NULL && is_dirty && !is_writing));
1120 BlockWriter::Add(cached_block* block, cache_transaction* transaction)
1141 Write(transaction, false);
1162 /*! Adds all blocks of the specified transaction to the to be written array.
1166 BlockWriter::Add(cache_transaction* transaction, bool& hasLeftOvers)
1168 ASSERT(!transaction->open);
1170 if (transaction->busy_writing_count != 0) {
1177 block_list::Iterator blockIterator = transaction->blocks.GetIterator();
1180 // This block was already part of a previous transaction within this
1185 if (!Add(block, transaction))
1200 BlockWriter::Write(cache_transaction* transaction, bool canUnlock)
1241 _BlockDone(fBlocks[i], transaction);
1249 the oldest change of the block if it is part of more than one transaction.
1303 cache_transaction* transaction)
1323 if (block->original_data != NULL && block->transaction == NULL) {
1324 // This block is not part of a transaction, so it does not need
1330 // Has the previous transaction been finished with that write?
1332 TRACE(("cache transaction %" B_PRId32 " finished!\n", previous->id));
1338 if (transaction != NULL) {
1343 fCache->transaction_hash->RemoveUnchecked(transaction);
1351 if (block->transaction == NULL && block->ref_count == 0 && !block->unused) {
1440 condition_variable.Init(this, "cache transaction sync");
1540 block->transaction = block->previous_transaction = NULL;
1614 /*! Discards the block from a transaction (this method must not be called
1615 for blocks not part of a transaction).
1858 && block->transaction == NULL && block->previous_transaction == NULL) {
1859 // This block is not used anymore, and not part of any transaction
1978 This is the only method to insert a block into a transaction. It makes
1985 TRACE(("get_writable_cached_block(blockNumber = %" B_PRIdOFF ", transaction = %" B_PRId32 ")\n",
2006 // if there is no transaction support, we just return the current block
2031 cache_transaction* transaction = block->transaction;
2033 if (transaction != NULL && transaction->id != transactionID) {
2034 // TODO: we have to wait here until the other transaction is done.
2037 "(transaction %" B_PRId32 ")\n", block->transaction->id);
2041 if (transaction == NULL && transactionID != -1) {
2042 // get new transaction
2043 transaction = lookup_transaction(cache, transactionID);
2044 if (transaction == NULL) {
2045 panic("get_writable_cached_block(): invalid transaction %" B_PRId32 "!\n",
2050 if (!transaction->open) {
2051 panic("get_writable_cached_block(): transaction already done!\n");
2056 block->transaction = transaction;
2058 // attach the block to the transaction block list
2059 block->transaction_next = transaction->first_block;
2060 transaction->first_block = block;
2061 transaction->num_blocks++;
2063 if (transaction != NULL)
2064 transaction->last_used = system_time();
2088 // remember any previous contents for the parent transaction
2091 // TODO: maybe we should just continue the current transaction in
2107 transaction->sub_num_blocks++;
2108 } else if (transaction != NULL && transaction->has_sub_transaction
2110 transaction->sub_num_blocks++;
2145 (addr_t)block->transaction,
2176 if (block->transaction != NULL) {
2177 kprintf(" transaction: %p (%" B_PRId32 ")\n", block->transaction,
2178 block->transaction->id);
2180 kprintf(" next in transaction: %" B_PRIdOFF "\n",
2185 kprintf(" previous transaction: %p (%" B_PRId32 ")\n",
2287 cache_transaction* transaction = iterator.Next();
2289 B_PRId32 "\n", transaction, transaction->id,
2290 transaction->open ? "open" : "closed",
2291 transaction->num_blocks, transaction->main_num_blocks,
2292 transaction->sub_num_blocks);
2345 cache_transaction* transaction = NULL;
2348 transaction = (cache_transaction*)(addr_t)parse_expression(argv[i]);
2352 transaction = lookup_transaction(cache, id);
2353 if (transaction == NULL) {
2354 kprintf("No transaction with ID %" B_PRId32 " found.\n", id);
2359 kprintf("TRANSACTION %p\n", transaction);
2361 kprintf(" id: %" B_PRId32 "\n", transaction->id);
2362 kprintf(" num block: %" B_PRId32 "\n", transaction->num_blocks);
2363 kprintf(" main num block: %" B_PRId32 "\n", transaction->main_num_blocks);
2364 kprintf(" sub num block: %" B_PRId32 "\n", transaction->sub_num_blocks);
2365 kprintf(" has sub: %d\n", transaction->has_sub_transaction);
2366 kprintf(" state: %s\n", transaction->open ? "open" : "closed");
2368 (system_time() - transaction->last_used) / 1000000);
2372 ListenerList::Iterator iterator = transaction->listeners.GetIterator();
2387 cached_block* block = transaction->first_block;
2395 block_list::Iterator blockIterator = transaction->blocks.GetIterator();
2583 // because a future transaction might then get held up waiting for
2627 cache_transaction* transaction = iterator.Next();
2628 if (transaction->open) {
2629 if (system_time() > transaction->last_used
2632 notify_transaction_listeners(cache, transaction,
2640 if (!writer.Add(transaction, hasLeftOvers)) {
2767 add_debugger_command_etc("transaction", &dump_transaction,
2768 "dumps a specific transaction", "[-b] ((<cache> <id>) | <transaction>)\n"
2769 "Either use a block cache pointer and an ID or a pointer to the transaction.\n"
2770 " -b lists all blocks that are part of this transaction\n", 0);
2798 // #pragma mark - public transaction API
2808 panic("last transaction (%" B_PRId32 ") still open!\n",
2812 cache_transaction* transaction = new(std::nothrow) cache_transaction;
2813 if (transaction == NULL)
2816 transaction->id = atomic_add(&cache->next_transaction_id, 1);
2817 cache->last_transaction = transaction;
2819 TRACE(("cache_start_transaction(): id %" B_PRId32 " started\n", transaction->id));
2820 T(Action("start", cache, transaction));
2822 cache->transaction_hash->Insert(transaction);
2824 return transaction->id;
2845 cache_transaction* transaction = iterator.Next();
2847 if (transaction->busy_writing_count != 0) {
2851 if (transaction->id <= id && !transaction->open) {
2853 T(Action("sync", cache, transaction));
2856 writer.Add(transaction, hasLeftOvers);
2859 // This transaction contains blocks that a previous
2860 // transaction is trying to write back in this write run
2887 cache_transaction* transaction = lookup_transaction(cache, id);
2888 if (transaction == NULL) {
2889 panic("cache_end_transaction(): invalid transaction ID\n");
2893 // Write back all pending transaction blocks
2894 status_t status = write_blocks_in_previous_transaction(cache, transaction);
2898 notify_transaction_listeners(cache, transaction, TRANSACTION_ENDED);
2901 && add_transaction_listener(cache, transaction, TRANSACTION_WRITTEN,
2906 T(Action("end", cache, transaction));
2911 for (cached_block* block = transaction->first_block; block != NULL;
2917 // This block has been discarded in the transaction
2919 transaction->num_blocks--;
2928 ASSERT(transaction->has_sub_transaction);
2932 // move the block to the previous transaction list
2933 transaction->blocks.Add(block);
2935 block->previous_transaction = transaction;
2937 block->transaction = NULL;
2940 transaction->open = false;
2953 cache_transaction* transaction = lookup_transaction(cache, id);
2954 if (transaction == NULL) {
2955 panic("cache_abort_transaction(): invalid transaction ID\n");
2959 T(Abort(cache, transaction));
2960 notify_transaction_listeners(cache, transaction, TRANSACTION_ABORTED);
2964 cached_block* block = transaction->first_block;
2971 "block %" B_PRIdOFF "\n", transaction->id, block->block_number));
2977 if (transaction->has_sub_transaction && block->parent_data != NULL)
2981 block->transaction = NULL;
2987 cache->transaction_hash->Remove(transaction);
2988 delete_transaction(cache, transaction);
2993 /*! Acknowledges the current parent transaction, and starts a new transaction
2994 from its sub transaction.
2995 The new transaction also gets a new transaction ID.
3006 cache_transaction* transaction = lookup_transaction(cache, id);
3007 if (transaction == NULL) {
3008 panic("cache_detach_sub_transaction(): invalid transaction ID\n");
3011 if (!transaction->has_sub_transaction)
3016 status_t status = write_blocks_in_previous_transaction(cache, transaction);
3020 // create a new transaction for the sub transaction
3026 T(Detach(cache, transaction, newTransaction));
3028 notify_transaction_listeners(cache, transaction, TRANSACTION_ENDED);
3030 if (add_transaction_listener(cache, transaction, TRANSACTION_WRITTEN, hook,
3038 for (cached_block* block = transaction->first_block; block != NULL;
3045 transaction->main_num_blocks--;
3064 // move the block to the previous transaction list
3065 transaction->blocks.Add(block);
3066 block->previous_transaction = transaction;
3070 // This block had been changed in the current sub transaction,
3071 // we need to move this block over to the new transaction.
3079 block->transaction = newTransaction;
3082 block->transaction = NULL;
3087 newTransaction->num_blocks = transaction->sub_num_blocks;
3089 transaction->open = false;
3090 transaction->has_sub_transaction = false;
3091 transaction->num_blocks = transaction->main_num_blocks;
3092 transaction->sub_num_blocks = 0;
3109 cache_transaction* transaction = lookup_transaction(cache, id);
3110 if (transaction == NULL) {
3111 panic("cache_abort_sub_transaction(): invalid transaction ID\n");
3114 if (!transaction->has_sub_transaction)
3117 T(Abort(cache, transaction));
3118 notify_transaction_listeners(cache, transaction, TRANSACTION_ABORTED);
3122 cached_block* block = transaction->first_block;
3129 // The parent transaction didn't change the block, but the sub
3130 // transaction did - we need to revert to the original data.
3131 // The block is no longer part of the transaction
3141 transaction->first_block = next;
3144 block->transaction = NULL;
3145 transaction->num_blocks--;
3162 // is still dirty and part of the transaction
3165 transaction->id, block->block_number));
3178 // all subsequent changes will go into the main transaction
3179 transaction->has_sub_transaction = false;
3180 transaction->sub_num_blocks = 0;
3194 cache_transaction* transaction = lookup_transaction(cache, id);
3195 if (transaction == NULL) {
3196 panic("cache_start_sub_transaction(): invalid transaction ID %" B_PRId32 "\n",
3201 notify_transaction_listeners(cache, transaction, TRANSACTION_ENDED);
3205 cached_block* block = transaction->first_block;
3211 // There already is an older sub transaction - we acknowledge
3213 ASSERT(transaction->has_sub_transaction);
3217 // This block has been discarded in the parent transaction.
3218 // Just throw away any changes made in this transaction, so that
3236 // all subsequent changes will go into the sub transaction
3237 transaction->has_sub_transaction = true;
3238 transaction->main_num_blocks = transaction->num_blocks;
3239 transaction->sub_num_blocks = 0;
3240 T(Action("start-sub", cache, transaction));
3246 /*! Adds a transaction listener that gets notified when the transaction
3248 The listener gets automatically removed when the transaction ends.
3257 cache_transaction* transaction = lookup_transaction(cache, id);
3258 if (transaction == NULL)
3261 return add_transaction_listener(cache, transaction, events, hook, data);
3272 cache_transaction* transaction = lookup_transaction(cache, id);
3273 if (transaction == NULL)
3276 ListenerList::Iterator iterator = transaction->listeners.GetIterator();
3304 cache_transaction* transaction = lookup_transaction(cache, id);
3305 if (transaction == NULL || !transaction->open)
3309 block = transaction->first_block;
3313 if (transaction->has_sub_transaction) {
3346 cache_transaction* transaction = lookup_transaction(cache, id);
3347 if (transaction == NULL)
3350 return transaction->num_blocks;
3354 /*! Returns the number of blocks that are part of the main transaction. If this
3355 transaction does not have a sub transaction yet, this is the same value as
3364 cache_transaction* transaction = lookup_transaction(cache, id);
3365 if (transaction == NULL)
3368 if (transaction->has_sub_transaction)
3369 return transaction->main_num_blocks;
3371 return transaction->num_blocks;
3381 cache_transaction* transaction = lookup_transaction(cache, id);
3382 if (transaction == NULL)
3385 return transaction->sub_num_blocks;
3389 /*! Check if block is in transaction
3399 return (block != NULL && block->transaction != NULL
3400 && block->transaction->id == id);
3436 cache_transaction* transaction = cache->transaction_hash->Clear(true);
3437 while (transaction != NULL) {
3438 cache_transaction* next = transaction->next;
3439 delete transaction;
3440 transaction = next;
3473 // transaction or no transaction only
3503 // transaction or no transaction only
3535 /*! Discards a block from the current transaction or from the cache.
3573 if (block->transaction != NULL && block->parent_data != NULL
3576 "transaction!", blockNumber);
3579 // mark it as discarded (in the current transaction only, if any)
3587 block_cache_make_writable(void* _cache, off_t blockNumber, int32 transaction)
3600 blockNumber, 1, transaction, false, &block);
3612 off_t length, int32 transaction, void** _block)
3617 TRACE(("block_cache_get_writable_etc(block = %" B_PRIdOFF ", transaction = %" B_PRId32 ")\n",
3618 blockNumber, transaction));
3623 transaction, false, _block);
3628 block_cache_get_writable(void* _cache, off_t blockNumber, int32 transaction)
3632 blockNumber, 1, transaction, &block) == B_OK)
3640 block_cache_get_empty(void* _cache, off_t blockNumber, int32 transaction)
3645 TRACE(("block_cache_get_empty(block = %" B_PRIdOFF ", transaction = %" B_PRId32 ")\n",
3646 blockNumber, transaction));
3652 blockNumber, 1, transaction, true, &block) == B_OK)
3707 int32 transaction)