1119
1177
enum thr_lock_type new_lock_type)
1121
1179
THR_LOCK *lock=in_data->lock;
1181
enum thr_lock_type old_lock_type= in_data->type;
1183
#ifdef TO_BE_REMOVED
1184
THR_LOCK_DATA *data, *next;
1185
bool start_writers= FALSE;
1186
bool start_readers= FALSE;
1188
DBUG_ENTER("thr_downgrade_write_only_lock");
1123
1190
pthread_mutex_lock(&lock->mutex);
1191
DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY);
1192
DBUG_ASSERT(old_lock_type > new_lock_type);
1124
1193
in_data->type= new_lock_type;
1125
1194
check_locks(lock,"after downgrading lock",0);
1197
switch (old_lock_type)
1201
case TL_WRITE_LOW_PRIORITY:
1203
Previous lock was exclusive we are now ready to start up most waiting
1206
switch (new_lock_type)
1208
case TL_WRITE_ALLOW_READ:
1209
/* Still cannot start WRITE operations. Can only start readers. */
1210
start_readers= TRUE;
1213
case TL_WRITE_LOW_PRIORITY:
1215
Still cannot start anything, but new requests are no longer
1219
case TL_WRITE_ALLOW_WRITE:
1221
We can start both writers and readers.
1223
start_writers= TRUE;
1224
start_readers= TRUE;
1226
case TL_WRITE_CONCURRENT_INSERT:
1227
case TL_WRITE_DELAYED:
1229
This routine is not designed for those. Lock will be downgraded
1230
but no start of waiters will occur. This is not the optimal but
1231
should be a correct behaviour.
1238
case TL_WRITE_DELAYED:
1239
case TL_WRITE_CONCURRENT_INSERT:
1241
This routine is not designed for those. Lock will be downgraded
1242
but no start of waiters will occur. This is not the optimal but
1243
should be a correct behaviour.
1246
case TL_WRITE_ALLOW_READ:
1247
DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
1249
Previously writers were not allowed to start, now it is ok to
1250
start them again. Readers are already allowed so no reason to
1253
start_writers= TRUE;
1262
At this time the only active writer can be ourselves. Thus we need
1263
not worry about that there are other concurrent write operations
1264
active on the table. Thus we only need to worry about starting
1266
We also only come here with TL_WRITE_ALLOW_WRITE as the new
1267
lock type, thus we can start other writers also of the same type.
1268
If we find a lock at exclusive level >= TL_WRITE_LOW_PRIORITY we
1269
don't start any more operations that would be mean those operations
1270
will have to wait for things started afterwards.
1272
DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
1273
for (data=lock->write_wait.data; data ; data= next)
1276
All WRITE requests compatible with new lock type are also
1280
if (start_writers && data->type == new_lock_type)
1282
pthread_cond_t *cond= data->cond;
1284
It is ok to start this waiter.
1285
Move from being first in wait queue to be last in write queue.
1287
if (((*data->prev)= data->next))
1288
data->next->prev= data->prev;
1290
lock->write_wait.last= data->prev;
1291
data->prev= lock->write.last;
1292
lock->write.last= &data->next;
1294
check_locks(lock, "Started write lock after downgrade",0);
1296
pthread_cond_signal(cond);
1301
We found an incompatible lock, we won't start any more write
1302
requests to avoid letting writers pass other writers in the
1305
start_writers= FALSE;
1306
if (data->type >= TL_WRITE_LOW_PRIORITY)
1309
We have an exclusive writer in the queue so we won't start
1312
start_readers= FALSE;
1319
DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE ||
1320
new_lock_type == TL_WRITE_ALLOW_READ);
1322
When we come here we know that the write locks are
1323
TL_WRITE_ALLOW_WRITE or TL_WRITE_ALLOW_READ. This means that reads
1326
for (data=lock->read_wait.data; data ; data=next)
1330
All reads are ok to start now except TL_READ_NO_INSERT when
1331
write lock is TL_WRITE_ALLOW_READ.
1333
if (new_lock_type != TL_WRITE_ALLOW_READ ||
1334
data->type != TL_READ_NO_INSERT)
1336
pthread_cond_t *cond= data->cond;
1337
if (((*data->prev)= data->next))
1338
data->next->prev= data->prev;
1340
lock->read_wait.last= data->prev;
1341
data->prev= lock->read.last;
1342
lock->read.last= &data->next;
1345
if (data->type == TL_READ_NO_INSERT)
1346
lock->read_no_write_count++;
1347
check_locks(lock, "Started read lock after downgrade",0);
1349
pthread_cond_signal(cond);
1353
check_locks(lock,"after starting waiters after downgrading lock",0);
1127
1355
pthread_mutex_unlock(&lock->mutex);
1131
1359
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
1133
bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
1361
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
1135
1363
THR_LOCK *lock=data->lock;
1364
DBUG_ENTER("thr_upgrade_write_delay_lock");
1137
1366
pthread_mutex_lock(&lock->mutex);
1138
1367
if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
1140
1369
pthread_mutex_unlock(&lock->mutex);
1141
return(data->type == TL_UNLOCK); /* Test if Aborted */
1370
DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */
1143
1372
check_locks(lock,"before upgrading lock",0);
1144
1373
/* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
1207
1437
free_all_read_locks(lock,0);
1209
1439
pthread_mutex_unlock(&lock->mutex);
1210
return(thr_upgrade_write_delay_lock(data));
1440
DBUG_RETURN(thr_upgrade_write_delay_lock(data));
1214
1444
#include <my_sys.h>
1446
static void thr_print_lock(const char* name,struct st_lock_list *list)
1448
THR_LOCK_DATA *data,**prev;
1453
printf("%-10s: ",name);
1455
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
1457
printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
1459
if (data->prev != prev)
1460
printf("\nWarning: prev didn't point at previous lock\n");
1464
if (prev != list->last)
1465
printf("Warning: last didn't point at last lock\n");
1469
void thr_print_locks(void)
1474
pthread_mutex_lock(&THR_LOCK_lock);
1475
puts("Current locks:");
1476
for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
1477
list= list_rest(list))
1479
THR_LOCK *lock=(THR_LOCK*) list->data;
1480
VOID(pthread_mutex_lock(&lock->mutex));
1481
printf("lock: 0x%lx:",(ulong) lock);
1482
if ((lock->write_wait.data || lock->read_wait.data) &&
1483
(! lock->read.data && ! lock->write.data))
1484
printf(" WARNING: ");
1485
if (lock->write.data)
1487
if (lock->write_wait.data)
1488
printf(" write_wait");
1489
if (lock->read.data)
1491
if (lock->read_wait.data)
1492
printf(" read_wait");
1494
thr_print_lock("write",&lock->write);
1495
thr_print_lock("write_wait",&lock->write_wait);
1496
thr_print_lock("read",&lock->read);
1497
thr_print_lock("read_wait",&lock->read_wait);
1498
VOID(pthread_mutex_unlock(&lock->mutex));
1502
pthread_mutex_unlock(&THR_LOCK_lock);
1216
1507
/*****************************************************************************
1217
1508
** Test of thread locks
1218
1509
****************************************************************************/
1222
1515
struct st_test {
1224
1517
enum thr_lock_type lock_type;