Commit 9f008768 authored by unknown's avatar unknown

merge


myisam/mi_check.c:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/table.h:
  Auto merged
parents d4e087e0 b33e9a2e
jcole@tetra.spaceapes.com
monty@donna.mysql.com
monty@work.mysql.com
mwagner@work.mysql.com
paul@central.snake.net
sasha@mysql.sashanet.com
sasha@work.mysql.com
serg@donna.mysql.com
serg@serg.mysql.com
tim@cane.mysql.fi
monty@work.mysql.com
This diff is collapsed.
......@@ -692,6 +692,10 @@ static int get_options(int argc, char **argv)
skip_column_names=1;
break;
case 'P':
if(!current_host) {
my_free(current_host, MYF(MY_ALLOW_ZERO_PTR));
current_host=my_strdup("127.0.0.1", MYF(MY_WME));
};
opt_mysql_port= (unsigned int) atoi(optarg);
break;
case 'S':
......
......@@ -185,6 +185,10 @@ int main(int argc,char *argv[])
interval=atoi(optarg);
break;
case 'P':
if(!host) {
my_free(host, MYF(MY_ALLOW_ZERO_PTR));
host=my_strdup("127.0.0.1", MYF(MY_WME));
};
tcp_port= (unsigned int) atoi(optarg);
break;
case 'r':
......
......@@ -344,6 +344,10 @@ static int get_options(int *argc,char ***argv)
tty_password=1;
break;
case 'P':
if(!current_host) {
my_free(current_host, MYF(MY_ALLOW_ZERO_PTR));
current_host=my_strdup("127.0.0.1", MYF(MY_WME));
};
opt_mysql_port= (unsigned int) atoi(optarg);
break;
case 'S':
......
......@@ -238,6 +238,10 @@ get_options(int *argc,char ***argv)
break;
#endif
case 'P':
if(!host) {
my_free(host, MYF(MY_ALLOW_ZERO_PTR));
host=my_strdup("127.0.0.1", MYF(MY_WME));
};
opt_mysql_port= (unsigned int) atoi(optarg);
break;
case 'S':
......
......@@ -1154,6 +1154,10 @@ int parse_args(int argc, char **argv)
tty_password=1;
break;
case 'P':
if(!host) {
my_free(host, MYF(MY_ALLOW_ZERO_PTR));
host=my_strdup("127.0.0.1", MYF(MY_WME));
};
port = atoi(optarg);
break;
case 'S':
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
#ifndef _my_bitmap_h_
#define _my_bitmap_h_
#define MY_BIT_NONE ~(uint)0
#ifdef __cplusplus
extern "C" {
#endif
extern void bitmap_set_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit);
extern uint bitmap_set_next(uchar *bitmap, uint bitmap_size);
extern void bitmap_clear_bit(uchar *bitmap,uint bitmap_size,uint bitmap_bit);
#ifdef __cplusplus
}
#endif
#endif
......@@ -27,7 +27,8 @@ extern "C" {
#include <my_list.h>
struct st_thr_lock;
extern ulong locks_immediate,locks_waited ;
enum thr_lock_type { TL_IGNORE=-1,
TL_UNLOCK, /* UNLOCK ANY LOCK */
TL_READ, /* Read lock */
......
......@@ -36,7 +36,7 @@ const char *client_errors[]=
"MySQL client got out of memory",
"Wrong host info",
"Localhost via UNIX socket",
"%s via TCP/IP",
"%-.64s via TCP/IP",
"Error in server handshake",
"Lost connection to MySQL server during query",
"Commands out of sync; You can't run this command now",
......@@ -62,11 +62,11 @@ const char *client_errors[]=
"MySQL client run out of memory",
"Wrong host info",
"Localhost via UNIX socket",
"%s via TCP/IP",
"%-.64s via TCP/IP",
"Error in server handshake",
"Lost connection to MySQL server during query",
"Commands out of sync; You can't run this command now",
"%s via named pipe",
"%-.64s via named pipe",
"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
......
......@@ -376,7 +376,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
if ((!(param->testflag & T_SILENT)))
printf ("- check data record references index: %d\n",key+1);
if (share->state.key_root[key] == HA_OFFSET_ERROR &&
info->state->records == 0)
(info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
continue;
if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],info->buff,
0))
......
Log_name
master-bin.001
master-bin.002
n
3351
Variable_name Value
Table_locks_immediate 0
Table_locks_waited 0
Variable_name Value
Table_locks_immediate 3
Table_locks_waited 1
connect (con1,localhost,boo,,test,0,mysql-master.sock);
connection con1;
-- error 1064;
drop database AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
rm -f $MYSQL_TEST_DIR/var/lib/master-bin.*
cp $MYSQL_TEST_DIR/std_data/master-bin.001 $MYSQL_TEST_DIR/var/lib/
echo ./master-bin.001 > $MYSQL_TEST_DIR/var/lib/master-bin.index
--skip-slave-start --abort-slave-event-count=1
connect (master,localhost,root,,test,0,mysql-master.sock);
connect (slave,localhost,root,,test,0,mysql-slave.sock);
connection slave;
reset slave;
slave start;
connection master;
show master logs;
drop table if exists t1;
create table t1(n int);
insert into t1 values (3351);
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
connection master;
drop table t1;
save_master_pos;
connection slave;
sync_with_master;
connect (con1,localhost,root,,test,0,mysql-master.sock);
connect (con2,localhost,root,,test,0,mysql-master.sock);
flush status;
show status like 'Table_lock%';
connection con1;
SET SQL_LOG_BIN=0;
drop table if exists t1;
create table t1(n int);
insert into t1 values(1);
connection con2;
lock tables t1 read;
unlock tables;
lock tables t1 read;
connection con1;
send update t1 set n = 3;
connection con2;
sleep 0.5;
unlock tables;
connection con1;
reap;
show status like 'Table_lock%';
drop table t1;
......@@ -44,7 +44,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_quick.c my_lockmem.c my_static.c \
getopt.c getopt1.c getvar.c my_mkdir.c \
default.c my_compress.c checksum.c raid.cc my_net.c \
my_vsnprintf.c charset.c
my_vsnprintf.c charset.c my_bitmap.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/*
Handling of uchar arrays as large bitmaps.
*/
#include "mysys_priv.h"
#include <my_bitmap.h>
pthread_mutex_t LOCK_bitmap;
void bitmap_set_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) {
if((bitmap_bit != MY_BIT_NONE) && (bitmap_bit < bitmap_size*8)) {
pthread_mutex_lock(&LOCK_bitmap);
bitmap[bitmap_bit / 8] |= (1 << bitmap_bit % 8);
pthread_mutex_unlock(&LOCK_bitmap);
};
};
uint bitmap_set_next(uchar *bitmap, uint bitmap_size) {
uint bit_found = MY_BIT_NONE;
int i, b;
pthread_mutex_lock(&LOCK_bitmap);
for(i=0; (i<bitmap_size) && (bit_found==MY_BIT_NONE); i++) {
if(bitmap[i] == 0xff) continue;
for(b=0; (b<8) && (bit_found==MY_BIT_NONE); b++)
if((bitmap[i] & 1<<b) == 0) {
bit_found = (i*8)+b;
bitmap[i] |= 1<<b;
};
};
pthread_mutex_unlock(&LOCK_bitmap);
return bit_found;
};
void bitmap_clear_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) {
if((bitmap_bit != MY_BIT_NONE) && (bitmap_bit < bitmap_size*8)) {
pthread_mutex_lock(&LOCK_bitmap);
bitmap[bitmap_bit / 8] &= ~(1 << bitmap_bit % 8);
pthread_mutex_unlock(&LOCK_bitmap);
};
};
......@@ -48,6 +48,7 @@ static my_bool win32_init_tcp_ip();
static my_bool my_init_done=0;
static ulong atoi_octal(const char *str)
{
long int tmp;
......@@ -76,6 +77,7 @@ void my_init(void)
#ifndef __WIN__
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif
pthread_mutex_init(&LOCK_bitmap, NULL);
#endif
{
DBUG_ENTER("my_init");
......@@ -127,7 +129,12 @@ void my_end(int infoflag)
#ifdef HAVE_GETRUSAGE
struct rusage rus;
if (!getrusage(RUSAGE_SELF, &rus))
fprintf(info_file,"\nUser time %.2f, System time %.2f\nMaximum resident set size %ld, Integral resident set size %ld\nNon physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\nBlocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\nVouluntary context switches %ld, Invouluntary context switches %ld\n",
fprintf(info_file,"\n\
User time %.2f, System time %.2f\n\
Maximum resident set size %ld, Integral resident set size %ld\n\
Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\
Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\
Voluntary context switches %ld, Involuntary context switches %ld\n",
(rus.ru_utime.tv_sec * SCALE_SEC +
rus.ru_utime.tv_usec / SCALE_USEC) / 100.0,
(rus.ru_stime.tv_sec * SCALE_SEC +
......@@ -159,6 +166,7 @@ void my_end(int infoflag)
pthread_mutex_destroy(&THR_LOCK_keycache);
pthread_mutex_destroy(&THR_LOCK_malloc);
pthread_mutex_destroy(&THR_LOCK_open);
pthread_mutex_destroy(&LOCK_bitmap);
DBUG_POP(); /* Must be done before my_thread_end */
my_thread_end();
my_thread_global_end();
......
......@@ -25,6 +25,7 @@
#ifdef THREAD
extern pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_net,THR_LOCK_charset;
extern pthread_mutex_t LOCK_bitmap;
#else /* THREAD */
#define pthread_mutex_lock(A)
#define pthread_mutex_unlock(A)
......
......@@ -83,7 +83,7 @@ multiple read locks.
#include <errno.h>
my_bool thr_lock_inited=0;
ulong locks_immediate = 0L, locks_waited = 0L;
/* The following constants are only for debug output */
#define MAX_THREADS 100
......@@ -387,6 +387,7 @@ static my_bool wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
else
{
result=0;
statistic_increment(locks_waited, &THR_LOCK_lock);
if (data->lock->get_status)
(*data->lock->get_status)(data->status_param);
check_locks(data->lock,"got wait_for_lock",0);
......@@ -447,6 +448,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
check_locks(lock,"read lock with old write lock",0);
if (lock->get_status)
(*lock->get_status)(data->status_param);
++locks_immediate;
goto end;
}
if (lock->write.data->type == TL_WRITE_ONLY)
......@@ -470,6 +472,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
if ((int) lock_type == (int) TL_READ_NO_INSERT)
lock->read_no_write_count++;
check_locks(lock,"read lock with no write locks",0);
++locks_immediate;
goto end;
}
/* Can't get lock yet; Wait for it */
......@@ -501,6 +504,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
data->cond=get_cond();
if (lock->get_status)
(*lock->get_status)(data->status_param);
++locks_immediate;
goto end;
}
}
......@@ -535,6 +539,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
check_locks(lock,"second write lock",0);
if (data->lock->get_status)
(*data->lock->get_status)(data->status_param);
++locks_immediate;
goto end;
}
DBUG_PRINT("lock",("write locked by thread: %ld",
......@@ -560,6 +565,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
if (data->lock->get_status)
(*data->lock->get_status)(data->status_param);
check_locks(lock,"only write lock",0);
++locks_immediate;
goto end;
}
}
......
......@@ -73,6 +73,7 @@ void kill_one_thread(THD *thd, ulong id);
#ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
#endif
#define TEMP_POOL_SIZE 128
/* The following parameters is to decide when to use an extra cache to
optimise seeks when reading a big table in sorted order */
#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024)
......@@ -507,7 +508,8 @@ extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
ha_read_first_count, ha_read_last_count,
ha_read_rnd_count, ha_read_rnd_next_count;
extern uchar temp_pool[TEMP_POOL_SIZE];
extern bool use_temp_pool;
extern char f_fyllchar;
extern uchar *days_in_month;
extern DATE_FORMAT dayord;
......
......@@ -287,6 +287,9 @@ I_List<THD> threads,thread_cache;
time_t start_time;
uchar temp_pool[TEMP_POOL_SIZE];
bool use_temp_pool;
pthread_key(MEM_ROOT*,THR_MALLOC);
pthread_key(THD*, THR_THD);
pthread_key(NET*, THR_NET);
......@@ -1532,6 +1535,9 @@ int main(int argc, char **argv)
if (!mysql_tmpdir || !mysql_tmpdir[0])
mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
bzero(temp_pool, TEMP_POOL_SIZE);
use_temp_pool = 0;
set_options();
#ifdef __WIN__
/* service parameters can be overwritten by options */
......@@ -2404,7 +2410,8 @@ enum options {
OPT_INNOBASE_LOG_GROUP_HOME_DIR,
OPT_INNOBASE_LOG_ARCH_DIR, OPT_INNOBASE_LOG_ARCHIVE,
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT, OPT_SAFE_SHOW_DB,
OPT_GEMINI_SKIP
OPT_GEMINI_SKIP,
OPT_TEMP_POOL
};
static struct option long_options[] = {
......@@ -2535,6 +2542,7 @@ static struct option long_options[] = {
#ifdef __WIN__
{"standalone", no_argument, 0, (int) OPT_STANDALONE},
#endif
{"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL},
{"tmpdir", required_argument, 0, 't'},
{"use-locking", no_argument, 0, (int) OPT_USE_LOCKING},
#ifdef USE_SYMDIR
......@@ -2803,6 +2811,8 @@ struct show_var_st status_vars[]= {
{"Sort_range", (char*) &filesort_range_count, SHOW_LONG},
{"Sort_rows", (char*) &filesort_rows, SHOW_LONG},
{"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG},
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST},
{"Threads_created", (char*) &thread_created, SHOW_LONG_CONST},
{"Threads_connected", (char*) &thread_count, SHOW_INT_CONST},
......@@ -2911,6 +2921,7 @@ static void usage(void)
Don't give threads different priorities.\n\
--socket=... Socket file to use for connection\n\
-t, --tmpdir=path Path for temporary files\n\
--temp-pool Use a pool of temporary files\n\
-u, --user=user_name Run mysqld daemon as user\n\
-V, --version output version information and exit");
#ifdef __WIN__
......@@ -3086,6 +3097,9 @@ static void get_options(int argc,char **argv)
case 't':
mysql_tmpdir=optarg;
break;
case OPT_TEMP_POOL:
use_temp_pool=1;
break;
case 'u':
mysqld_user=optarg;
break;
......
......@@ -1055,9 +1055,12 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
break;
case STOP_EVENT:
close_temporary_tables(thd);
mi->inc_pos(event_len);
flush_master_info(mi);
if(mi->pos > 4) // stop event should be ignored after rotate event
{
close_temporary_tables(thd);
mi->inc_pos(event_len);
flush_master_info(mi);
}
delete ev;
break;
case ROTATE_EVENT:
......
......@@ -1167,6 +1167,7 @@ bool wait_for_tables(THD *thd)
/* Now we can open all tables without any interference */
thd->proc_info="Reopen tables";
result=reopen_tables(thd,0,0);
}
pthread_mutex_unlock(&LOCK_open);
thd->proc_info=0;
......
......@@ -1886,6 +1886,13 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
if (db == any_db)
return FALSE; // Allow select on anything
if (strlen(db) > NAME_LEN || check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db);
return TRUE;
}
if (db && (!thd->db || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, db); /* purecov: inspected */
......
......@@ -391,7 +391,7 @@ sweepstakes if you report the bug";
thd->mysys_var->current_mutex = log_lock;
thd->mysys_var->current_cond = &COND_binlog_update;
const char* proc_info = thd->proc_info;
thd->proc_info = "Waiting for update";
thd->proc_info = "Slave connection: waiting for binlog update";
pthread_mutex_unlock(&thd->mysys_var->mutex);
bool read_packet = 0, fatal_error = 0;
......
......@@ -30,6 +30,7 @@
#include <hash.h>
#include <ft_global.h>
#include <assert.h>
#include <my_bitmap.h>
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext" };
......@@ -3287,14 +3288,28 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
KEY_PART_INFO *key_part_info;
Item_result_field **copy_func;
MI_COLUMNDEF *recinfo;
uint temp_pool_slot;
DBUG_ENTER("create_tmp_table");
DBUG_PRINT("enter",("distinct: %d save_sum_fields: %d allow_distinct_limit: %d group: %d",
(int) distinct, (int) save_sum_fields,
(int) allow_distinct_limit,test(group)));
statistic_increment(created_tmp_tables, &LOCK_status);
sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
if(use_temp_pool) {
temp_pool_slot = bitmap_set_next(temp_pool, TEMP_POOL_SIZE);
if(temp_pool_slot != MY_BIT_NONE) // we got a slot
sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix,
current_pid, temp_pool_slot);
else // if we run out of slots in the pool, fall back to old behavior
sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
} else {
sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
};
if (group)
{
if (!param->quick_group)
......@@ -3324,10 +3339,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
param->group_length : 0,
NullS))
{
bitmap_clear_bit(temp_pool, TEMP_POOL_SIZE, temp_pool_slot);
DBUG_RETURN(NULL); /* purecov: inspected */
}
if (!(param->copy_field=copy=new Copy_field[field_count]))
{
bitmap_clear_bit(temp_pool, TEMP_POOL_SIZE, temp_pool_slot);
my_free((gptr) table,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NULL); /* purecov: inspected */
}
......@@ -3347,6 +3364,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->map=1;
table->tmp_table=1;
table->db_low_byte_first=1; // True for HEAP and MyISAM
table->temp_pool_slot = temp_pool_slot;
/* Calculate which type of fields we will store in the temporary table */
......@@ -3670,7 +3689,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
DBUG_RETURN(table);
err:
free_tmp_table(thd,table); /* purecov: inspected */
free_tmp_table(thd,table); /* purecov: inspected */
bitmap_clear_bit(temp_pool, TEMP_POOL_SIZE, temp_pool_slot);
DBUG_RETURN(NULL); /* purecov: inspected */
}
......@@ -3817,6 +3837,9 @@ free_tmp_table(THD *thd, TABLE *entry)
delete *ptr;
my_free((gptr) entry->record[0],MYF(0));
free_io_cache(entry);
bitmap_clear_bit(temp_pool, TEMP_POOL_SIZE, entry->temp_pool_slot);
my_free((gptr) entry,MYF(0));
thd->proc_info=save_proc_info;
......
......@@ -120,6 +120,8 @@ struct st_table {
key_part_map const_key_parts[MAX_KEY];
ulong query_id;
uint temp_pool_slot;
THD *in_use; /* Which thread uses this */
struct st_table *next,*prev;
};
......
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