Commit 7fbc4f2b authored by marko's avatar marko

branches/zip: Merge revisions 1009:1165 from trunk.

parent 75e35eb7
...@@ -794,43 +794,20 @@ dict_init(void) ...@@ -794,43 +794,20 @@ dict_init(void)
} }
/************************************************************************** /**************************************************************************
Returns a table object. NOTE! This is a high-level function to be used Returns a table object and optionally increment its MySQL open handle count.
mainly from outside the 'dict' directory. Inside this directory NOTE! This is a high-level function to be used mainly from outside the
dict_table_get_low is usually the appropriate function. */ 'dict' directory. Inside this directory dict_table_get_low is usually the
appropriate function. */
dict_table_t* dict_table_t*
dict_table_get( dict_table_get(
/*===========*/ /*===========*/
/* out: table, NULL if /* out: table, NULL if
does not exist */ does not exist */
const char* table_name) /* in: table name */ const char* table_name, /* in: table name */
{ ibool inc_mysql_count)
dict_table_t* table; /* in: whether to increment the open
handle count on the table */
mutex_enter(&(dict_sys->mutex));
table = dict_table_get_low(table_name);
mutex_exit(&(dict_sys->mutex));
if (table != NULL) {
if (!table->stat_initialized) {
dict_update_statistics(table);
}
}
return(table);
}
/**************************************************************************
Returns a table object and increments MySQL open handle count on the table. */
dict_table_t*
dict_table_get_and_increment_handle_count(
/*======================================*/
/* out: table, NULL if
does not exist */
const char* table_name) /* in: table name */
{ {
dict_table_t* table; dict_table_t* table;
...@@ -838,15 +815,17 @@ dict_table_get_and_increment_handle_count( ...@@ -838,15 +815,17 @@ dict_table_get_and_increment_handle_count(
table = dict_table_get_low(table_name); table = dict_table_get_low(table_name);
if (table != NULL) { if (inc_mysql_count && table) {
table->n_mysql_handles_opened++; table->n_mysql_handles_opened++;
} }
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
if (table != NULL) { if (table != NULL) {
if (!table->stat_initialized && !table->ibd_file_missing) { if (!table->stat_initialized) {
/* If table->ibd_file_missing == TRUE, this will
print an error message and return without doing
anything. */
dict_update_statistics(table); dict_update_statistics(table);
} }
} }
......
...@@ -40,9 +40,6 @@ have disables the InnoDB inlining in this file. */ ...@@ -40,9 +40,6 @@ have disables the InnoDB inlining in this file. */
#include <myisampack.h> #include <myisampack.h>
#include <mysys_err.h> #include <mysys_err.h>
#include <my_sys.h> #include <my_sys.h>
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
#include "ha_innodb.h" #include "ha_innodb.h"
pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
...@@ -1257,18 +1254,6 @@ trx_is_interrupted( ...@@ -1257,18 +1254,6 @@ trx_is_interrupted(
return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed); return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed);
} }
/**************************************************************************
Obtain a pointer to the MySQL THD object, as in current_thd(). This
definition must match the one in sql/ha_innodb.cc! */
extern "C"
void*
innobase_current_thd(void)
/*======================*/
/* out: MySQL THD object */
{
return(current_thd);
}
/********************************************************************* /*********************************************************************
Call this when you have opened a new table handle in HANDLER, before you Call this when you have opened a new table handle in HANDLER, before you
call index_read_idx() etc. Actually, we can let the cursor stay open even call index_read_idx() etc. Actually, we can let the cursor stay open even
...@@ -2328,7 +2313,7 @@ ha_innobase::open( ...@@ -2328,7 +2313,7 @@ ha_innobase::open(
/* Get pointer to a table object in InnoDB dictionary cache */ /* Get pointer to a table object in InnoDB dictionary cache */
ib_table = dict_table_get_and_increment_handle_count(norm_name); ib_table = dict_table_get(norm_name, TRUE);
if (NULL == ib_table) { if (NULL == ib_table) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -2490,7 +2475,7 @@ get_field_offset( ...@@ -2490,7 +2475,7 @@ get_field_offset(
/****************************************************************** /******************************************************************
Checks if a field in a record is SQL NULL. Uses the record format Checks if a field in a record is SQL NULL. Uses the record format
information in table to track the null bit in record. */ information in table to track the null bit in record. */
inline static inline
uint uint
field_in_record_is_null( field_in_record_is_null(
/*====================*/ /*====================*/
...@@ -4915,7 +4900,7 @@ ha_innobase::create( ...@@ -4915,7 +4900,7 @@ ha_innobase::create(
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
innobase_table = dict_table_get(norm_name); innobase_table = dict_table_get(norm_name, FALSE);
DBUG_ASSERT(innobase_table != 0); DBUG_ASSERT(innobase_table != 0);
...@@ -5526,16 +5511,10 @@ ha_innobase::info( ...@@ -5526,16 +5511,10 @@ ha_innobase::info(
prebuilt->trx->op_info = (char*) prebuilt->trx->op_info = (char*)
"returning various info to MySQL"; "returning various info to MySQL";
if (ib_table->space != 0) { my_snprintf(path, sizeof(path), "%s/%s%s",
my_snprintf(path, sizeof(path), "%s/%s%s",
mysql_data_home, ib_table->name, ".ibd");
unpack_filename(path,path);
} else {
my_snprintf(path, sizeof(path), "%s/%s%s",
mysql_data_home, ib_table->name, reg_ext); mysql_data_home, ib_table->name, reg_ext);
unpack_filename(path,path); unpack_filename(path,path);
}
/* Note that we do not know the access time of the table, /* Note that we do not know the access time of the table,
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
...@@ -7344,7 +7323,6 @@ innobase_get_at_most_n_mbchars( ...@@ -7344,7 +7323,6 @@ innobase_get_at_most_n_mbchars(
} }
} }
extern "C" {
/********************************************************************** /**********************************************************************
This function returns true if This function returns true if
...@@ -7354,33 +7332,34 @@ is either REPLACE or LOAD DATA INFILE REPLACE. ...@@ -7354,33 +7332,34 @@ is either REPLACE or LOAD DATA INFILE REPLACE.
2) SQL-query in the current thread 2) SQL-query in the current thread
is INSERT ON DUPLICATE KEY UPDATE. is INSERT ON DUPLICATE KEY UPDATE.
NOTE that /mysql/innobase/row/row0ins.c must contain the NOTE that storage/innobase/row/row0ins.c must contain the
prototype for this function ! */ prototype for this function ! */
extern "C"
ibool ibool
innobase_query_is_update(void) innobase_query_is_update(void)
/*==========================*/ /*==========================*/
{ {
THD* thd; THD* thd = current_thd;
thd = (THD *)innobase_current_thd(); if (!thd) {
/* InnoDB's internal threads may run InnoDB stored procedures
that call this function. Then current_thd is not defined
(it is probably NULL). */
if (thd->lex->sql_command == SQLCOM_REPLACE || return(FALSE);
thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
(thd->lex->sql_command == SQLCOM_LOAD &&
thd->lex->duplicates == DUP_REPLACE)) {
return(1);
} }
if (thd->lex->sql_command == SQLCOM_INSERT && switch (thd->lex->sql_command) {
thd->lex->duplicates == DUP_UPDATE) { case SQLCOM_REPLACE:
case SQLCOM_REPLACE_SELECT:
return(1); return(TRUE);
case SQLCOM_LOAD:
return(thd->lex->duplicates == DUP_REPLACE);
case SQLCOM_INSERT:
return(thd->lex->duplicates == DUP_UPDATE);
default:
return(FALSE);
} }
return(0);
}
} }
/*********************************************************************** /***********************************************************************
......
...@@ -183,7 +183,7 @@ struct btr_search_struct{ ...@@ -183,7 +183,7 @@ struct btr_search_struct{
number of full fields */ number of full fields */
ulint n_bytes; /* recommended prefix: number of bytes in ulint n_bytes; /* recommended prefix: number of bytes in
an incomplete field; an incomplete field;
cf. BTR_PAGE_MAX_REC_SIZE */ see also BTR_PAGE_MAX_REC_SIZE */
ibool left_side; /* TRUE or FALSE, depending on whether ibool left_side; /* TRUE or FALSE, depending on whether
the leftmost record of several records with the leftmost record of several records with
the same prefix should be indexed in the the same prefix should be indexed in the
......
...@@ -65,8 +65,8 @@ dtype_get_mblen( ...@@ -65,8 +65,8 @@ dtype_get_mblen(
innobase_get_cset_width(dtype_get_charset_coll(prtype), innobase_get_cset_width(dtype_get_charset_coll(prtype),
mbminlen, mbmaxlen); mbminlen, mbmaxlen);
ut_ad(*mbminlen <= *mbmaxlen); ut_ad(*mbminlen <= *mbmaxlen);
ut_ad(*mbminlen <= 2); /* cf. the bit-field in dtype_t */ ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
ut_ad(*mbmaxlen < 1 << 3); /* cf. the bit-field in dtype_t */ ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
#else /* !UNIV_HOTBACKUP */ #else /* !UNIV_HOTBACKUP */
ut_a(mtype <= DATA_BINARY); ut_a(mtype <= DATA_BINARY);
*mbminlen = *mbmaxlen = 1; *mbminlen = *mbmaxlen = 1;
......
...@@ -333,26 +333,20 @@ dict_foreign_parse_drop_constraints( ...@@ -333,26 +333,20 @@ dict_foreign_parse_drop_constraints(
const char*** constraints_to_drop); /* out: id's of the const char*** constraints_to_drop); /* out: id's of the
constraints to drop */ constraints to drop */
/************************************************************************** /**************************************************************************
Returns a table object. NOTE! This is a high-level function to be used Returns a table object and optionally increment its MySQL open handle count.
mainly from outside the 'dict' directory. Inside this directory NOTE! This is a high-level function to be used mainly from outside the
dict_table_get_low is usually the appropriate function. */ 'dict' directory. Inside this directory dict_table_get_low is usually the
appropriate function. */
dict_table_t* dict_table_t*
dict_table_get( dict_table_get(
/*===========*/ /*===========*/
/* out: table, NULL if /* out: table, NULL if
does not exist */ does not exist */
const char* table_name); /* in: table name */ const char* table_name, /* in: table name */
/************************************************************************** ibool inc_mysql_count);
Returns a table object and increments MySQL open handle count on the table. /* in: whether to increment the open
*/ handle count on the table */
dict_table_t*
dict_table_get_and_increment_handle_count(
/*======================================*/
/* out: table, NULL if
does not exist */
const char* table_name); /* in: table name */
/************************************************************************** /**************************************************************************
Returns a table object based on table id. */ Returns a table object based on table id. */
......
...@@ -516,12 +516,6 @@ to 20 microseconds. */ ...@@ -516,12 +516,6 @@ to 20 microseconds. */
#define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
#define SYNC_INFINITE_TIME ((ulint)(-1))
/* Means that a timeout elapsed when waiting */
#define SYNC_TIME_EXCEEDED (ulint)1
/* The number of system calls made in this module. Intended for performance /* The number of system calls made in this module. Intended for performance
monitoring. */ monitoring. */
......
...@@ -77,25 +77,37 @@ memory is read outside the allocated blocks. */ ...@@ -77,25 +77,37 @@ memory is read outside the allocated blocks. */
/* Make a non-inline debug version */ /* Make a non-inline debug version */
#if 0 #if 0
#define UNIV_DEBUG_VALGRIND #define UNIV_DEBUG_VALGRIND /* Enable extra
#define UNIV_DEBUG_PRINT Valgrind instrumentation */
#define UNIV_BUF_DEBUG #define UNIV_DEBUG_PRINT /* Enable the compilation of
#define UNIV_DEBUG some debug print functions */
#define UNIV_DEBUG_FILE_ACCESSES #define UNIV_BUF_DEBUG /* Enable buffer pool
#define UNIV_LIST_DEBUG debugging without UNIV_DEBUG */
#define UNIV_MEM_DEBUG #define UNIV_DEBUG /* Enable ut_ad() assertions */
#define UNIV_IBUF_DEBUG #define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
#define UNIV_SYNC_DEBUG (field file_page_was_freed
#define UNIV_SEARCH_DEBUG in buf_page_t) */
#define UNIV_SYNC_PERF_STAT #define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
#define UNIV_SEARCH_PERF_STAT #define UNIV_MEM_DEBUG /* detect memory leaks etc */
#define UNIV_SRV_PRINT_LATCH_WAITS #define UNIV_IBUF_DEBUG /* debug the insert buffer;
#define UNIV_BTR_PRINT this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES,
and the insert buffer must be empty when the database is started */
#define UNIV_SYNC_DEBUG /* debug mutex and latch
operations (very slow); also UNIV_DEBUG must be defined */
#define UNIV_SEARCH_DEBUG /* debug B-tree comparisons */
#define UNIV_SYNC_PERF_STAT /* operation counts for
rw-locks and mutexes */
#define UNIV_SEARCH_PERF_STAT /* statistics for the
adaptive hash index */
#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output
in sync0sync.c */
#define UNIV_BTR_PRINT /* enable functions for
printing B-trees */
#define UNIV_ZIP_DEBUG #define UNIV_ZIP_DEBUG
#endif #endif
#define UNIV_BTR_DEBUG #define UNIV_BTR_DEBUG /* check B-tree links */
#define UNIV_LIGHT_MEM_DEBUG #define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */
#ifdef HAVE_purify #ifdef HAVE_purify
/* The following sets all new allocated memory to zero before use: /* The following sets all new allocated memory to zero before use:
......
...@@ -127,7 +127,8 @@ ulint ...@@ -127,7 +127,8 @@ ulint
ut_2_power_up( ut_2_power_up(
/*==========*/ /*==========*/
/* out: first power of 2 which is >= n */ /* out: first power of 2 which is >= n */
ulint n); /* in: number != 0 */ ulint n) /* in: number != 0 */
__attribute__((const));
/**************************************************************** /****************************************************************
Sort function for ulint arrays. */ Sort function for ulint arrays. */
......
...@@ -34,6 +34,7 @@ Created 9/20/1997 Heikki Tuuri ...@@ -34,6 +34,7 @@ Created 9/20/1997 Heikki Tuuri
#include "btr0cur.h" #include "btr0cur.h"
#include "dict0boot.h" #include "dict0boot.h"
#include "fil0fil.h" #include "fil0fil.h"
#include "sync0sync.h"
#ifdef UNIV_HOTBACKUP #ifdef UNIV_HOTBACKUP
/* This is set to FALSE if the backup was originally taken with the /* This is set to FALSE if the backup was originally taken with the
...@@ -191,6 +192,7 @@ recv_sys_empty_hash(void) ...@@ -191,6 +192,7 @@ recv_sys_empty_hash(void)
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256); recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
} }
#ifndef UNIV_LOG_DEBUG
/************************************************************ /************************************************************
Frees the recovery system. */ Frees the recovery system. */
static static
...@@ -210,6 +212,7 @@ recv_sys_free(void) ...@@ -210,6 +212,7 @@ recv_sys_free(void)
mutex_exit(&(recv_sys->mutex)); mutex_exit(&(recv_sys->mutex));
} }
#endif /* UNIV_LOG_DEBUG */
/************************************************************ /************************************************************
Truncates possible corrupted or extra records from a log group. */ Truncates possible corrupted or extra records from a log group. */
...@@ -2887,6 +2890,15 @@ recv_recovery_from_checkpoint_finish(void) ...@@ -2887,6 +2890,15 @@ recv_recovery_from_checkpoint_finish(void)
#ifndef UNIV_LOG_DEBUG #ifndef UNIV_LOG_DEBUG
recv_sys_free(); recv_sys_free();
#endif #endif
#ifdef UNIV_SYNC_DEBUG
/* Wait for a while so that created threads have time to suspend
themselves before we switch the latching order checks on */
os_thread_sleep(1000000);
/* Switch latching order checks on in sync0sync.c */
sync_order_checks_on = TRUE;
#endif
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
/* Rollback the uncommitted transactions which have no user /* Rollback the uncommitted transactions which have no user
session */ session */
......
...@@ -335,6 +335,8 @@ que_fork_start_command( ...@@ -335,6 +335,8 @@ que_fork_start_command(
que_fork_t* fork) /* in: a query fork */ que_fork_t* fork) /* in: a query fork */
{ {
que_thr_t* thr; que_thr_t* thr;
que_thr_t* suspended_thr = NULL;
que_thr_t* completed_thr = NULL;
fork->state = QUE_FORK_ACTIVE; fork->state = QUE_FORK_ACTIVE;
...@@ -344,14 +346,18 @@ que_fork_start_command( ...@@ -344,14 +346,18 @@ que_fork_start_command(
but in a parallelized select, which necessarily is non-scrollable, but in a parallelized select, which necessarily is non-scrollable,
there may be several to choose from */ there may be several to choose from */
/*--------------------------------------------------------------- /* First we try to find a query thread in the QUE_THR_COMMAND_WAIT
First we try to find a query thread in the QUE_THR_COMMAND_WAIT state state. Then we try to find a query thread in the QUE_THR_SUSPENDED
*/ state, finally we try to find a query thread in the QUE_THR_COMPLETED
state */
thr = UT_LIST_GET_FIRST(fork->thrs); thr = UT_LIST_GET_FIRST(fork->thrs);
while (thr != NULL) { /* We make a single pass over the thr list within which we note which
if (thr->state == QUE_THR_COMMAND_WAIT) { threads are ready to run. */
while (thr) {
switch (thr->state) {
case QUE_THR_COMMAND_WAIT:
/* We have to send the initial message to query thread /* We have to send the initial message to query thread
to start it */ to start it */
...@@ -359,49 +365,44 @@ que_fork_start_command( ...@@ -359,49 +365,44 @@ que_fork_start_command(
que_thr_init_command(thr); que_thr_init_command(thr);
return(thr); return(thr);
}
ut_ad(thr->state != QUE_THR_LOCK_WAIT);
thr = UT_LIST_GET_NEXT(thrs, thr);
}
/*----------------------------------------------------------------
Then we try to find a query thread in the QUE_THR_SUSPENDED state */
thr = UT_LIST_GET_FIRST(fork->thrs); case QUE_THR_SUSPENDED:
while (thr != NULL) {
if (thr->state == QUE_THR_SUSPENDED) {
/* In this case the execution of the thread was /* In this case the execution of the thread was
suspended: no initial message is needed because suspended: no initial message is needed because
execution can continue from where it was left */ execution can continue from where it was left */
if (!suspended_thr) {
suspended_thr = thr;
}
que_thr_move_to_run_state(thr); break;
case QUE_THR_COMPLETED:
if (!completed_thr) {
completed_thr = thr;
}
break;
case QUE_THR_LOCK_WAIT:
ut_error;
return(thr);
} }
thr = UT_LIST_GET_NEXT(thrs, thr); thr = UT_LIST_GET_NEXT(thrs, thr);
} }
/*----------------------------------------------------------------- if (suspended_thr) {
Then we try to find a query thread in the QUE_THR_COMPLETED state */
thr = UT_LIST_GET_FIRST(fork->thrs);
while (thr != NULL) { thr = suspended_thr;
if (thr->state == QUE_THR_COMPLETED) { que_thr_move_to_run_state(thr);
que_thr_init_command(thr);
return(thr); } else if (completed_thr) {
}
thr = UT_LIST_GET_NEXT(thrs, thr); thr = completed_thr;
que_thr_init_command(thr);
} }
/* Else we return NULL */ return(thr);
return(NULL);
} }
/************************************************************************** /**************************************************************************
......
...@@ -1535,7 +1535,8 @@ row_ins_check_foreign_constraints( ...@@ -1535,7 +1535,8 @@ row_ins_check_foreign_constraints(
if (foreign->foreign_index == index) { if (foreign->foreign_index == index) {
if (foreign->referenced_table == NULL) { if (foreign->referenced_table == NULL) {
dict_table_get(foreign->referenced_table_name); dict_table_get(foreign->referenced_table_name,
FALSE);
} }
if (0 == trx->dict_operation_lock_mode) { if (0 == trx->dict_operation_lock_mode) {
......
...@@ -4506,7 +4506,7 @@ row_search_check_if_query_cache_permitted( ...@@ -4506,7 +4506,7 @@ row_search_check_if_query_cache_permitted(
dict_table_t* table; dict_table_t* table;
ibool ret = FALSE; ibool ret = FALSE;
table = dict_table_get(norm_name); table = dict_table_get(norm_name, FALSE);
if (table == NULL) { if (table == NULL) {
......
...@@ -203,7 +203,8 @@ row_upd_check_references_constraints( ...@@ -203,7 +203,8 @@ row_upd_check_references_constraints(
foreign->n_fields))) { foreign->n_fields))) {
if (foreign->foreign_table == NULL) { if (foreign->foreign_table == NULL) {
dict_table_get(foreign->foreign_table_name); dict_table_get(foreign->foreign_table_name,
FALSE);
} }
if (foreign->foreign_table) { if (foreign->foreign_table) {
......
...@@ -1558,17 +1558,6 @@ innobase_start_or_create_for_mysql(void) ...@@ -1558,17 +1558,6 @@ innobase_start_or_create_for_mysql(void)
srv_was_started = TRUE; srv_was_started = TRUE;
srv_is_being_started = FALSE; srv_is_being_started = FALSE;
#ifdef UNIV_SYNC_DEBUG
/* Wait a while so that the created threads have time to suspend
themselves before we switch sync debugging on; otherwise a thread may
execute mutex_enter() before the checks are on, and mutex_exit() after
the checks are on, which will cause an assertion failure in sync
debug. */
os_thread_sleep(3000000);
sync_order_checks_on = TRUE;
#endif
if (trx_doublewrite == NULL) { if (trx_doublewrite == NULL) {
/* Create the doublewrite buffer to a new tablespace */ /* Create the doublewrite buffer to a new tablespace */
......
...@@ -131,8 +131,26 @@ trx_rollback_for_mysql( ...@@ -131,8 +131,26 @@ trx_rollback_for_mysql(
trx->op_info = "rollback"; trx->op_info = "rollback";
err = trx_general_rollback_for_mysql(trx, FALSE, NULL); /* If we are doing the XA recovery of prepared transactions, then
the transaction object does not have an InnoDB session object, and we
set a dummy session that we use for all MySQL transactions. */
mutex_enter(&kernel_mutex);
if (trx->sess == NULL) {
/* Open a dummy session */
if (!trx_dummy_sess) {
trx_dummy_sess = sess_open();
}
trx->sess = trx_dummy_sess;
}
mutex_exit(&kernel_mutex);
err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
trx->op_info = ""; trx->op_info = "";
return(err); return(err);
......
...@@ -1595,6 +1595,24 @@ trx_commit_for_mysql( ...@@ -1595,6 +1595,24 @@ trx_commit_for_mysql(
trx->op_info = "committing"; trx->op_info = "committing";
/* If we are doing the XA recovery of prepared transactions, then
the transaction object does not have an InnoDB session object, and we
set the dummy session that we use for all MySQL transactions. */
mutex_enter(&kernel_mutex);
if (trx->sess == NULL) {
/* Open a dummy session */
if (!trx_dummy_sess) {
trx_dummy_sess = sess_open();
}
trx->sess = trx_dummy_sess;
}
mutex_exit(&kernel_mutex);
trx_start_if_not_started(trx); trx_start_if_not_started(trx);
mutex_enter(&kernel_mutex); mutex_enter(&kernel_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