List:Commits« Previous MessageNext Message »
From:marko.makela Date:April 5 2011 11:33am
Subject:bzr push into mysql-5.5-innodb branch (marko.makela:3359)
View as plain text  
 3359 Marko Mäkelä	2011-04-05 [merge]
      Merge from mysql-5.5-innodb to local tree.

    added:
      mysql-test/suite/innodb/r/innodb_bug59410.result
      mysql-test/suite/innodb/t/innodb_bug59410.test
=== modified file 'storage/innobase/buf/buf0flu.c'
--- a/storage/innobase/buf/buf0flu.c	revid:vasil.dimov@strippedga9eq8jr3k9h6y4
+++ b/storage/innobase/buf/buf0flu.c	revid:marko.makela@stripped
@@ -1716,7 +1716,7 @@ buf_flush_batch(
 	ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad((flush_type != BUF_FLUSH_LIST)
-	      || sync_thread_levels_empty_gen(TRUE));
+	      || sync_thread_levels_empty_except_dict());
 #endif /* UNIV_SYNC_DEBUG */
 
 	buf_pool_mutex_enter(buf_pool);

=== modified file 'storage/innobase/fil/fil0fil.c'
--- a/storage/innobase/fil/fil0fil.c	revid:vasil.dimov@stripped-20110405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/fil/fil0fil.c	revid:marko.makela@stripped-2x7cmsl3dzr530ue
@@ -4527,8 +4527,8 @@ fil_aio_wait(
 		ret = os_aio_linux_handle(segment, &fil_node,
 					  &message, &type);
 #else
-		ret = 0; /* Eliminate compiler warning */
 		ut_error;
+		ret = 0; /* Eliminate compiler warning */
 #endif
 	} else {
 		srv_set_io_thread_op_info(segment, "simulated aio handle");
@@ -4538,6 +4538,10 @@ fil_aio_wait(
 	}
 
 	ut_a(ret);
+	if (UNIV_UNLIKELY(fil_node == NULL)) {
+		ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
+		return;
+	}
 
 	srv_set_io_thread_op_info(segment, "complete io for fil node");
 

=== modified file 'storage/innobase/include/log0log.ic'
--- a/storage/innobase/include/log0log.ic	revid:vasil.dimov@oracle.com-20110405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/include/log0log.ic	revid:marko.makela@stripped0405111854-2x7cmsl3dzr530ue
@@ -435,7 +435,7 @@ log_free_check(void)
 {
 
 #ifdef UNIV_SYNC_DEBUG
-	ut_ad(sync_thread_levels_empty_gen(TRUE));
+	ut_ad(sync_thread_levels_empty_except_dict());
 #endif /* UNIV_SYNC_DEBUG */
 
 	if (log_sys->check_flush_or_checkpoint) {

=== modified file 'storage/innobase/include/os0sync.h'
--- a/storage/innobase/include/os0sync.h	revid:vasil.dimov@stripped405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/include/os0sync.h	revid:marko.makela@strippedx7cmsl3dzr530ue
@@ -150,10 +150,7 @@ os_event_free(
 	os_event_t	event);	/*!< in: event to free */
 
 /**********************************************************//**
-Waits for an event object until it is in the signaled state. If
-srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
-waiting thread when the event becomes signaled (or immediately if the
-event is already in the signaled state).
+Waits for an event object until it is in the signaled state.
 
 Typically, if the event has been signalled after the os_event_reset()
 we'll return immediately because event->is_set == TRUE.

=== modified file 'storage/innobase/include/os0thread.h'
--- a/storage/innobase/include/os0thread.h	revid:vasil.dimov@stripped05083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/include/os0thread.h	revid:marko.makela@stripped2x7cmsl3dzr530ue
@@ -107,8 +107,9 @@ UNIV_INTERN
 void
 os_thread_exit(
 /*===========*/
-	void*	exit_value);	/*!< in: exit value; in Windows this void*
+	void*	exit_value)	/*!< in: exit value; in Windows this void*
 				is cast as a DWORD */
+	__attribute__((cold, noreturn));
 /*****************************************************************//**
 Returns the thread identifier of current thread.
 @return	current thread identifier */
@@ -117,13 +118,6 @@ os_thread_id_t
 os_thread_get_curr_id(void);
 /*========================*/
 /*****************************************************************//**
-Returns handle to the current thread.
-@return	current thread handle */
-UNIV_INTERN
-os_thread_t
-os_thread_get_curr(void);
-/*====================*/
-/*****************************************************************//**
 Advises the os to give up remainder of the thread's time slice. */
 UNIV_INTERN
 void
@@ -136,29 +130,6 @@ void
 os_thread_sleep(
 /*============*/
 	ulint	tm);	/*!< in: time in microseconds */
-/******************************************************************//**
-Gets a thread priority.
-@return	priority */
-UNIV_INTERN
-ulint
-os_thread_get_priority(
-/*===================*/
-	os_thread_t	handle);/*!< in: OS handle to the thread */
-/******************************************************************//**
-Sets a thread priority. */
-UNIV_INTERN
-void
-os_thread_set_priority(
-/*===================*/
-	os_thread_t	handle,	/*!< in: OS handle to the thread */
-	ulint		pri);	/*!< in: priority: one of OS_PRIORITY_... */
-/******************************************************************//**
-Gets the last operating system error code for the calling thread.
-@return	last error on Windows, 0 otherwise */
-UNIV_INTERN
-ulint
-os_thread_get_last_error(void);
-/*==========================*/
 
 #ifndef UNIV_NONINL
 #include "os0thread.ic"

=== modified file 'storage/innobase/include/sync0sync.h'
--- a/storage/innobase/include/sync0sync.h	revid:vasil.dimov@stripped
+++ b/storage/innobase/include/sync0sync.h	revid:marko.makela@oracle.com-20110405111854-2x7cmsl3dzr530ue
@@ -413,13 +413,6 @@ sync_thread_reset_level(
 /*====================*/
 	void*	latch);	/*!< in: pointer to a mutex or an rw-lock */
 /******************************************************************//**
-Checks that the level array for the current thread is empty.
-@return	TRUE if empty */
-UNIV_INTERN
-ibool
-sync_thread_levels_empty(void);
-/*==========================*/
-/******************************************************************//**
 Checks if the level array for the current thread contains a
 mutex or rw-latch at the specified level.
 @return	a matching latch, or NULL if not found */
@@ -430,17 +423,33 @@ sync_thread_levels_contains(
 	ulint	level);			/*!< in: latching order level
 					(SYNC_DICT, ...)*/
 /******************************************************************//**
-Checks if the level array for the current thread is empty.
+Checks that the level array for the current thread is empty.
 @return	a latch, or NULL if empty except the exceptions specified below */
 UNIV_INTERN
 void*
 sync_thread_levels_nonempty_gen(
 /*============================*/
-	ibool	dict_mutex_allowed);	/*!< in: TRUE if dictionary mutex is
-					allowed to be owned by the thread,
-					also purge_is_running mutex is
-					allowed */
-#define sync_thread_levels_empty_gen(d) (!sync_thread_levels_nonempty_gen(d))
+	ibool	dict_mutex_allowed)	/*!< in: TRUE if dictionary mutex is
+					allowed to be owned by the thread */
+	__attribute__((warn_unused_result));
+/******************************************************************//**
+Checks if the level array for the current thread is empty,
+except for data dictionary latches. */
+#define sync_thread_levels_empty_except_dict()		\
+	(!sync_thread_levels_nonempty_gen(TRUE))
+/******************************************************************//**
+Checks if the level array for the current thread is empty,
+except for the btr_search_latch.
+@return	a latch, or NULL if empty except the exceptions specified below */
+UNIV_INTERN
+void*
+sync_thread_levels_nonempty_trx(
+/*============================*/
+	ibool	has_search_latch)
+				/*!< in: TRUE if and only if the thread
+				is supposed to hold btr_search_latch */
+	__attribute__((warn_unused_result));
+
 /******************************************************************//**
 Gets the debug information for a reserved mutex. */
 UNIV_INTERN

=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h	revid:vasil.dimov@stripped4
+++ b/storage/innobase/include/trx0trx.h	revid:marko.makela@stripped
@@ -569,11 +569,6 @@ struct trx_struct{
 	ib_int64_t	mysql_log_offset;/* if MySQL binlog is used, this field
 					contains the end offset of the binlog
 					entry */
-	os_thread_id_t	mysql_thread_id;/* id of the MySQL thread associated
-					with this transaction object */
-	ulint		mysql_process_no;/* since in Linux, 'top' reports
-					process id's and not thread id's, we
-					store the process number too */
 	/*------------------------------*/
 	ulint		n_mysql_tables_in_use; /* number of Innobase tables
 					used in the processing of the current

=== modified file 'storage/innobase/include/ut0dbg.h'
--- a/storage/innobase/include/ut0dbg.h	revid:vasil.dimov@stripped038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/include/ut0dbg.h	revid:marko.makela@strippeddzr530ue
@@ -50,9 +50,10 @@ UNIV_INTERN
 void
 ut_dbg_assertion_failed(
 /*====================*/
-	const char* expr,	/*!< in: the failed assertion */
-	const char* file,	/*!< in: source file containing the assertion */
-	ulint line);		/*!< in: line number of the assertion */
+	const char*	expr,	/*!< in: the failed assertion */
+	const char*	file,	/*!< in: source file containing the assertion */
+	ulint		line)	/*!< in: line number of the assertion */
+	__attribute__((nonnull(2), cold));
 
 #if defined(__WIN__) || defined(__INTEL_COMPILER)
 # undef UT_DBG_USE_ABORT

=== modified file 'storage/innobase/include/ut0ut.h'
--- a/storage/innobase/include/ut0ut.h	revid:vasil.dimov@oracle.com-20110405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/include/ut0ut.h	revid:marko.makela@stripped0405111854-2x7cmsl3dzr530ue
@@ -275,7 +275,8 @@ UNIV_INTERN
 void
 ut_print_timestamp(
 /*===============*/
-	FILE*  file); /*!< in: file where to print */
+	FILE*	file)	/*!< in: file where to print */
+	__attribute__((nonnull, cold));
 /**********************************************************//**
 Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
 UNIV_INTERN

=== modified file 'storage/innobase/log/log0log.c'
--- a/storage/innobase/log/log0log.c	revid:vasil.dimov@stripped083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/log/log0log.c	revid:marko.makela@strippeddzr530ue
@@ -3078,6 +3078,7 @@ logs_empty_and_mark_files_at_shutdown(vo
 {
 	ib_uint64_t	lsn;
 	ulint		arch_log_no;
+	ibool		server_busy;
 
 	if (srv_print_verbose_log) {
 		ut_print_timestamp(stderr);
@@ -3092,14 +3093,12 @@ loop:
 
 	mutex_enter(&kernel_mutex);
 
-	/* We need the monitor threads to stop before we proceed with a
-	normal shutdown. In case of very fast shutdown, however, we can
-	proceed without waiting for monitor threads. */
-
-	if (srv_fast_shutdown < 2
-	   && (srv_error_monitor_active
-	      || srv_lock_timeout_active
-	      || srv_monitor_active)) {
+	/* We need the monitor threads to stop before we proceed with
+	a shutdown. */
+
+	if (srv_error_monitor_active
+	    || srv_lock_timeout_active
+	    || srv_monitor_active) {
 
 		mutex_exit(&kernel_mutex);
 
@@ -3114,65 +3113,57 @@ loop:
 	for the 'very fast' shutdown, because the InnoDB layer may have
 	committed or prepared transactions and we don't want to lose them. */
 
-	if (trx_n_mysql_transactions > 0
-	    || UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
-
-		mutex_exit(&kernel_mutex);
-
-		goto loop;
-	}
-
-	if (srv_fast_shutdown == 2) {
-		/* In this fastest shutdown we do not flush the buffer pool:
-		it is essentially a 'crash' of the InnoDB server. Make sure
-		that the log is all flushed to disk, so that we can recover
-		all committed transactions in a crash recovery. We must not
-		write the lsn stamps to the data files, since at a startup
-		InnoDB deduces from the stamps if the previous shutdown was
-		clean. */
-
-		log_buffer_flush_to_disk();
-
-		mutex_exit(&kernel_mutex);
-
-		return; /* We SKIP ALL THE REST !! */
-	}
-
+	server_busy = trx_n_mysql_transactions > 0
+		|| UT_LIST_GET_LEN(trx_sys->trx_list) > 0;
 	mutex_exit(&kernel_mutex);
 
-	/* Check that the background threads are suspended */
-
-	if (srv_is_any_background_thread_active()) {
+	if (server_busy || srv_is_any_background_thread_active()) {
 		goto loop;
 	}
 
-	mutex_enter(&(log_sys->mutex));
-
-	if (log_sys->n_pending_checkpoint_writes
+	mutex_enter(&log_sys->mutex);
+	server_busy = log_sys->n_pending_checkpoint_writes
 #ifdef UNIV_LOG_ARCHIVE
-	    || log_sys->n_pending_archive_ios
+		|| log_sys->n_pending_archive_ios
 #endif /* UNIV_LOG_ARCHIVE */
-	    || log_sys->n_pending_writes) {
-
-		mutex_exit(&(log_sys->mutex));
-
-		goto loop;
-	}
-
-	mutex_exit(&(log_sys->mutex));
-
-	if (!buf_pool_check_no_pending_io()) {
+		|| log_sys->n_pending_writes;
+	mutex_exit(&log_sys->mutex);
 
+	if (server_busy || !buf_pool_check_no_pending_io()) {
 		goto loop;
 	}
 
 #ifdef UNIV_LOG_ARCHIVE
 	log_archive_all();
 #endif /* UNIV_LOG_ARCHIVE */
+	if (srv_fast_shutdown == 2) {
+		/* In this fastest shutdown we do not flush the buffer
+		pool: it is essentially a 'crash' of the InnoDB
+		server. Make sure that the log is all flushed to disk,
+		so that we can recover all committed transactions in a
+		crash recovery. We must not write the lsn stamps to
+		the data files, since at a startup InnoDB deduces from
+		the stamps if the previous shutdown was clean. */
+
+		log_buffer_flush_to_disk();
+
+		/* Check that the background threads stay suspended */
+		if (srv_is_any_background_thread_active()) {
+			fprintf(stderr,
+				"InnoDB: Warning: some background thread"
+				" woke up during shutdown\n");
+			goto loop;
+		}
+
+		srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
+		fil_close_all_files();
+		ut_a(!srv_is_any_background_thread_active());
+		return;
+	}
 
 	log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
 
-	mutex_enter(&(log_sys->mutex));
+	mutex_enter(&log_sys->mutex);
 
 	lsn = log_sys->lsn;
 
@@ -3183,7 +3174,7 @@ loop:
 #endif /* UNIV_LOG_ARCHIVE */
 	    ) {
 
-		mutex_exit(&(log_sys->mutex));
+		mutex_exit(&log_sys->mutex);
 
 		goto loop;
 	}
@@ -3201,7 +3192,7 @@ loop:
 	log_archive_close_groups(TRUE);
 #endif /* UNIV_LOG_ARCHIVE */
 
-	mutex_exit(&(log_sys->mutex));
+	mutex_exit(&log_sys->mutex);
 
 	/* Check that the background threads stay suspended */
 	if (srv_is_any_background_thread_active()) {

=== modified file 'storage/innobase/os/os0file.c'
--- a/storage/innobase/os/os0file.c	revid:vasil.dimov@stripped38-hga9eq8jr3k9h6y4
+++ b/storage/innobase/os/os0file.c	revid:marko.makela@stripped0ue
@@ -4064,13 +4064,13 @@ os_aio_func(
 	}
 
 try_again:
-	if (mode == OS_AIO_NORMAL) {
-		if (type == OS_FILE_READ) {
-			array = os_aio_read_array;
-		} else {
-			array = os_aio_write_array;
-		}
-	} else if (mode == OS_AIO_IBUF) {
+	switch (mode) {
+	case OS_AIO_NORMAL:
+		array = (type == OS_FILE_READ)
+			? os_aio_read_array
+			: os_aio_write_array;
+		break;
+	case OS_AIO_IBUF:
 		ut_ad(type == OS_FILE_READ);
 		/* Reduce probability of deadlock bugs in connection with ibuf:
 		do not let the ibuf i/o handler sleep */
@@ -4078,19 +4078,21 @@ try_again:
 		wake_later = FALSE;
 
 		array = os_aio_ibuf_array;
-	} else if (mode == OS_AIO_LOG) {
-
+		break;
+	case OS_AIO_LOG:
 		array = os_aio_log_array;
-	} else if (mode == OS_AIO_SYNC) {
+		break;
+	case OS_AIO_SYNC:
 		array = os_aio_sync_array;
 
 #if defined(LINUX_NATIVE_AIO)
 		/* In Linux native AIO we don't use sync IO array. */
 		ut_a(!srv_use_native_aio);
 #endif /* LINUX_NATIVE_AIO */
-	} else {
-		array = NULL; /* Eliminate compiler warning */
+		break;
+	default:
 		ut_error;
+		array = NULL; /* Eliminate compiler warning */
 	}
 
 	slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
@@ -4253,11 +4255,17 @@ os_aio_windows_handle(
 					   INFINITE);
 	}
 
-	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-		os_thread_exit(NULL);
+	os_mutex_enter(array->mutex);
+
+	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS
+	    && array->n_reserved == 0) {
+		*message1 = NULL;
+		*message2 = NULL;
+		os_mutex_exit(array->mutex);
+		return(TRUE);
 	}
 
-	os_mutex_enter(array->mutex);
+	ut_a(i >= WAIT_OBJECT_0 && i <= WAIT_OBJECT_0 + n);
 
 	slot = os_aio_array_get_nth_slot(array, i + segment * n);
 
@@ -4403,14 +4411,6 @@ os_aio_linux_collect(
 
 retry:
 
-	/* Go down if we are in shutdown mode.
-	In case of srv_fast_shutdown == 2, there may be pending
-	IO requests but that should be OK as we essentially treat
-	that as a crash of InnoDB. */
-	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-		os_thread_exit(NULL);
-	}
-
 	/* Initialize the events. The timeout value is arbitrary.
 	We probably need to experiment with it a little. */
 	memset(events, 0, sizeof(*events) * seg_size);
@@ -4419,76 +4419,72 @@ retry:
 
 	ret = io_getevents(io_ctx, 1, seg_size, events, &timeout);
 
-	/* This error handling is for any error in collecting the
-	IO requests. The errors, if any, for any particular IO
-	request are simply passed on to the calling routine. */
+	if (ret > 0) {
+		for (i = 0; i < ret; i++) {
+			os_aio_slot_t*	slot;
+			struct iocb*	control;
+
+			control = (struct iocb *)events[i].obj;
+			ut_a(control != NULL);
+
+			slot = (os_aio_slot_t *) control->data;
+
+			/* Some sanity checks. */
+			ut_a(slot != NULL);
+			ut_a(slot->reserved);
 
-	/* Not enough resources! Try again. */
-	if (ret == -EAGAIN) {
-		goto retry;
-	}
+#if defined(UNIV_AIO_DEBUG)
+			fprintf(stderr,
+				"io_getevents[%c]: slot[%p] ctx[%p]"
+				" seg[%lu]\n",
+				(slot->type == OS_FILE_WRITE) ? 'w' : 'r',
+				slot, io_ctx, segment);
+#endif
 
-	/* Interrupted! I have tested the behaviour in case of an
-	interrupt. If we have some completed IOs available then
-	the return code will be the number of IOs. We get EINTR only
-	if there are no completed IOs and we have been interrupted. */
-	if (ret == -EINTR) {
-		goto retry;
-	}
+			/* We are not scribbling previous segment. */
+			ut_a(slot->pos >= start_pos);
 
-	/* No pending request! Go back and check again. */
-	if (ret == 0) {
-		goto retry;
-	}
+			/* We have not overstepped to next segment. */
+			ut_a(slot->pos < end_pos);
 
-	/* All other errors! should cause a trap for now. */
-	if (UNIV_UNLIKELY(ret < 0)) {
-		ut_print_timestamp(stderr);
-		fprintf(stderr,
-			"  InnoDB: unexpected ret_code[%d] from"
-			" io_getevents()!\n", ret);
-		ut_error;
+			/* Mark this request as completed. The error handling
+			will be done in the calling function. */
+			os_mutex_enter(array->mutex);
+			slot->n_bytes = events[i].res;
+			slot->ret = events[i].res2;
+			slot->io_already_done = TRUE;
+			os_mutex_exit(array->mutex);
+		}
+		return;
 	}
 
-	ut_a(ret > 0);
-
-	for (i = 0; i < ret; i++) {
-		os_aio_slot_t*	slot;
-		struct iocb*	control;
-
-		control = (struct iocb *)events[i].obj;
-		ut_a(control != NULL);
-
-		slot = (os_aio_slot_t *) control->data;
-
-		/* Some sanity checks. */
-		ut_a(slot != NULL);
-		ut_a(slot->reserved);
-
-#if defined(UNIV_AIO_DEBUG)
-		fprintf(stderr,
-			"io_getevents[%c]: slot[%p] ctx[%p]"
-			" seg[%lu]\n",
-			(slot->type == OS_FILE_WRITE) ? 'w' : 'r',
-			slot, io_ctx, segment);
-#endif
-
-		/* We are not scribbling previous segment. */
-		ut_a(slot->pos >= start_pos);
+	if (UNIV_UNLIKELY(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS)) {
+		return;
+	}
 
-		/* We have not overstepped to next segment. */
-		ut_a(slot->pos < end_pos);
+	/* This error handling is for any error in collecting the
+	IO requests. The errors, if any, for any particular IO
+	request are simply passed on to the calling routine. */
 
-		/* Mark this request as completed. The error handling
-		will be done in the calling function. */
-		os_mutex_enter(array->mutex);
-		slot->n_bytes = events[i].res;
-		slot->ret = events[i].res2;
-		slot->io_already_done = TRUE;
-		os_mutex_exit(array->mutex);
+	switch (ret) {
+	case -EAGAIN:
+		/* Not enough resources! Try again. */
+	case -EINTR:
+		/* Interrupted! I have tested the behaviour in case of an
+		interrupt. If we have some completed IOs available then
+		the return code will be the number of IOs. We get EINTR only
+		if there are no completed IOs and we have been interrupted. */
+	case 0:
+		/* No pending request! Go back and check again. */
+		goto retry;
 	}
 
-	return;
+	/* All other errors should cause a trap for now. */
+	ut_print_timestamp(stderr);
+	fprintf(stderr,
+		"  InnoDB: unexpected ret_code[%d] from io_getevents()!\n",
+		ret);
+	ut_error;
 }
 
 /**********************************************************************//**
@@ -4532,20 +4528,35 @@ os_aio_linux_handle(
 
 	/* Loop until we have found a completed request. */
 	for (;;) {
+		ibool	any_reserved = FALSE;
 		os_mutex_enter(array->mutex);
 		for (i = 0; i < n; ++i) {
 			slot = os_aio_array_get_nth_slot(
-					array, i + segment * n);
-			if (slot->reserved && slot->io_already_done) {
+				array, i + segment * n);
+			if (!slot->reserved) {
+				continue;
+			} else if (slot->io_already_done) {
 				/* Something for us to work on. */
 				goto found;
+			} else {
+				any_reserved = TRUE;
 			}
 		}
 
 		os_mutex_exit(array->mutex);
 
-		/* We don't have any completed request.
-		Wait for some request. Note that we return
+		/* There is no completed request.
+		If there is no pending request at all,
+		and the system is being shut down, exit. */
+		if (UNIV_UNLIKELY
+		    (!any_reserved
+		     && srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS)) {
+			*message1 = NULL;
+			*message2 = NULL;
+			return(TRUE);
+		}
+
+		/* Wait for some request. Note that we return
 		from wait iff we have found a request. */
 
 		srv_set_io_thread_op_info(global_seg,
@@ -4641,6 +4652,7 @@ os_aio_simulated_handle(
 	byte*		combined_buf;
 	byte*		combined_buf2;
 	ibool		ret;
+	ibool		any_reserved;
 	ulint		n;
 	ulint		i;
 
@@ -4671,18 +4683,21 @@ restart:
 		goto recommended_sleep;
 	}
 
-	os_mutex_enter(array->mutex);
-
 	srv_set_io_thread_op_info(global_segment,
 				  "looking for i/o requests (b)");
 
 	/* Check if there is a slot for which the i/o has already been
 	done */
+	any_reserved = FALSE;
+
+	os_mutex_enter(array->mutex);
 
 	for (i = 0; i < n; i++) {
 		slot = os_aio_array_get_nth_slot(array, i + segment * n);
 
-		if (slot->reserved && slot->io_already_done) {
+		if (!slot->reserved) {
+			continue;
+		} else if (slot->io_already_done) {
 
 			if (os_aio_print_debug) {
 				fprintf(stderr,
@@ -4694,9 +4709,23 @@ restart:
 			ret = TRUE;
 
 			goto slot_io_done;
+		} else {
+			any_reserved = TRUE;
 		}
 	}
 
+	/* There is no completed request.
+	If there is no pending request at all,
+	and the system is being shut down, exit. */
+	if (UNIV_UNLIKELY
+	    (!any_reserved
+	     && srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS)) {
+		os_mutex_exit(array->mutex);
+		*message1 = NULL;
+		*message2 = NULL;
+		return(TRUE);
+	}
+
 	n_consecutive = 0;
 
 	/* If there are at least 2 seconds old requests, then pick the oldest

=== modified file 'storage/innobase/os/os0sync.c'
--- a/storage/innobase/os/os0sync.c	revid:vasil.dimov@stripped-hga9eq8jr3k9h6y4
+++ b/storage/innobase/os/os0sync.c	revid:marko.makela@strippede
@@ -558,10 +558,7 @@ os_event_free(
 }
 
 /**********************************************************//**
-Waits for an event object until it is in the signaled state. If
-srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
-waiting thread when the event becomes signaled (or immediately if the
-event is already in the signaled state).
+Waits for an event object until it is in the signaled state.
 
 Typically, if the event has been signalled after the os_event_reset()
 we'll return immediately because event->is_set == TRUE.
@@ -586,8 +583,6 @@ os_event_wait_low(
 					returned by previous call of
 					os_event_reset(). */
 {
-	ib_int64_t	old_signal_count;
-
 #ifdef __WIN__
 	if(!srv_use_native_conditions) {
 		DWORD	err;
@@ -600,43 +595,25 @@ os_event_wait_low(
 		err = WaitForSingleObject(event->handle, INFINITE);
 
 		ut_a(err == WAIT_OBJECT_0);
-
-		if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-			os_thread_exit(NULL);
-		}
 		return;
 	}
 #endif
 
-	os_fast_mutex_lock(&(event->os_mutex));
+	os_fast_mutex_lock(&event->os_mutex);
 
-	if (reset_sig_count) {
-		old_signal_count = reset_sig_count;
-	} else {
-		old_signal_count = event->signal_count;
+	if (!reset_sig_count) {
+		reset_sig_count = event->signal_count;
 	}
 
-	for (;;) {
-		if (event->is_set == TRUE
-		    || event->signal_count != old_signal_count) {
-
-			os_fast_mutex_unlock(&(event->os_mutex));
-
-			if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-
-				os_thread_exit(NULL);
-			}
-			/* Ok, we may return */
-
-			return;
-		}
-
+	while (!event->is_set && event->signal_count == reset_sig_count) {
 		os_cond_wait(&(event->cond_var), &(event->os_mutex));
 
 		/* Solaris manual said that spurious wakeups may occur: we
 		have to check if the event really has been signaled after
 		we came here to wait */
 	}
+
+	os_fast_mutex_unlock(&event->os_mutex);
 }
 
 /**********************************************************//**
@@ -657,7 +634,6 @@ os_event_wait_time_low(
 
 {
 	ibool		timed_out = FALSE;
-	ib_int64_t	old_signal_count;
 
 #ifdef __WIN__
 	DWORD		time_in_ms;
@@ -727,15 +703,12 @@ os_event_wait_time_low(
 
 	os_fast_mutex_lock(&event->os_mutex);
 
-	if (reset_sig_count) {
-		old_signal_count = reset_sig_count;
-	} else {
-		old_signal_count = event->signal_count;
+	if (!reset_sig_count) {
+		reset_sig_count = event->signal_count;
 	}
 
 	do {
-		if (event->is_set == TRUE
-		    || event->signal_count != old_signal_count) {
+		if (event->is_set || event->signal_count != reset_sig_count) {
 
 			break;
 		}
@@ -753,11 +726,6 @@ os_event_wait_time_low(
 
 	os_fast_mutex_unlock(&event->os_mutex);
 
-	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-
-		os_thread_exit(NULL);
-	}
-
 	return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
 }
 

=== modified file 'storage/innobase/os/os0thread.c'
--- a/storage/innobase/os/os0thread.c	revid:vasil.dimov@oracle.com-20110405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/os/os0thread.c	revid:marko.makela@stripped1854-2x7cmsl3dzr530ue
@@ -220,21 +220,6 @@ os_thread_exit(
 }
 
 /*****************************************************************//**
-Returns handle to the current thread.
-@return	current thread handle */
-UNIV_INTERN
-os_thread_t
-os_thread_get_curr(void)
-/*====================*/
-{
-#ifdef __WIN__
-	return(GetCurrentThread());
-#else
-	return(pthread_self());
-#endif
-}
-
-/*****************************************************************//**
 Advises the os to give up remainder of the thread's time slice. */
 UNIV_INTERN
 void
@@ -274,81 +259,3 @@ os_thread_sleep(
 	select(0, NULL, NULL, NULL, &t);
 #endif
 }
-
-#ifndef UNIV_HOTBACKUP
-/******************************************************************//**
-Sets a thread priority. */
-UNIV_INTERN
-void
-os_thread_set_priority(
-/*===================*/
-	os_thread_t	handle,	/*!< in: OS handle to the thread */
-	ulint		pri)	/*!< in: priority */
-{
-#ifdef __WIN__
-	int	os_pri;
-
-	if (pri == OS_THREAD_PRIORITY_BACKGROUND) {
-		os_pri = THREAD_PRIORITY_BELOW_NORMAL;
-	} else if (pri == OS_THREAD_PRIORITY_NORMAL) {
-		os_pri = THREAD_PRIORITY_NORMAL;
-	} else if (pri == OS_THREAD_PRIORITY_ABOVE_NORMAL) {
-		os_pri = THREAD_PRIORITY_HIGHEST;
-	} else {
-		ut_error;
-	}
-
-	ut_a(SetThreadPriority(handle, os_pri));
-#else
-	UT_NOT_USED(handle);
-	UT_NOT_USED(pri);
-#endif
-}
-
-/******************************************************************//**
-Gets a thread priority.
-@return	priority */
-UNIV_INTERN
-ulint
-os_thread_get_priority(
-/*===================*/
-	os_thread_t	handle __attribute__((unused)))
-				/*!< in: OS handle to the thread */
-{
-#ifdef __WIN__
-	int	os_pri;
-	ulint	pri;
-
-	os_pri = GetThreadPriority(handle);
-
-	if (os_pri == THREAD_PRIORITY_BELOW_NORMAL) {
-		pri = OS_THREAD_PRIORITY_BACKGROUND;
-	} else if (os_pri == THREAD_PRIORITY_NORMAL) {
-		pri = OS_THREAD_PRIORITY_NORMAL;
-	} else if (os_pri == THREAD_PRIORITY_HIGHEST) {
-		pri = OS_THREAD_PRIORITY_ABOVE_NORMAL;
-	} else {
-		ut_error;
-	}
-
-	return(pri);
-#else
-	return(0);
-#endif
-}
-
-/******************************************************************//**
-Gets the last operating system error code for the calling thread.
-@return	last error on Windows, 0 otherwise */
-UNIV_INTERN
-ulint
-os_thread_get_last_error(void)
-/*==========================*/
-{
-#ifdef __WIN__
-	return(GetLastError());
-#else
-	return(0);
-#endif
-}
-#endif /* !UNIV_HOTBACKUP */

=== modified file 'storage/innobase/row/row0merge.c'
--- a/storage/innobase/row/row0merge.c	revid:vasil.dimov@stripped83038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/row/row0merge.c	revid:marko.makela@stripped3dzr530ue
@@ -1929,7 +1929,6 @@ row_merge_lock_table(
 	sel_node_t*	node;
 
 	ut_ad(trx);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 	ut_ad(mode == LOCK_X || mode == LOCK_S);
 
 	heap = mem_heap_create(512);
@@ -2390,7 +2389,6 @@ row_merge_rename_tables(
 	pars_info_t*	info;
 	char		old_name[MAX_FULL_NAME_LEN + 1];
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 	ut_ad(old_table != new_table);
 	ut_ad(mutex_own(&dict_sys->mutex));
 

=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c	revid:vasil.dimov@stripped
+++ b/storage/innobase/row/row0mysql.c	revid:marko.makela@oracle.com-20110405111854-2x7cmsl3dzr530ue
@@ -976,7 +976,6 @@ row_lock_table_autoinc_for_mysql(
 	ibool			was_lock_wait;
 
 	ut_ad(trx);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
 	/* If we already hold an AUTOINC lock on the table then do nothing.
         Note: We peek at the value of the current owner without acquiring
@@ -1056,7 +1055,6 @@ row_lock_table_for_mysql(
 	ibool		was_lock_wait;
 
 	ut_ad(trx);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
 	trx->op_info = "setting table lock";
 
@@ -1130,7 +1128,6 @@ row_insert_for_mysql(
 	ins_node_t*	node		= prebuilt->ins_node;
 
 	ut_ad(trx);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
 	if (prebuilt->table->ibd_file_missing) {
 		ut_print_timestamp(stderr);
@@ -1364,7 +1361,6 @@ row_update_for_mysql(
 	trx_t*		trx		= prebuilt->trx;
 
 	ut_ad(prebuilt && trx);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 	UT_NOT_USED(mysql_rec);
 
 	if (prebuilt->table->ibd_file_missing) {
@@ -1532,7 +1528,6 @@ row_unlock_for_mysql(
 	trx_t*		trx		= prebuilt->trx;
 
 	ut_ad(prebuilt && trx);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
 	if (UNIV_UNLIKELY
 	    (!srv_locks_unsafe_for_binlog
@@ -1834,7 +1829,6 @@ row_create_table_for_mysql(
 	ulint		table_name_len;
 	ulint		err;
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
 #endif /* UNIV_SYNC_DEBUG */
@@ -2008,7 +2002,6 @@ row_create_index_for_mysql(
 	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
 #endif /* UNIV_SYNC_DEBUG */
 	ut_ad(mutex_own(&(dict_sys->mutex)));
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
 	trx->op_info = "creating index";
 
@@ -2411,8 +2404,6 @@ row_discard_tablespace_for_mysql(
 	table->n_foreign_key_checks_running > 0, we do not allow the
 	discard. We also reserve the data dictionary latch. */
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
-
 	trx->op_info = "discarding tablespace";
 	trx_start_if_not_started(trx);
 
@@ -2571,8 +2562,6 @@ row_import_tablespace_for_mysql(
 	ib_uint64_t	current_lsn;
 	ulint		err		= DB_SUCCESS;
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
-
 	trx_start_if_not_started(trx);
 
 	trx->op_info = "importing tablespace";
@@ -2756,7 +2745,6 @@ row_truncate_table_for_mysql(
 	redo log records on the truncated tablespace, we will assign
 	a new tablespace identifier to the truncated tablespace. */
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 	ut_ad(table);
 
 	if (srv_created_new_raw) {
@@ -3607,7 +3595,6 @@ row_drop_database_for_mysql(
 	int	err	= DB_SUCCESS;
 	ulint	namelen	= strlen(name);
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 	ut_a(name != NULL);
 	ut_a(name[namelen - 1] == '/');
 
@@ -3777,7 +3764,6 @@ row_rename_table_for_mysql(
 	ibool		old_is_tmp, new_is_tmp;
 	pars_info_t*	info			= NULL;
 
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 	ut_a(old_name != NULL);
 	ut_a(new_name != NULL);
 

=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c	revid:vasil.dimov@stripped6y4
+++ b/storage/innobase/row/row0sel.c	revid:marko.makela@stripped
@@ -1951,7 +1951,7 @@ stop_for_a_while:
 	mtr_commit(&mtr);
 
 #ifdef UNIV_SYNC_DEBUG
-	ut_ad(sync_thread_levels_empty_gen(TRUE));
+	ut_ad(sync_thread_levels_empty_except_dict());
 #endif /* UNIV_SYNC_DEBUG */
 	err = DB_SUCCESS;
 	goto func_exit;
@@ -1971,7 +1971,7 @@ commit_mtr_for_a_while:
 	mtr_has_extra_clust_latch = FALSE;
 
 #ifdef UNIV_SYNC_DEBUG
-	ut_ad(sync_thread_levels_empty_gen(TRUE));
+	ut_ad(sync_thread_levels_empty_except_dict());
 #endif /* UNIV_SYNC_DEBUG */
 
 	goto table_loop;
@@ -1988,7 +1988,7 @@ lock_wait_or_error:
 	mtr_commit(&mtr);
 
 #ifdef UNIV_SYNC_DEBUG
-	ut_ad(sync_thread_levels_empty_gen(TRUE));
+	ut_ad(sync_thread_levels_empty_except_dict());
 #endif /* UNIV_SYNC_DEBUG */
 
 func_exit:
@@ -3370,7 +3370,6 @@ row_search_for_mysql(
 	rec_offs_init(offsets_);
 
 	ut_ad(index && pcur && search_tuple);
-	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
 	if (UNIV_UNLIKELY(prebuilt->table->ibd_file_missing)) {
 		ut_print_timestamp(stderr);
@@ -3387,11 +3386,17 @@ row_search_for_mysql(
 			"InnoDB: how you can resolve the problem.\n",
 			prebuilt->table->name);
 
+#ifdef UNIV_SYNC_DEBUG
+		ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 		return(DB_ERROR);
 	}
 
 	if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
 
+#ifdef UNIV_SYNC_DEBUG
+		ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 		return(DB_MISSING_HISTORY);
 	}
 
@@ -4680,6 +4685,10 @@ func_exit:
 			prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
 		}
 	}
+
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 	return(err);
 }
 

=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c	revid:vasil.dimov@stripped20110405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/srv/srv0srv.c	revid:marko.makela@stripped2x7cmsl3dzr530ue
@@ -687,8 +687,6 @@ Unix.*/
 
 /* Thread slot in the thread table */
 struct srv_slot_struct{
-	os_thread_id_t	id;		/*!< thread id */
-	os_thread_t	handle;		/*!< thread handle */
 	unsigned	type:1;		/*!< thread type: user, utility etc. */
 	unsigned	in_use:1;	/*!< TRUE if this slot is in use */
 	unsigned	suspended:1;	/*!< TRUE if the thread is waiting
@@ -887,8 +885,6 @@ srv_table_reserve_slot(
 	slot->suspended = FALSE;
 	slot->type = type;
 	ut_ad(srv_slot_get_type(slot) == type);
-	slot->id = os_thread_get_curr_id();
-	slot->handle = os_thread_get_curr();
 
 	return(slot);
 }
@@ -907,7 +903,6 @@ srv_suspend_thread(
 	ut_ad(mutex_own(&kernel_mutex));
 	ut_ad(slot->in_use);
 	ut_ad(!slot->suspended);
-	ut_ad(slot->id == os_thread_get_curr_id());
 
 	if (srv_print_thread_releases) {
 		fprintf(stderr,
@@ -962,10 +957,9 @@ srv_release_threads(
 
 			if (srv_print_thread_releases) {
 				fprintf(stderr,
-					"Releasing thread %lu type %lu"
+					"Releasing thread type %lu"
 					" from slot %lu\n",
-					(ulong) slot->id, (ulong) type,
-					(ulong) i);
+					(ulong) type, (ulong) i);
 			}
 
 			count++;
@@ -1149,6 +1143,10 @@ srv_conc_enter_innodb(
 	srv_conc_slot_t*	slot	  = NULL;
 	ulint			i;
 
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
+
 	if (trx->mysql_thd != NULL
 	    && thd_is_replication_slave_thread(trx->mysql_thd)) {
 
@@ -1272,6 +1270,10 @@ retry:
 	/* Go to wait for the event; when a thread leaves InnoDB it will
 	release this thread */
 
+	ut_ad(!trx->has_search_latch);
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 	trx->op_info = "waiting in InnoDB queue";
 
 	thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
@@ -1307,6 +1309,10 @@ srv_conc_force_enter_innodb(
 	trx_t*	trx)	/*!< in: transaction object associated with the
 			thread */
 {
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
+
 	if (UNIV_LIKELY(!srv_thread_concurrency)) {
 
 		return;
@@ -1378,6 +1384,10 @@ srv_conc_force_exit_innodb(
 	if (slot != NULL) {
 		os_event_set(slot->event);
 	}
+
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 }
 
 /*********************************************************************//**
@@ -1389,6 +1399,10 @@ srv_conc_exit_innodb(
 	trx_t*	trx)	/*!< in: transaction object associated with the
 			thread */
 {
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
+
 	if (trx->n_tickets_to_enter_innodb > 0) {
 		/* We will pretend the thread is still inside InnoDB though it
 		now leaves the InnoDB engine. In this way we save
@@ -1505,10 +1519,9 @@ srv_table_reserve_slot_for_mysql(void)
 				slot = srv_mysql_table + i;
 
 				fprintf(stderr,
-					"Slot %lu: thread id %lu, type %lu,"
+					"Slot %lu: thread type %lu,"
 					" in use %lu, susp %lu, time %lu\n",
 					(ulong) i,
-					(ulong) os_thread_pf(slot->id),
 					(ulong) slot->type,
 					(ulong) slot->in_use,
 					(ulong) slot->suspended,
@@ -1525,8 +1538,6 @@ srv_table_reserve_slot_for_mysql(void)
 	ut_a(slot->in_use == FALSE);
 
 	slot->in_use = TRUE;
-	slot->id = os_thread_get_curr_id();
-	slot->handle = os_thread_get_curr();
 
 	return(slot);
 }
@@ -1733,6 +1744,10 @@ srv_suspend_mysql_thread(
 
 		trx->error_state = DB_INTERRUPTED;
 	}
+
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 }
 
 /********************************************************************//**
@@ -3067,11 +3082,7 @@ suspend_thread:
 	os_event_wait(slot->event);
 
 	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-		/* This is only extra safety, the thread should exit
-		already when the event wait ends */
-
 		os_thread_exit(NULL);
-
 	}
 
 	/* When there is user activity, InnoDB will set the event and the

=== modified file 'storage/innobase/srv/srv0start.c'
--- a/storage/innobase/srv/srv0start.c	revid:vasil.dimov@strippedq8jr3k9h6y4
+++ b/storage/innobase/srv/srv0start.c	revid:marko.makela@stripped
@@ -2122,17 +2122,9 @@ innobase_shutdown_for_mysql(void)
 
 	srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
 
-	/* In a 'very fast' shutdown, we do not need to wait for these threads
-	to die; all which counts is that we flushed the log; a 'very fast'
-	shutdown is essentially a crash. */
-
-	if (srv_fast_shutdown == 2) {
-		return(DB_SUCCESS);
-	}
-
 	/* All threads end up waiting for certain events. Put those events
-	to the signaled state. Then the threads will exit themselves in
-	os_thread_event_wait(). */
+	to the signaled state. Then the threads will exit themselves after
+	os_event_wait(). */
 
 	for (i = 0; i < 1000; i++) {
 		/* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM

=== modified file 'storage/innobase/sync/sync0sync.c'
--- a/storage/innobase/sync/sync0sync.c	revid:vasil.dimov@stripped9h6y4
+++ b/storage/innobase/sync/sync0sync.c	revid:marko.makela@stripped
@@ -189,12 +189,12 @@ UNIV_INTERN sync_array_t*	sync_primary_w
 /** This variable is set to TRUE when sync_init is called */
 UNIV_INTERN ibool	sync_initialized	= FALSE;
 
+#ifdef UNIV_SYNC_DEBUG
 /** An acquired mutex or rw-lock and its level in the latching order */
 typedef struct sync_level_struct	sync_level_t;
 /** Mutexes or rw-locks held by a thread */
 typedef struct sync_thread_struct	sync_thread_t;
 
-#ifdef UNIV_SYNC_DEBUG
 /** The latch levels currently owned by threads are stored in this data
 structure; the size of this array is OS_THREAD_MAX_N */
 
@@ -221,7 +221,6 @@ UNIV_INTERN mysql_pfs_key_t	mutex_list_m
 #ifdef UNIV_SYNC_DEBUG
 /** Latching order checks start when this is set TRUE */
 UNIV_INTERN ibool	sync_order_checks_on	= FALSE;
-#endif /* UNIV_SYNC_DEBUG */
 
 /** Number of slots reserved for each OS thread in the sync level array */
 static const ulint SYNC_THREAD_N_LEVELS = 10000;
@@ -258,6 +257,7 @@ struct sync_level_struct{
 					the ordinal value of the next free
 					element */
 };
+#endif /* UNIV_SYNC_DEBUG */
 
 /******************************************************************//**
 Creates, or rather, initializes a mutex object in a specified memory
@@ -1020,9 +1020,7 @@ void*
 sync_thread_levels_nonempty_gen(
 /*============================*/
 	ibool	dict_mutex_allowed)	/*!< in: TRUE if dictionary mutex is
-					allowed to be owned by the thread,
-					also purge_is_running mutex is
-					allowed */
+					allowed to be owned by the thread */
 {
 	ulint		i;
 	sync_arr_t*	arr;
@@ -1069,14 +1067,61 @@ sync_thread_levels_nonempty_gen(
 }
 
 /******************************************************************//**
-Checks that the level array for the current thread is empty.
-@return	TRUE if empty */
+Checks if the level array for the current thread is empty,
+except for the btr_search_latch.
+@return	a latch, or NULL if empty except the exceptions specified below */
 UNIV_INTERN
-ibool
-sync_thread_levels_empty(void)
-/*==========================*/
+void*
+sync_thread_levels_nonempty_trx(
+/*============================*/
+	ibool	has_search_latch)
+				/*!< in: TRUE if and only if the thread
+				is supposed to hold btr_search_latch */
 {
-	return(sync_thread_levels_empty_gen(FALSE));
+	ulint		i;
+	sync_arr_t*	arr;
+	sync_thread_t*	thread_slot;
+
+	if (!sync_order_checks_on) {
+
+		return(NULL);
+	}
+
+	ut_a(!has_search_latch
+	     || sync_thread_levels_contains(SYNC_SEARCH_SYS));
+
+	mutex_enter(&sync_thread_mutex);
+
+	thread_slot = sync_thread_level_arrays_find_slot();
+
+	if (thread_slot == NULL) {
+
+		mutex_exit(&sync_thread_mutex);
+
+		return(NULL);
+	}
+
+	arr = thread_slot->levels;
+
+	for (i = 0; i < arr->n_elems; ++i) {
+		const sync_level_t*	slot;
+
+		slot = &arr->elems[i];
+
+		if (slot->latch != NULL
+		    && (!has_search_latch
+			|| slot->level != SYNC_SEARCH_SYS)) {
+
+			mutex_exit(&sync_thread_mutex);
+			ut_error;
+
+			return(slot->latch);
+		}
+	}
+
+	mutex_exit(&sync_thread_mutex);
+
+	return(NULL);
 }
 
 /******************************************************************//**

=== modified file 'storage/innobase/trx/trx0roll.c'
--- a/storage/innobase/trx/trx0roll.c	revid:vasil.dimov@oracle.com-20110405083038-hga9eq8jr3k9h6y4
+++ b/storage/innobase/trx/trx0roll.c	revid:marko.makela@stripped0405111854-2x7cmsl3dzr530ue
@@ -460,10 +460,6 @@ trx_rollback_active(
 		(ulong) rows_to_undo, unit);
 	mutex_exit(&kernel_mutex);
 
-	trx->mysql_thread_id = os_thread_get_curr_id();
-
-	trx->mysql_process_no = os_proc_get_number();
-
 	if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
 		row_mysql_lock_data_dictionary(trx);
 		dictionary_locked = TRUE;

=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c	revid:vasil.dimov@stripped
+++ b/storage/innobase/trx/trx0trx.c	revid:marko.makela@oracle.com-20110405111854-2x7cmsl3dzr530ue
@@ -214,10 +214,6 @@ trx_allocate_for_mysql(void)
 
 	mutex_exit(&kernel_mutex);
 
-	trx->mysql_thread_id = os_thread_get_curr_id();
-
-	trx->mysql_process_no = os_proc_get_number();
-
 	return(trx);
 }
 
@@ -1729,12 +1725,6 @@ trx_print(
 		fprintf(f, " state %lu", (ulong) trx->conc_state);
 	}
 
-#ifdef UNIV_LINUX
-	fprintf(f, ", process no %lu", trx->mysql_process_no);
-#endif
-	fprintf(f, ", OS thread id %lu",
-		(ulong) os_thread_pf(trx->mysql_thread_id));
-
 	if (*trx->op_info) {
 		putc(' ', f);
 		fputs(trx->op_info, f);

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20110405111854-2x7cmsl3dzr530ue.bundle
Thread
bzr push into mysql-5.5-innodb branch (marko.makela:3359) marko.makela5 Apr