Commit a13a636c authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-11802 innodb.innodb_bug14676111 fails

The function trx_purge_stop() was calling os_event_reset(purge_sys->event)
before calling rw_lock_x_lock(&purge_sys->latch). The os_event_set()
call in srv_purge_coordinator_suspend() is protected by that X-latch.

It would seem a good idea to consistently protect both os_event_set()
and os_event_reset() calls with a common mutex or rw-lock in those
cases where os_event_set() and os_event_reset() are used
like condition variables, tied to changes of shared state.

For each os_event_t, we try to document the mutex or rw-lock that is
being used. For some events, frequent calls to os_event_set() seem to
try to avoid hangs. Some events are never waited for infinitely, only
timed waits, and os_event_set() is used for early termination of these
waits.

os_aio_simulated_put_read_threads_to_sleep(): Define as a null macro
on other systems than Windows. TODO: remove this altogether and disable
innodb_use_native_aio on Windows.

os_aio_segment_wait_events[]: Initialize only if innodb_use_native_aio=0.

log_write_flush_to_disk_low(): Invoke log_mutex_enter() at the end, to
avoid race conditions when changing the system state. (No potential
race condition existed before MySQL 5.7.)
parent cc4b2b18
......@@ -54,8 +54,8 @@ enum status_severity {
/* Flags that tell the buffer pool dump/load thread which action should it
take after being waked up. */
static ibool buf_dump_should_start = FALSE;
static ibool buf_load_should_start = FALSE;
static volatile bool buf_dump_should_start;
static volatile bool buf_load_should_start;
static ibool buf_load_abort_flag = FALSE;
......@@ -79,7 +79,7 @@ void
buf_dump_start()
/*============*/
{
buf_dump_should_start = TRUE;
buf_dump_should_start = true;
os_event_set(srv_buf_dump_event);
}
......@@ -92,7 +92,7 @@ void
buf_load_start()
/*============*/
{
buf_load_should_start = TRUE;
buf_load_should_start = true;
os_event_set(srv_buf_dump_event);
}
......@@ -799,15 +799,18 @@ DECLARE_THREAD(buf_dump_thread)(void*)
os_event_wait(srv_buf_dump_event);
if (buf_dump_should_start) {
buf_dump_should_start = FALSE;
buf_dump_should_start = false;
buf_dump(TRUE /* quit on shutdown */);
}
if (buf_load_should_start) {
buf_load_should_start = FALSE;
buf_load_should_start = false;
buf_load();
}
if (buf_dump_should_start || buf_load_should_start) {
continue;
}
os_event_reset(srv_buf_dump_event);
}
......
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2016, MariaDB Corporation
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
......@@ -795,6 +795,8 @@ buf_flush_write_complete(
flush_type = buf_page_get_flush_type(bpage);
buf_pool->n_flush[flush_type]--;
ut_ad(buf_pool_mutex_own(buf_pool));
if (buf_pool->n_flush[flush_type] == 0
&& buf_pool->init_flush[flush_type] == FALSE) {
......
......@@ -43,8 +43,9 @@ Created Apr 25, 2012 Vasil Dimov
#define SHUTTING_DOWN() (srv_shutdown_state != SRV_SHUTDOWN_NONE)
/** Event to wake up the stats thread */
os_event_t dict_stats_event = NULL;
/** Event to wake up dict_stats_thread on dict_stats_recalc_pool_add()
or shutdown. Not protected by any mutex. */
os_event_t dict_stats_event;
/** Variable to initiate shutdown the dict stats thread. Note we don't
use 'srv_shutdown_state' because we want to shutdown dict stats thread
......
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -2183,7 +2183,9 @@ struct buf_pool_t{
os_event_t no_flush[BUF_FLUSH_N_TYPES];
/*!< this is in the set state
when there is no flush batch
of the given type running */
of the given type running;
os_event_set() and os_event_reset()
are protected by buf_pool_t::mutex */
ib_rbt_t* flush_rbt; /*!< a red-black tree is used
exclusively during recovery to
speed up insertions in the
......
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -132,11 +133,13 @@ struct buf_dblwr_t{
ulint b_reserved;/*!< number of slots currently reserved
for batch flush. */
os_event_t b_event;/*!< event where threads wait for a
batch flush to end. */
batch flush to end;
os_event_set() and os_event_reset()
are protected by buf_dblwr_t::mutex */
ulint s_reserved;/*!< number of slots currently
reserved for single page flushes. */
os_event_t s_event;/*!< event where threads wait for a
single page flush slot. */
single page flush slot. Protected by mutex. */
bool* in_use; /*!< flag used to indicate if a slot is
in use. Only used for single page
flushes. */
......
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -32,7 +33,8 @@ Created Apr 26, 2012 Vasil Dimov
#include "os0event.h"
#include "os0thread.h"
/** Event to wake up the stats thread */
/** Event to wake up dict_stats_thread on dict_stats_recalc_pool_add()
or shutdown. Not protected by any mutex. */
extern os_event_t dict_stats_event;
#ifdef HAVE_PSI_INTERFACE
......
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -203,7 +203,9 @@ struct fil_node_t {
char* name;
/** file handle (valid if is_open) */
os_file_t handle;
/** event that groups and serializes calls to fsync */
/** event that groups and serializes calls to fsync;
os_event_set() and os_event_reset() are protected by
fil_system_t::mutex */
os_event_t sync_event;
/** whether the file actually is a raw device or disk partition */
bool is_raw_disk;
......
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -127,7 +128,9 @@ struct fts_sync_t {
bool in_progress; /*!< flag whether sync is in progress.*/
bool unlock_cache; /*!< flag whether unlock cache when
write fts node */
os_event_t event; /*!< sync finish event */
os_event_t event; /*!< sync finish event;
only os_event_set() and os_event_wait()
are used */
};
/** The cache for the FTS system. It is a memory-based inverted index
......
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -1039,7 +1040,12 @@ struct lock_sys_t{
srv_slot_t* waiting_threads; /*!< Array of user threads
suspended while waiting for
locks within InnoDB, protected
by the lock_sys->wait_mutex */
by the lock_sys->wait_mutex;
os_event_set() and
os_event_reset() on
waiting_threads[]->event
are protected by
trx_t::mutex */
srv_slot_t* last_slot; /*!< highest slot ever used
in the waiting_threads array,
protected by
......@@ -1052,10 +1058,11 @@ struct lock_sys_t{
ulint n_lock_max_wait_time; /*!< Max wait time */
os_event_t timeout_event; /*!< Set to the event that is
created in the lock wait monitor
thread. A value of 0 means the
thread is not active */
os_event_t timeout_event; /*!< An event waited for by
lock_wait_timeout_thread.
Not protected by a mutex,
but the waits are timed.
Signaled on shutdown only. */
bool timeout_thread_active; /*!< True if the timeout thread
is running */
......
......@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
Copyright (c) 2017, MariaDB Corporation
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
......@@ -669,16 +669,12 @@ struct log_t{
/*!< how far we have written the log
AND flushed to disk */
ulint n_pending_flushes;/*!< number of currently
pending flushes; incrementing is
protected by the log mutex;
may be decremented between
resetting and setting flush_event */
pending flushes; protected by
log_sys_t::mutex */
os_event_t flush_event; /*!< this event is in the reset state
when a flush is running; a thread
should wait for this without
owning the log mutex, but NOTE that
to set this event, the
thread MUST own the log mutex! */
when a flush is running;
os_event_set() and os_event_reset()
are protected by log_sys_t::mutex */
ulint n_log_ios; /*!< number of log i/os initiated thus
far */
ulint n_log_ios_old; /*!< number of log i/o's at the
......
......@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
......@@ -1440,12 +1440,16 @@ os_aio_wait_until_no_pending_writes();
void
os_aio_simulated_wake_handler_threads();
#ifdef _WIN32
/** This function can be called if one wants to post a batch of reads and
prefers an i/o-handler thread to handle them all at once later. You must
call os_aio_simulated_wake_handler_threads later to ensure the threads
are not left sleeping! */
void
os_aio_simulated_put_read_threads_to_sleep();
#else /* _WIN32 */
# define os_aio_simulated_put_read_threads_to_sleep()
#endif /* _WIN32 */
/** This is the generic AIO handler interface function.
Waits for an aio operation to complete. This function is used to wait the
......
......@@ -3,7 +3,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, 2009, Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
......@@ -188,13 +188,16 @@ extern const char* srv_main_thread_op_info;
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
extern const char srv_mysql50_table_name_prefix[10];
/* The monitor thread waits on this event. */
/** Event to signal srv_monitor_thread. Not protected by a mutex.
Set after setting srv_print_innodb_monitor. */
extern os_event_t srv_monitor_event;
/* The error monitor thread waits on this event. */
/** Event to signal the shutdown of srv_error_monitor_thread.
Not protected by a mutex. */
extern os_event_t srv_error_event;
/** The buffer pool dump/load thread waits on this event. */
/** Event for waking up buf_dump_thread. Not protected by a mutex.
Set on shutdown or by buf_dump_start() or buf_load_start(). */
extern os_event_t srv_buf_dump_event;
/** The buffer pool resize thread waits on this event. */
......
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -399,7 +400,10 @@ struct trx_purge_t{
log operation can prevent this by
obtaining an s-latch here. It also
protects state and running */
os_event_t event; /*!< State signal event */
os_event_t event; /*!< State signal event;
os_event_set() and os_event_reset()
are protected by trx_purge_t::latch
X-lock */
ulint n_stop; /*!< Counter to track number stops */
volatile bool running; /*!< true, if purge is active,
we check this without the latch too */
......
......@@ -1166,11 +1166,14 @@ log_group_write_buf(
}
}
/** Flush the log has been written to the log file. */
/** Flush the recently written changes to the log file.
and invoke log_mutex_enter(). */
static
void
log_write_flush_to_disk_low()
{
/* FIXME: This is not holding log_sys->mutex while
calling os_event_set()! */
ut_a(log_sys->n_pending_flushes == 1); /* No other threads here */
#ifndef _WIN32
......@@ -1179,13 +1182,17 @@ log_write_flush_to_disk_low()
bool do_flush = true;
#endif
if (do_flush) {
log_group_t* group = UT_LIST_GET_FIRST(log_sys->log_groups);
fil_flush(group->space_id);
fil_flush(SRV_LOG_SPACE_FIRST_ID);
}
MONITOR_DEC(MONITOR_PENDING_LOG_FLUSH);
log_mutex_enter();
if (do_flush) {
log_sys->flushed_to_disk_lsn = log_sys->current_flush_lsn;
}
log_sys->n_pending_flushes--;
MONITOR_DEC(MONITOR_PENDING_LOG_FLUSH);
os_event_set(log_sys->flush_event);
}
......@@ -1340,6 +1347,7 @@ log_write_up_to(
/* Nothing to write, flush only */
log_mutex_exit_all();
log_write_flush_to_disk_low();
log_mutex_exit();
return;
}
}
......@@ -1419,6 +1427,7 @@ log_write_up_to(
log_write_flush_to_disk_low();
ib_uint64_t write_lsn = log_sys->write_lsn;
ib_uint64_t flush_lsn = log_sys->flushed_to_disk_lsn;
log_mutex_exit();
innobase_mysql_log_notify(write_lsn, flush_lsn);
}
......
......@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
......@@ -469,8 +469,6 @@ class AIO {
must call os_aio_simulated_wake_handler_threads later to ensure the
threads are not left sleeping! */
static void simulated_put_read_threads_to_sleep();
#endif /* _WIN32 */
/** Create an instance using new(std::nothrow)
......@@ -616,11 +614,13 @@ class AIO {
ulint m_n_segments;
/** The event which is set to the signaled state when
there is space in the aio outside the ibuf segment */
there is space in the aio outside the ibuf segment;
os_event_set() and os_event_reset() are protected by AIO::m_mutex */
os_event_t m_not_full;
/** The event which is set to the signaled state when
there are no pending i/os in this array */
there are no pending i/os in this array;
os_event_set() and os_event_reset() are protected by AIO::m_mutex */
os_event_t m_is_empty;
/** Number of reserved slots in the AIO array outside
......@@ -680,7 +680,7 @@ static const int OS_AIO_IO_SETUP_RETRY_ATTEMPTS = 5;
#endif /* LINUX_NATIVE_AIO */
/** Array of events used in simulated AIO */
static os_event_t* os_aio_segment_wait_events = NULL;
static os_event_t* os_aio_segment_wait_events;
/** Number of asynchronous I/O segments. Set by os_aio_init(). */
static ulint os_aio_n_segments = ULINT_UNDEFINED;
......@@ -3393,16 +3393,6 @@ os_file_set_eof(
return(!ftruncate(fileno(file), ftell(file)));
}
/** This function can be called if one wants to post a batch of reads and
prefers an i/o-handler thread to handle them all at once later. You must
call os_aio_simulated_wake_handler_threads later to ensure the threads
are not left sleeping! */
void
os_aio_simulated_put_read_threads_to_sleep()
{
/* No op on non Windows */
}
#else /* !_WIN32 */
#include <WinIoCtl.h>
......@@ -5982,6 +5972,12 @@ AIO::start(
os_aio_validate();
os_last_printout = ut_time();
if (srv_use_native_aio) {
return(true);
}
os_aio_segment_wait_events = static_cast<os_event_t*>(
ut_zalloc_nokey(
n_segments * sizeof *os_aio_segment_wait_events));
......@@ -5995,8 +5991,6 @@ AIO::start(
os_aio_segment_wait_events[i] = os_event_create(0);
}
os_last_printout = ut_time();
return(true);
}
......@@ -6047,12 +6041,14 @@ os_aio_free()
{
AIO::shutdown();
for (ulint i = 0; i < os_aio_n_segments; i++) {
os_event_destroy(os_aio_segment_wait_events[i]);
}
if (!srv_use_native_aio) {
for (ulint i = 0; i < os_aio_n_segments; i++) {
os_event_destroy(os_aio_segment_wait_events[i]);
}
ut_free(os_aio_segment_wait_events);
os_aio_segment_wait_events = 0;
ut_free(os_aio_segment_wait_events);
os_aio_segment_wait_events = 0;
}
os_aio_n_segments = 0;
}
......@@ -6066,21 +6062,16 @@ os_aio_wake_all_threads_at_shutdown()
AIO::wake_at_shutdown();
#elif defined(LINUX_NATIVE_AIO)
/* When using native AIO interface the io helper threads
wait on io_getevents with a timeout value of 500ms. At
each wake up these threads check the server status.
No need to do anything to wake them up. */
#endif /* !WIN_ASYNC_AIO */
if (srv_use_native_aio) {
return;
}
#endif /* !WIN_ASYNC_AIO */
/* Fall through to simulated AIO handler wakeup if we are
not using native AIO. */
/* This loop wakes up all simulated ai/o threads */
for (ulint i = 0; i < os_aio_n_segments; ++i) {
......@@ -7433,7 +7424,8 @@ os_aio_print(FILE* file)
srv_io_thread_function[i]);
#ifndef _WIN32
if (os_event_is_set(os_aio_segment_wait_events[i])) {
if (!srv_use_native_aio
&& os_event_is_set(os_aio_segment_wait_events[i])) {
fprintf(file, " ev set");
}
#endif /* _WIN32 */
......
......@@ -3,7 +3,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
......@@ -631,7 +631,11 @@ struct srv_sys_t{
ulint n_sys_threads; /*!< size of the sys_threads
array */
srv_slot_t* sys_threads; /*!< server thread table */
srv_slot_t* sys_threads; /*!< server thread table;
os_event_set() and
os_event_reset() on
sys_threads[]->event are
covered by srv_sys_t::mutex */
ulint n_threads_active[SRV_MASTER + 1];
/*!< number of threads active
......@@ -644,13 +648,16 @@ struct srv_sys_t{
static srv_sys_t* srv_sys = NULL;
/** Event to signal the monitor thread. */
/** Event to signal srv_monitor_thread. Not protected by a mutex.
Set after setting srv_print_innodb_monitor. */
os_event_t srv_monitor_event;
/** Event to signal the error thread */
/** Event to signal the shutdown of srv_error_monitor_thread.
Not protected by a mutex. */
os_event_t srv_error_event;
/** Event to signal the buffer pool dump/load thread */
/** Event for waking up buf_dump_thread. Not protected by a mutex.
Set on shutdown or by buf_dump_start() or buf_load_start(). */
os_event_t srv_buf_dump_event;
/** Event to signal the buffer pool resize thread */
......
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -282,23 +283,16 @@ trx_purge_sys_close(void)
sess_close(purge_sys->sess);
purge_sys->sess = NULL;
purge_sys->view.close();
purge_sys->view.~ReadView();
rw_lock_free(&purge_sys->latch);
mutex_free(&purge_sys->pq_mutex);
if (purge_sys->purge_queue != NULL) {
UT_DELETE(purge_sys->purge_queue);
purge_sys->purge_queue = NULL;
}
UT_DELETE(purge_sys->purge_queue);
os_event_destroy(purge_sys->event);
purge_sys->event = NULL;
UT_DELETE(purge_sys->rseg_iter);
ut_free(purge_sys);
......@@ -1910,20 +1904,16 @@ void
trx_purge_stop(void)
/*================*/
{
purge_state_t state;
int64_t sig_count = os_event_reset(purge_sys->event);
ut_a(srv_n_purge_threads > 0);
rw_lock_x_lock(&purge_sys->latch);
ut_a(purge_sys->state != PURGE_STATE_INIT);
ut_a(purge_sys->state != PURGE_STATE_EXIT);
ut_a(purge_sys->state != PURGE_STATE_DISABLED);
const int64_t sig_count = os_event_reset(purge_sys->event);
const purge_state_t state = purge_sys->state;
++purge_sys->n_stop;
ut_a(state == PURGE_STATE_RUN || state == PURGE_STATE_STOP);
state = purge_sys->state;
++purge_sys->n_stop;
if (state == PURGE_STATE_RUN) {
ib::info() << "Stopping purge";
......@@ -1936,18 +1926,14 @@ trx_purge_stop(void)
purge_sys->state = PURGE_STATE_STOP;
rw_lock_x_unlock(&purge_sys->latch);
if (state != PURGE_STATE_STOP) {
rw_lock_x_unlock(&purge_sys->latch);
/* Wait for purge coordinator to signal that it
is suspended. */
os_event_wait_low(purge_sys->event, sig_count);
} else {
bool once = true;
rw_lock_x_lock(&purge_sys->latch);
/* Wait for purge to signal that it has actually stopped. */
while (purge_sys->running) {
......@@ -1984,17 +1970,11 @@ trx_purge_run(void)
ut_error;
case PURGE_STATE_RUN:
case PURGE_STATE_STOP:
ut_a(!purge_sys->n_stop);
break;
}
if (purge_sys->n_stop > 0) {
ut_a(purge_sys->state == PURGE_STATE_STOP);
--purge_sys->n_stop;
if (purge_sys->n_stop == 0) {
case PURGE_STATE_STOP:
ut_a(purge_sys->n_stop);
if (--purge_sys->n_stop == 0) {
ib::info() << "Resuming purge";
......@@ -2002,8 +1982,6 @@ trx_purge_run(void)
}
MONITOR_INC_VALUE(MONITOR_PURGE_RESUME_COUNT, 1);
} else {
ut_a(purge_sys->state == PURGE_STATE_RUN);
}
rw_lock_x_unlock(&purge_sys->latch);
......
/*****************************************************************************
Copyright (c) 2006, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -31,7 +32,9 @@ Created 4/26/2006 Osku Salerma
struct ib_wqueue_t {
ib_mutex_t mutex; /*!< mutex protecting everything */
ib_list_t* items; /*!< work item list */
os_event_t event; /*!< event we use to signal additions to list */
os_event_t event; /*!< event we use to signal additions to list;
os_event_set() and os_event_reset() are
protected by ib_wqueue_t::mutex */
};
/****************************************************************//**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment