1119
1176
enum thr_lock_type new_lock_type)
1121
1178
THR_LOCK *lock=in_data->lock;
1180
enum thr_lock_type old_lock_type= in_data->type;
1182
#ifdef TO_BE_REMOVED
1183
THR_LOCK_DATA *data, *next;
1184
bool start_writers= FALSE;
1185
bool start_readers= FALSE;
1187
DBUG_ENTER("thr_downgrade_write_only_lock");
1123
1189
pthread_mutex_lock(&lock->mutex);
1190
DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY);
1191
DBUG_ASSERT(old_lock_type > new_lock_type);
1124
1192
in_data->type= new_lock_type;
1125
1193
check_locks(lock,"after downgrading lock",0);
1196
switch (old_lock_type)
1200
case TL_WRITE_LOW_PRIORITY:
1202
Previous lock was exclusive we are now ready to start up most waiting
1205
switch (new_lock_type)
1207
case TL_WRITE_ALLOW_READ:
1208
/* Still cannot start WRITE operations. Can only start readers. */
1209
start_readers= TRUE;
1212
case TL_WRITE_LOW_PRIORITY:
1214
Still cannot start anything, but new requests are no longer
1218
case TL_WRITE_ALLOW_WRITE:
1220
We can start both writers and readers.
1222
start_writers= TRUE;
1223
start_readers= TRUE;
1225
case TL_WRITE_CONCURRENT_INSERT:
1226
case TL_WRITE_DELAYED:
1228
This routine is not designed for those. Lock will be downgraded
1229
but no start of waiters will occur. This is not the optimal but
1230
should be a correct behaviour.
1237
case TL_WRITE_DELAYED:
1238
case TL_WRITE_CONCURRENT_INSERT:
1240
This routine is not designed for those. Lock will be downgraded
1241
but no start of waiters will occur. This is not the optimal but
1242
should be a correct behaviour.
1245
case TL_WRITE_ALLOW_READ:
1246
DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
1248
Previously writers were not allowed to start, now it is ok to
1249
start them again. Readers are already allowed so no reason to
1252
start_writers= TRUE;
1261
At this time the only active writer can be ourselves. Thus we need
1262
not worry about that there are other concurrent write operations
1263
active on the table. Thus we only need to worry about starting
1265
We also only come here with TL_WRITE_ALLOW_WRITE as the new
1266
lock type, thus we can start other writers also of the same type.
1267
If we find a lock at exclusive level >= TL_WRITE_LOW_PRIORITY we
1268
don't start any more operations that would be mean those operations
1269
will have to wait for things started afterwards.
1271
DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
1272
for (data=lock->write_wait.data; data ; data= next)
1275
All WRITE requests compatible with new lock type are also
1279
if (start_writers && data->type == new_lock_type)
1281
pthread_cond_t *cond= data->cond;
1283
It is ok to start this waiter.
1284
Move from being first in wait queue to be last in write queue.
1286
if (((*data->prev)= data->next))
1287
data->next->prev= data->prev;
1289
lock->write_wait.last= data->prev;
1290
data->prev= lock->write.last;
1291
lock->write.last= &data->next;
1293
check_locks(lock, "Started write lock after downgrade",0);
1295
pthread_cond_signal(cond);
1300
We found an incompatible lock, we won't start any more write
1301
requests to avoid letting writers pass other writers in the
1304
start_writers= FALSE;
1305
if (data->type >= TL_WRITE_LOW_PRIORITY)
1308
We have an exclusive writer in the queue so we won't start
1311
start_readers= FALSE;
1318
DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE ||
1319
new_lock_type == TL_WRITE_ALLOW_READ);
1321
When we come here we know that the write locks are
1322
TL_WRITE_ALLOW_WRITE or TL_WRITE_ALLOW_READ. This means that reads
1325
for (data=lock->read_wait.data; data ; data=next)
1329
All reads are ok to start now except TL_READ_NO_INSERT when
1330
write lock is TL_WRITE_ALLOW_READ.
1332
if (new_lock_type != TL_WRITE_ALLOW_READ ||
1333
data->type != TL_READ_NO_INSERT)
1335
pthread_cond_t *cond= data->cond;
1336
if (((*data->prev)= data->next))
1337
data->next->prev= data->prev;
1339
lock->read_wait.last= data->prev;
1340
data->prev= lock->read.last;
1341
lock->read.last= &data->next;
1344
if (data->type == TL_READ_NO_INSERT)
1345
lock->read_no_write_count++;
1346
check_locks(lock, "Started read lock after downgrade",0);
1348
pthread_cond_signal(cond);
1352
check_locks(lock,"after starting waiters after downgrading lock",0);
1127
1354
pthread_mutex_unlock(&lock->mutex);
1131
1358
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
1133
bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
1360
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
1135
1362
THR_LOCK *lock=data->lock;
1363
DBUG_ENTER("thr_upgrade_write_delay_lock");
1137
1365
pthread_mutex_lock(&lock->mutex);
1138
1366
if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
1140
1368
pthread_mutex_unlock(&lock->mutex);
1141
return(data->type == TL_UNLOCK); /* Test if Aborted */
1369
DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */
1143
1371
check_locks(lock,"before upgrading lock",0);
1144
1372
/* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
1207
1436
free_all_read_locks(lock,0);
1209
1438
pthread_mutex_unlock(&lock->mutex);
1210
return(thr_upgrade_write_delay_lock(data));
1439
DBUG_RETURN(thr_upgrade_write_delay_lock(data));
1214
1443
#include <my_sys.h>
1445
static void thr_print_lock(const char* name,struct st_lock_list *list)
1447
THR_LOCK_DATA *data,**prev;
1452
printf("%-10s: ",name);
1454
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
1456
printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
1458
if (data->prev != prev)
1459
printf("\nWarning: prev didn't point at previous lock\n");
1463
if (prev != list->last)
1464
printf("Warning: last didn't point at last lock\n");
1468
void thr_print_locks(void)
1473
pthread_mutex_lock(&THR_LOCK_lock);
1474
puts("Current locks:");
1475
for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
1476
list= list_rest(list))
1478
THR_LOCK *lock=(THR_LOCK*) list->data;
1479
VOID(pthread_mutex_lock(&lock->mutex));
1480
printf("lock: 0x%lx:",(ulong) lock);
1481
if ((lock->write_wait.data || lock->read_wait.data) &&
1482
(! lock->read.data && ! lock->write.data))
1483
printf(" WARNING: ");
1484
if (lock->write.data)
1486
if (lock->write_wait.data)
1487
printf(" write_wait");
1488
if (lock->read.data)
1490
if (lock->read_wait.data)
1491
printf(" read_wait");
1493
thr_print_lock("write",&lock->write);
1494
thr_print_lock("write_wait",&lock->write_wait);
1495
thr_print_lock("read",&lock->read);
1496
thr_print_lock("read_wait",&lock->read_wait);
1497
VOID(pthread_mutex_unlock(&lock->mutex));
1501
pthread_mutex_unlock(&THR_LOCK_lock);
1216
1504
/*****************************************************************************
1217
1505
** Test of thread locks
1218
1506
****************************************************************************/