361
358
else /* Request for WRITE lock */
363
if (lock_type == TL_WRITE_DELAYED)
365
if (lock->write.data && lock->write.data->type == TL_WRITE_ONLY)
367
data->type=TL_UNLOCK;
368
result= THR_LOCK_ABORTED; /* Can't wait for this one */
372
if there is a TL_WRITE_ALLOW_READ lock, we have to wait for a lock
373
(TL_WRITE_ALLOW_READ is used for ALTER TABLE in MySQL)
375
if ((!lock->write.data ||
376
lock->write.data->type != TL_WRITE_ALLOW_READ) &&
377
!have_specific_lock(lock->write_wait.data,TL_WRITE_ALLOW_READ) &&
378
(lock->write.data || lock->read.data))
380
/* Add delayed write lock to write_wait queue, and return at once */
381
(*lock->write_wait.last)=data;
382
data->prev=lock->write_wait.last;
383
lock->write_wait.last= &data->next;
384
data->cond=get_cond();
386
We don't have to do get_status here as we will do it when we change
387
the delayed lock to a real write lock
389
statistic_increment(locks_immediate,&THR_LOCK_lock);
393
else if (lock_type == TL_WRITE_CONCURRENT_INSERT && ! lock->check_status)
360
if (lock_type == TL_WRITE_CONCURRENT_INSERT && ! lock->check_status)
394
361
data->type=lock_type= thr_upgraded_concurrent_insert_lock;
396
363
if (lock->write.data) /* If there is a write lock */
871
830
pthread_mutex_unlock(&lock->mutex);
877
Downgrade a WRITE_* to a lower WRITE level
879
thr_downgrade_write_lock()
880
in_data Lock data of thread downgrading its lock
881
new_lock_type New write lock type
885
This can be used to downgrade a lock already owned. When the downgrade
886
occurs also other waiters, both readers and writers can be allowed to
888
The previous lock is often TL_WRITE_ONLY but can also be
889
TL_WRITE and TL_WRITE_ALLOW_READ. The normal downgrade variants are
890
TL_WRITE_ONLY => TL_WRITE_ALLOW_READ After a short exclusive lock
891
TL_WRITE_ALLOW_READ => TL_WRITE_ALLOW_WRITE After discovering that the
892
operation didn't need such a high lock.
893
TL_WRITE_ONLY => TL_WRITE after a short exclusive lock while holding a
895
TL_WRITE_ONLY => TL_WRITE_ALLOW_WRITE After a short exclusive lock after
896
already earlier having dongraded lock to TL_WRITE_ALLOW_WRITE
897
The implementation is conservative and rather don't start rather than
898
go on unknown paths to start, the common cases are handled.
901
In its current implementation it is only allowed to downgrade from
902
TL_WRITE_ONLY. In this case there are no waiters. Thus no wake up
906
void thr_downgrade_write_lock(THR_LOCK_DATA *in_data,
907
enum thr_lock_type new_lock_type)
909
THR_LOCK *lock=in_data->lock;
911
pthread_mutex_lock(&lock->mutex);
912
in_data->type= new_lock_type;
914
pthread_mutex_unlock(&lock->mutex);
918
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
920
bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
922
THR_LOCK *lock=data->lock;
924
pthread_mutex_lock(&lock->mutex);
925
if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
927
pthread_mutex_unlock(&lock->mutex);
928
return(data->type == TL_UNLOCK); /* Test if Aborted */
930
/* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
931
data->type=TL_WRITE; /* Upgrade lock */
933
/* Check if someone has given us the lock */
936
if (!lock->read.data) /* No read locks */
937
{ /* We have the lock */
938
if (data->lock->get_status)
939
(*data->lock->get_status)(data->status_param, 0);
940
pthread_mutex_unlock(&lock->mutex);
944
if (((*data->prev)=data->next)) /* remove from lock-list */
945
data->next->prev= data->prev;
947
lock->write.last=data->prev;
949
if ((data->next=lock->write_wait.data)) /* Put first in lock_list */
950
data->next->prev= &data->next;
952
lock->write_wait.last= &data->next;
953
data->prev= &lock->write_wait.data;
954
lock->write_wait.data=data;
957
return(wait_for_lock(&lock->write_wait,data,1));
961
/* downgrade a WRITE lock to a WRITE_DELAY lock if there is pending locks */
963
bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
965
THR_LOCK *lock=data->lock;
967
pthread_mutex_lock(&lock->mutex);
968
if (!lock->read_wait.data) /* No waiting read locks */
970
pthread_mutex_unlock(&lock->mutex);
974
data->type=TL_WRITE_DELAYED;
975
if (lock->update_status)
976
(*lock->update_status)(data->status_param);
977
if (((*data->prev)=data->next)) /* remove from lock-list */
978
data->next->prev= data->prev;
980
lock->write.last=data->prev;
982
if ((data->next=lock->write_wait.data)) /* Put first in lock_list */
983
data->next->prev= &data->next;
985
lock->write_wait.last= &data->next;
986
data->prev= &lock->write_wait.data;
987
data->cond=get_cond(); /* This was zero */
988
lock->write_wait.data=data;
989
free_all_read_locks(lock,0);
991
pthread_mutex_unlock(&lock->mutex);
992
return(thr_upgrade_write_delay_lock(data));