diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index cfb445e9427..7e9cb81a8f0 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -1883,6 +1883,20 @@ a b 2 Curly drop table federated.t1; drop table federated.t1; + +Bug#18287 create federated table always times out, error 1159 ' ' + +Test that self-references work + +create table federated.t1 (a int primary key); +create table federated.t2 (a int primary key) +ENGINE=FEDERATED +connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +insert into federated.t1 (a) values (1); +select * from federated.t2; +a +1 +drop table federated.t1, federated.t2; CREATE TABLE federated.t1 (a INT PRIMARY KEY) DEFAULT CHARSET=utf8; CREATE TABLE federated.t1 (a INT PRIMARY KEY) ENGINE=FEDERATED diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index efca7f3232d..ee607225d35 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1685,6 +1685,20 @@ drop table federated.t1; connection slave; drop table federated.t1; +--echo +--echo Bug#18287 create federated table always times out, error 1159 ' ' +--echo +--echo Test that self-references work +--echo +connection slave; +create table federated.t1 (a int primary key); +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval create table federated.t2 (a int primary key) + ENGINE=FEDERATED + connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +insert into federated.t1 (a) values (1); +select * from federated.t2; +drop table federated.t1, federated.t2; # # BUG#29875 Disable support for transactions diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 20edffb49c2..a81ed925562 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -384,6 +384,9 @@ static inline my_bool have_specific_lock(THR_LOCK_DATA *data, } +static void wake_up_waiters(THR_LOCK *lock); + + static enum enum_thr_lock_result wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, my_bool in_wait_list) @@ -445,8 +448,13 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, else wait->last=data->prev; data->type= TL_UNLOCK; /* No lock */ + check_locks(data->lock, "killed or timed out wait_for_lock", 1); + wake_up_waiters(data->lock); + } + else + { + check_locks(data->lock, "aborted wait_for_lock", 0); } - check_locks(data->lock,"failed wait_for_lock",0); } else { @@ -776,6 +784,26 @@ void thr_unlock(THR_LOCK_DATA *data) lock->read_no_write_count--; data->type=TL_UNLOCK; /* Mark unlocked */ check_locks(lock,"after releasing lock",1); + wake_up_waiters(lock); + pthread_mutex_unlock(&lock->mutex); + DBUG_VOID_RETURN; +} + + +/** + @brief Wake up all threads which pending requests for the lock + can be satisfied. + + @param lock Lock for which threads should be woken up + +*/ + +static void wake_up_waiters(THR_LOCK *lock) +{ + THR_LOCK_DATA *data; + enum thr_lock_type lock_type; + + DBUG_ENTER("wake_up_waiters"); if (!lock->write.data) /* If no active write locks */ { @@ -827,11 +855,7 @@ void thr_unlock(THR_LOCK_DATA *data) data=lock->write_wait.data; /* Free this too */ } if (data->type >= TL_WRITE_LOW_PRIORITY) - { - check_locks(lock,"giving write lock",0); - pthread_mutex_unlock(&lock->mutex); - DBUG_VOID_RETURN; - } + goto end; /* Release possible read locks together with the write lock */ } if (lock->read_wait.data) @@ -886,8 +910,7 @@ void thr_unlock(THR_LOCK_DATA *data) free_all_read_locks(lock,0); } end: - check_locks(lock,"thr_unlock",0); - pthread_mutex_unlock(&lock->mutex); + check_locks(lock, "after waking up waiters", 0); DBUG_VOID_RETURN; } @@ -1101,6 +1124,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) lock->write_wait.last= data->prev; } } + wake_up_waiters(lock); pthread_mutex_unlock(&lock->mutex); DBUG_RETURN(found); }