summaryrefslogtreecommitdiff
path: root/sql/sql_cache.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2003-12-19 18:03:27 +0100
committerunknown <pem@mysql.com>2003-12-19 18:03:27 +0100
commit4cd90227696cdc8dced6efec7aad9836bf93dd7c (patch)
tree00894c28662192eed25fdacc555298265a2880ac /sql/sql_cache.cc
parent58a52a2a84eafe535317a533af56a81d81a8fd56 (diff)
parentbfe77e3398944bed4c919ba0c7477a4318d9f2cc (diff)
downloadmariadb-git-4cd90227696cdc8dced6efec7aad9836bf93dd7c.tar.gz
Merge 4.1 to 5.0.
BitKeeper/etc/logging_ok: auto-union client/mysql.cc: Auto merged configure.in: Auto merged client/mysqltest.c: Auto merged include/my_global.h: Auto merged include/my_pthread.h: Auto merged include/mysql_com.h: Auto merged libmysql/libmysql.c: Auto merged libmysqld/lib_sql.cc: Auto merged myisam/mi_check.c: Auto merged mysql-test/r/insert.result: Auto merged mysql-test/r/join_outer.result: Auto merged mysql-test/r/multi_update.result: Auto merged mysql-test/r/query_cache.result: Auto merged mysql-test/r/symlink.result: Auto merged mysql-test/t/func_time.test: Auto merged mysql-test/t/insert.test: Auto merged mysql-test/t/multi_update.test: Auto merged mysql-test/t/query_cache.test: Auto merged sql/ha_innodb.cc: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_subselect.cc: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged sql/item_timefunc.cc: Auto merged sql/lex.h: Auto merged sql/log.cc: Auto merged sql/log_event.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/opt_range.cc: Auto merged sql/records.cc: Auto merged sql/repl_failsafe.cc: Auto merged sql/set_var.cc: Auto merged sql/slave.cc: Auto merged sql/sql_acl.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_db.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_load.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_rename.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.h: Auto merged sql/share/czech/errmsg.txt: Auto merged sql/share/romanian/errmsg.txt: Auto merged
Diffstat (limited to 'sql/sql_cache.cc')
-rw-r--r--sql/sql_cache.cc34
1 files changed, 28 insertions, 6 deletions
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index edc61acb117..4a517a04495 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1211,9 +1211,29 @@ void Query_cache::invalidate(char *db)
if (query_cache_size > 0)
{
DUMP(this);
- /* invalidate_table reduce list while only root of list remain */
- while (tables_blocks !=0 )
- invalidate_table(tables_blocks);
+ restart_search:
+ if (tables_blocks)
+ {
+ Query_cache_block *curr= tables_blocks;
+ Query_cache_block *next;
+ do
+ {
+ next= curr->next;
+ if (strcmp(db, (char*)(curr->table()->db())) == 0)
+ invalidate_table(curr);
+ /*
+ invalidate_table can freed block on which point 'next' (if
+ table of this block used only in queries which was deleted
+ by invalidate_table). As far as we do not allocate new blocks
+ and mark all headers of freed blocks as 'FREE' (even if they are
+ merged with other blocks) we can just test type of block
+ to be sure that block is not deleted
+ */
+ if (next->type == Query_cache_block::FREE)
+ goto restart_search;
+ curr= next;
+ } while (curr != tables_blocks);
+ }
}
STRUCT_UNLOCK(&structure_guard_mutex);
}
@@ -2223,9 +2243,11 @@ void Query_cache::free_memory_block(Query_cache_block *block)
{
DBUG_ENTER("Query_cache::free_memory_block");
block->used=0;
- DBUG_PRINT("qcache",("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx",
- (ulong) first_block, (ulong) block,block->pnext,
- (ulong) block->pprev));
+ block->type= Query_cache_block::FREE; // mark block as free in any case
+ DBUG_PRINT("qcache",
+ ("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx",
+ (ulong) first_block, (ulong) block, (ulong) block->pnext,
+ (ulong) block->pprev));
if (block->pnext != first_block && block->pnext->is_free())
block = join_free_blocks(block, block->pnext);