summaryrefslogtreecommitdiff
path: root/storage/innobase/ut
diff options
context:
space:
mode:
authorunknown <aivanov@mysql.com>2006-06-01 10:34:04 +0400
committerunknown <aivanov@mysql.com>2006-06-01 10:34:04 +0400
commit2dca2a1a5d3689e30eea204bb7923620c369fed2 (patch)
tree6e3a741f3a17d4092daffffbb0e8e1e0f47ab029 /storage/innobase/ut
parent39b6d186e8933a1e6e5544194e66138f78e14b11 (diff)
downloadmariadb-git-2dca2a1a5d3689e30eea204bb7923620c369fed2.tar.gz
Applied innodb-5.1-ss594 snapshot.
Fixed BUG#19542 "InnoDB doesn't increase the Handler_read_prev couter". Fixed BUG#19609 "Case sensitivity of innodb_data_file_path gives stupid error". Fixed BUG#19727 "InnoDB crashed server and crashed tables are ot recoverable". Also: * Remove remnants of the obsolete concept of memoryfixing tables and indexes. * Remove unused dict_table_LRU_trim(). * Remove unused 'trx' parameter from dict_table_get_on_id_low(), dict_table_get(), dict_table_get_and_increment_handle_count(). * Add a normal linked list implementation. * Add a work queue implementation. * Add 'level' parameter to mutex_create() and rw_lock_create(). Remove mutex_set_level() and rw_lock_set_level(). * Rename SYNC_LEVEL_NONE to SYNC_LEVEL_VARYING. * Add support for bound ids in InnoDB's parser. * Define UNIV_BTR_DEBUG for enabling consistency checks of FIL_PAGE_NEXT and FIL_PAGE_PREV when accessing sibling pages of B-tree indexes. btr_validate_level(): Check the validity of the doubly linked list formed by FIL_PAGE_NEXT and FIL_PAGE_PREV. * Adapt InnoDB to the new tablename to filename encoding in MySQL 5.1. ut_print_name(), ut_print_name1(): Add parameter 'table_id' for distinguishing names of tables from other identifiers. New: innobase_convert_from_table_id(), innobase_convert_from_id(), innobase_convert_from_filename(), innobase_get_charset. dict_accept(), dict_scan_id(), dict_scan_col(), dict_scan_table_name(), dict_skip_word(), dict_create_foreign_constraints_low(): Add parameter 'cs' so that isspace() can be replaced with my_isspace(), whose operation depends on the connection character set. dict_scan_id(): Convert identifier to UTF-8. dict_str_starts_with_keyword(): New extern function, to replace dict_accept() in row_search_for_mysql(). mysql_get_identifier_quote_char(): Replaced with innobase_print_identifier(). ha_innobase::create(): Remove the thd->convert_strin() call. Pass the statement to InnoDB in the connection character set and let InnoDB convert the identifier to UTF-8. * Add max_row_size to dict_table_t. * btr0cur.c btr_copy_externally_stored_field(): Only set the 'offset' variable when needed. * buf0buf.c buf_page_io_complete(): Write to the error log if the page number or the space id o the disk do not match those in memory. Also write to the error log if a page was read from the doublewrite buffer. The doublewrite buffer should be only read by the lower-level function fil_io() at database startup. * dict0dict.c dict_scan_table_name(): Remove fallback to differently encoded name when the table is not found. The encoding is handled at a higher level. * ha_innodb.cc Increment statistic counter in ha_innobase::index_prev() (bug 19542). Add innobase_convert_string wrapper function and a new file ha_prototypes.h. innobase_print_identifier(): Remove TODO comment before calling get_quote_char_for_identifier(). That function apparently assumes the identifier to be encoded in UTF-8. * ibuf0ibuf.c|h ibuf_count_get(), ibuf_counts[], ibuf_count_inited(): Define these only #ifdef UNIV_IBUF_DEBUG. Previously, when compiled without UNIV_IBUF_DEBUG, invoking ibuf_count_get() would crash InnoDB. The function is only being called #ifdef UNIV_IBUF_DEBUG. * innodb.result Adjust the results for changes in the foreign key error messages. * mem0mem.c|h New: mem_heap_dup(), mem_heap_printf(), mem_heap_cat(). * os0file.c Check the page trailers also after writing to disk. This improves chances of diagnosing bug 18886. os_file_check_page_trailers(): New function for checking that the two copies of the LSN stamped on the page match. os_aio_simulated_handle(): Call os_file_check_page_trailers() before and after os_file_write(). * row0mysql.c Move trx_commit_for_mysql(trx) calls before calls to row_mysql_unlock_data_dictionary(trx) (bug 19727). * row0sel.c row_fetch_print(): Handle SQL NULL values without crashing. row_sel_store_mysql_rec(): Remove useless call to rec_get_nth_field when handling an externally stored column. Fetch externally stored fields when using InnoDB's internal SQL parser. Optimize BLOB selects by using prebuilt->blob_heap directly instead of first reading BLOB data to a temporary heap and then copying it to prebuilt->blob_heap. * srv0srv.c srv_master_thread(): Remove unreachable code. * srv0start.c srv_parse_data_file_paths_and_sizes(): Accept lower-case 'm' and 'g' as abbreviations of megabyte and gigabyte (bug 19609). srv_parse_megabytes(): New fuction. * ut0dbg.c|h Implement InnoDB assertions (ut_a and ut_error) with abort() when the code is compiled with GCC 3 or later on other platforms than Windows or Netware. Also disable the variable ut_dbg_stop_threads and the function ut_dbg_stop_thread() i this case, unless UNIV_SYC_DEBUG is defined. This should allow the compiler to generate more compact code for assertions. * ut0list.c|h Add ib_list_create_heap(). mysql-test/r/innodb.result: Applied innodb-5.1-ss594 snapshot. mysql-test/t/innodb.test: Copy the comment from the beginning of the file to the end because MySQL developers continue adding test cases to this file. sql/ha_innodb.cc: Applied innodb-5.1-ss594 snapshot. storage/innobase/CMakeLists.txt: Applied innodb-5.1-ss594 snapshot. storage/innobase/Makefile.am: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0btr.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0cur.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0pcur.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0sea.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/buf/buf0buf.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/buf/buf0flu.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/data/data0type.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0crea.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0dict.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0load.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0mem.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/fil/fil0fil.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ha/hash0hash.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ibuf/ibuf0ibuf.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/data0type.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/dict0dict.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/dict0dict.ic: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/dict0mem.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/fil0fil.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/fsp0fsp.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ibuf0ibuf.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/mem0mem.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/pars0pars.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/pars0sym.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/pars0types.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/rem0rec.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/row0purge.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/row0undo.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/srv0srv.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/sync0rw.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/sync0sync.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/univ.i: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0dbg.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0ut.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/lock/lock0lock.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/log/log0log.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/log/log0recv.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/mem/mem0dbg.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/mem/mem0mem.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/mem/mem0pool.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/os/os0file.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/os/os0thread.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/lexyy.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/pars0lex.l: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/pars0pars.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/pars0sym.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0ins.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0mysql.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0purge.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0row.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0sel.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0upd.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/srv/srv0srv.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/srv/srv0start.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/sync/sync0arr.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/sync/sync0rw.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/sync/sync0sync.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/thr/thr0loc.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0purge.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0rec.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0roll.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0rseg.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0sys.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0trx.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/Makefile.am: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0dbg.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0ut.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ha_prototypes.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0list.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0list.ic: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0wqueue.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0list.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0wqueue.c: Applied innodb-5.1-ss594 snapshot.
Diffstat (limited to 'storage/innobase/ut')
-rw-r--r--storage/innobase/ut/Makefile.am2
-rw-r--r--storage/innobase/ut/ut0dbg.c10
-rw-r--r--storage/innobase/ut/ut0list.c169
-rw-r--r--storage/innobase/ut/ut0ut.c49
-rw-r--r--storage/innobase/ut/ut0wqueue.c92
5 files changed, 295 insertions, 27 deletions
diff --git a/storage/innobase/ut/Makefile.am b/storage/innobase/ut/Makefile.am
index c833a6d5a4c..fa4eeb2e9c9 100644
--- a/storage/innobase/ut/Makefile.am
+++ b/storage/innobase/ut/Makefile.am
@@ -19,6 +19,6 @@ include ../include/Makefile.i
noinst_LIBRARIES = libut.a
-libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c
+libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c ut0list.c ut0wqueue.c
EXTRA_PROGRAMS =
diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c
index 2157a71116a..a9391cd3adc 100644
--- a/storage/innobase/ut/ut0dbg.c
+++ b/storage/innobase/ut/ut0dbg.c
@@ -14,19 +14,21 @@ Created 1/30/1994 Heikki Tuuri
ulint ut_dbg_zero = 0;
#endif
+#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
/* If this is set to TRUE all threads will stop into the next assertion
and assert */
ibool ut_dbg_stop_threads = FALSE;
+#endif
#ifdef __NETWARE__
ibool panic_shutdown = FALSE; /* This is set to TRUE when on NetWare there
happens an InnoDB assertion failure or other
fatal error condition that requires an
immediate shutdown. */
-#else /* __NETWARE__ */
+#elif !defined(UT_DBG_USE_ABORT)
/* Null pointer used to generate memory trap */
ulint* ut_dbg_null_ptr = NULL;
-#endif /* __NETWARE__ */
+#endif
/*****************************************************************
Report a failed assertion. */
@@ -56,7 +58,9 @@ ut_dbg_assertion_failed(
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
+#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
ut_dbg_stop_threads = TRUE;
+#endif
}
#ifdef __NETWARE__
@@ -74,6 +78,7 @@ ut_dbg_panic(void)
exit(1);
}
#else /* __NETWARE__ */
+# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
/*****************************************************************
Stop a thread after assertion failure. */
@@ -87,4 +92,5 @@ ut_dbg_stop_thread(
os_thread_pf(os_thread_get_curr_id()), file, line);
os_thread_sleep(1000000000);
}
+# endif
#endif /* __NETWARE__ */
diff --git a/storage/innobase/ut/ut0list.c b/storage/innobase/ut/ut0list.c
new file mode 100644
index 00000000000..a0db7ff7b55
--- /dev/null
+++ b/storage/innobase/ut/ut0list.c
@@ -0,0 +1,169 @@
+#include "ut0list.h"
+#ifdef UNIV_NONINL
+#include "ut0list.ic"
+#endif
+
+/********************************************************************
+Create a new list. */
+
+ib_list_t*
+ib_list_create(void)
+/*=================*/
+ /* out: list */
+{
+ ib_list_t* list = mem_alloc(sizeof(ib_list_t));
+
+ list->first = NULL;
+ list->last = NULL;
+ list->is_heap_list = FALSE;
+
+ return(list);
+}
+
+/********************************************************************
+Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
+lists created with this function. */
+
+ib_list_t*
+ib_list_create_heap(
+/*================*/
+ /* out: list */
+ mem_heap_t* heap) /* in: memory heap to use */
+{
+ ib_list_t* list = mem_heap_alloc(heap, sizeof(ib_list_t));
+
+ list->first = NULL;
+ list->last = NULL;
+ list->is_heap_list = TRUE;
+
+ return(list);
+}
+
+/********************************************************************
+Free a list. */
+
+void
+ib_list_free(
+/*=========*/
+ ib_list_t* list) /* in: list */
+{
+ ut_a(!list->is_heap_list);
+
+ /* We don't check that the list is empty because it's entirely valid
+ to e.g. have all the nodes allocated from a single heap that is then
+ freed after the list itself is freed. */
+
+ mem_free(list);
+}
+
+/********************************************************************
+Add the data to the start of the list. */
+
+ib_list_node_t*
+ib_list_add_first(
+/*==============*/
+ /* out: new list node*/
+ ib_list_t* list, /* in: list */
+ void* data, /* in: data */
+ mem_heap_t* heap) /* in: memory heap to use */
+{
+ return(ib_list_add_after(list, ib_list_get_first(list), data, heap));
+}
+
+/********************************************************************
+Add the data to the end of the list. */
+
+ib_list_node_t*
+ib_list_add_last(
+/*=============*/
+ /* out: new list node*/
+ ib_list_t* list, /* in: list */
+ void* data, /* in: data */
+ mem_heap_t* heap) /* in: memory heap to use */
+{
+ return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
+}
+
+/********************************************************************
+Add the data after the indicated node. */
+
+ib_list_node_t*
+ib_list_add_after(
+/*==============*/
+ /* out: new list node*/
+ ib_list_t* list, /* in: list */
+ ib_list_node_t* prev_node, /* in: node preceding new node (can
+ be NULL) */
+ void* data, /* in: data */
+ mem_heap_t* heap) /* in: memory heap to use */
+{
+ ib_list_node_t* node = mem_heap_alloc(heap, sizeof(ib_list_node_t));
+
+ node->data = data;
+
+ if (!list->first) {
+ /* Empty list. */
+
+ ut_a(!prev_node);
+
+ node->prev = NULL;
+ node->next = NULL;
+
+ list->first = node;
+ list->last = node;
+ } else if (!prev_node) {
+ /* Start of list. */
+
+ node->prev = NULL;
+ node->next = list->first;
+
+ list->first->prev = node;
+
+ list->first = node;
+ } else {
+ /* Middle or end of list. */
+
+ node->prev = prev_node;
+ node->next = prev_node->next;
+
+ prev_node->next = node;
+
+ if (node->next) {
+ node->next->prev = node;
+ } else {
+ list->last = node;
+ }
+ }
+
+ return(node);
+}
+
+/********************************************************************
+Remove the node from the list. */
+
+void
+ib_list_remove(
+/*===========*/
+ ib_list_t* list, /* in: list */
+ ib_list_node_t* node) /* in: node to remove */
+{
+ if (node->prev) {
+ node->prev->next = node->next;
+ } else {
+ /* First item in list. */
+
+ ut_ad(list->first == node);
+
+ list->first = node->next;
+ }
+
+ if (node->next) {
+ node->next->prev = node->prev;
+ } else {
+ /* Last item in list. */
+
+ ut_ad(list->last == node);
+
+ list->last = node->prev;
+ }
+}
diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c
index 48435fe6155..6d81c113e42 100644
--- a/storage/innobase/ut/ut0ut.c
+++ b/storage/innobase/ut/ut0ut.c
@@ -20,18 +20,20 @@ Created 5/11/1994 Heikki Tuuri
ibool ut_always_false = FALSE;
+#ifndef UNIV_HOTBACKUP
/*********************************************************************
-Get the quote character to be used in SQL identifiers.
+Display an SQL identifier.
This definition must match the one in sql/ha_innodb.cc! */
extern
-int
-mysql_get_identifier_quote_char(
-/*============================*/
- /* out: quote character to be
- used in SQL identifiers; EOF if none */
+void
+innobase_print_identifier(
+/*======================*/
+ FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name, /* in: name to print */
ulint namelen);/* in: length of name */
+#endif /* !UNIV_HOTBACKUP */
/************************************************************
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
@@ -398,9 +400,10 @@ ut_print_name(
/*==========*/
FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name) /* in: name to print */
{
- ut_print_namel(f, trx, name, strlen(name));
+ ut_print_namel(f, trx, table_id, name, strlen(name));
}
/**************************************************************************
@@ -411,29 +414,27 @@ ut_print_namel(
/*===========*/
FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction (NULL=no quotes) */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name, /* in: name to print */
ulint namelen)/* in: length of name */
{
- const char* s = name;
- const char* e = s + namelen;
#ifdef UNIV_HOTBACKUP
- int q = '"';
+ fwrite(name, 1, namelen, f);
#else
- int q = mysql_get_identifier_quote_char(trx, name, namelen);
-#endif
- if (q == EOF) {
- fwrite(name, 1, namelen, f);
- return;
+ char* slash = strchr(name, '/');
+
+ if (UNIV_LIKELY_NULL(slash)) {
+ /* Print the database name and table name separately. */
+ ut_ad(table_id);
+
+ innobase_print_identifier(f, trx, TRUE, name, slash - name);
+ putc('.', f);
+ innobase_print_identifier(f, trx, TRUE, slash + 1,
+ namelen - (slash - name) - 1);
+ } else {
+ innobase_print_identifier(f, trx, table_id, name, namelen);
}
- putc(q, f);
- while (s < e) {
- int c = *s++;
- if (c == q) {
- putc(c, f);
- }
- putc(c, f);
- }
- putc(q, f);
+#endif
}
/**************************************************************************
diff --git a/storage/innobase/ut/ut0wqueue.c b/storage/innobase/ut/ut0wqueue.c
new file mode 100644
index 00000000000..2a6d8c19ef0
--- /dev/null
+++ b/storage/innobase/ut/ut0wqueue.c
@@ -0,0 +1,92 @@
+#include "ut0wqueue.h"
+
+/********************************************************************
+Create a new work queue. */
+
+ib_wqueue_t*
+ib_wqueue_create(void)
+/*===================*/
+ /* out: work queue */
+{
+ ib_wqueue_t* wq = mem_alloc(sizeof(ib_wqueue_t));
+
+ mutex_create(&wq->mutex, SYNC_WORK_QUEUE);
+
+ wq->items = ib_list_create();
+ wq->event = os_event_create(NULL);
+
+ return(wq);
+}
+
+/********************************************************************
+Free a work queue. */
+
+void
+ib_wqueue_free(
+/*===========*/
+ ib_wqueue_t* wq) /* in: work queue */
+{
+ ut_a(!ib_list_get_first(wq->items));
+
+ mutex_free(&wq->mutex);
+ ib_list_free(wq->items);
+ os_event_free(wq->event);
+
+ mem_free(wq);
+}
+
+/********************************************************************
+Add a work item to the queue. */
+
+void
+ib_wqueue_add(
+/*==========*/
+ ib_wqueue_t* wq, /* in: work queue */
+ void* item, /* in: work item */
+ mem_heap_t* heap) /* in: memory heap to use for allocating the
+ list node */
+{
+ mutex_enter(&wq->mutex);
+
+ ib_list_add_last(wq->items, item, heap);
+ os_event_set(wq->event);
+
+ mutex_exit(&wq->mutex);
+}
+
+/********************************************************************
+Wait for a work item to appear in the queue. */
+
+void*
+ib_wqueue_wait(
+ /* out: work item */
+ ib_wqueue_t* wq) /* in: work queue */
+{
+ ib_list_node_t* node;
+
+ for (;;) {
+ os_event_wait(wq->event);
+
+ mutex_enter(&wq->mutex);
+
+ node = ib_list_get_first(wq->items);
+
+ if (node) {
+ ib_list_remove(wq->items, node);
+
+ if (!ib_list_get_first(wq->items)) {
+ /* We must reset the event when the list
+ gets emptied. */
+ os_event_reset(wq->event);
+ }
+
+ break;
+ }
+
+ mutex_exit(&wq->mutex);
+ }
+
+ mutex_exit(&wq->mutex);
+
+ return(node->data);
+}