Commit 373ab5b3 authored by unknown's avatar unknown

Share DB *file; this fixes a deadlock problem.

    While we're at it, share the keyfile and keytype arrays, too.


sql/ha_berkeley.cc:
  Share DB *file; this fixes a deadlock problem.
  While we're at it, share the keyfile and keytype arrays, too.
sql/ha_berkeley.h:
  Share DB *file; this fixes a deadlock problem.
  While we're at it, share the keyfile and keytype arrays, too.
parent 74bb64d3
......@@ -81,7 +81,7 @@ u_int32_t berkeley_init_flags= DB_PRIVATE | DB_RECOVER, berkeley_env_flags=0,
ulong berkeley_cache_size;
char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
long berkeley_lock_scan_time=0;
ulong berkeley_trans_retry=5;
ulong berkeley_trans_retry=1;
ulong berkeley_max_lock;
pthread_mutex_t bdb_mutex;
......@@ -99,7 +99,7 @@ static void berkeley_print_error(const char *db_errpfx, char *buffer);
static byte* bdb_get_key(BDB_SHARE *share,uint *length,
my_bool not_used __attribute__((unused)));
static BDB_SHARE *get_share(const char *table_name, TABLE *table);
static void free_share(BDB_SHARE *share, TABLE *table);
static int free_share(BDB_SHARE *share, TABLE *table);
static int write_status(DB *status_block, char *buff, uint length);
static void update_status(BDB_SHARE *share, TABLE *table);
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
......@@ -433,8 +433,6 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
uint max_key_length= table->max_key_length + MAX_REF_PARTS*2;
if (!(alloc_ptr=
my_multi_malloc(MYF(MY_WME),
&key_file, (table->keys+1)*sizeof(*key_file),
&key_type, (table->keys+1)*sizeof(u_int32_t),
&key_buff, max_key_length,
&key_buff2, max_key_length,
&primary_key_buff,
......@@ -449,7 +447,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(1);
}
/* Init table lock structure */
/* Init shared structure */
if (!(share=get_share(name,table)))
{
my_free(rec_buff,MYF(0));
......@@ -457,7 +455,14 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(1);
}
thr_lock_data_init(&share->lock,&lock,(void*) 0);
key_file = share->key_file;
key_type = share->key_type;
/* Fill in shared structure, if needed */
pthread_mutex_lock(&share->mutex);
file = share->file;
if (!share->use_count++)
{
if ((error=db_create(&file, db_env, 0)))
{
free_share(share,table);
......@@ -466,6 +471,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
my_errno=error;
DBUG_RETURN(1);
}
share->file = file;
file->set_bt_compare(file,
(hidden_primary_key ? berkeley_cmp_hidden_key :
......@@ -483,13 +489,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(1);
}
transaction=0;
cursor=0;
key_read=0;
fixed_length_row=!(table->db_create_options & HA_OPTION_PACK_RECORD);
/* Open other keys */
bzero((char*) key_file,sizeof(*key_file)*table->keys);
key_file[primary_key]=file;
key_type[primary_key]=DB_NOOVERWRITE;
bzero((char*) &current_row,sizeof(current_row));
......@@ -533,6 +533,15 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
(ref_length == table->key_info[primary_key].key_length);
share->status|=STATUS_PRIMARY_KEY_INIT;
}
}
pthread_mutex_unlock(&share->mutex);
transaction=0;
cursor=0;
key_read=0;
fixed_length_row=!(table->db_create_options & HA_OPTION_PACK_RECORD);
get_status();
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
DBUG_RETURN(0);
......@@ -541,21 +550,12 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
int ha_berkeley::close(void)
{
int error,result=0;
uint keys=table->keys + test(hidden_primary_key);
DBUG_ENTER("ha_berkeley::close");
for (uint i=0; i < keys; i++)
{
if (key_file[i] && (error=key_file[i]->close(key_file[i],0)))
result=error;
}
free_share(share,table);
my_free(rec_buff,MYF(MY_ALLOW_ZERO_PTR));
my_free(alloc_ptr,MYF(MY_ALLOW_ZERO_PTR));
if (result)
my_errno=result;
DBUG_RETURN(result);
DBUG_RETURN(free_share(share,table));
}
......@@ -2024,16 +2024,26 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table)
uint length=(uint) strlen(table_name);
if (!(share=(BDB_SHARE*) hash_search(&bdb_open_tables, table_name, length)))
{
if ((share=(BDB_SHARE *) my_malloc(ALIGN_SIZE(sizeof(*share))+
sizeof(ha_rows)* table->keys +
length+1,
MYF(MY_WME | MY_ZEROFILL))))
ha_rows *rec_per_key;
char *tmp_name;
DB **key_file;
u_int32_t *key_type;
if ((share=(BDB_SHARE *)
my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&share, sizeof(*share),
&rec_per_key, table->keys * sizeof(ha_rows),
&tmp_name, length+1,
&key_file, (table->keys+1) * sizeof(*key_file),
&key_type, (table->keys+1) * sizeof(u_int32_t),
NullS)))
{
share->rec_per_key= (ha_rows*) ((char*) share +
ALIGN_SIZE(sizeof(*share)));
share->table_name=(char*) (share->rec_per_key+table->keys);
share->rec_per_key = rec_per_key;
share->table_name = tmp_name;
share->table_name_length=length;
strmov(share->table_name,table_name);
share->key_file = key_file;
share->key_type = key_type;
if (hash_insert(&bdb_open_tables, (char*) share))
{
pthread_mutex_unlock(&bdb_mutex);
......@@ -2044,25 +2054,34 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table)
pthread_mutex_init(&share->mutex,NULL);
}
}
share->use_count++;
pthread_mutex_unlock(&bdb_mutex);
return share;
}
static void free_share(BDB_SHARE *share, TABLE *table)
static int free_share(BDB_SHARE *share, TABLE *table)
{
int error, result = 0;
pthread_mutex_lock(&bdb_mutex);
if (!--share->use_count)
{
DB **key_file = share->key_file;
update_status(share,table);
if (share->status_block)
share->status_block->close(share->status_block,0);
/* this does share->file->close() implicitly */
for (uint i=0; i < table->keys; i++)
{
if (key_file[i] && (error=key_file[i]->close(key_file[i],0)))
result=error;
}
if (share->status_block &&
(error = share->status_block->close(share->status_block,0)))
result = error;
hash_delete(&bdb_open_tables, (gptr) share);
thr_lock_delete(&share->lock);
pthread_mutex_destroy(&share->mutex);
my_free((gptr) share, MYF(0));
}
pthread_mutex_unlock(&bdb_mutex);
return result;
}
/*
......
......@@ -31,7 +31,8 @@ typedef struct st_berkeley_share {
THR_LOCK lock;
pthread_mutex_t mutex;
char *table_name;
DB *status_block;
DB *status_block, *file, **key_file;
u_int32_t *key_type;
uint table_name_length,use_count;
uint status,version;
} BDB_SHARE;
......
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