~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/lock.cc

  • Committer: Brian Aker
  • Date: 2008-07-10 19:37:55 UTC
  • mfrom: (51.1.67 remove-dbug)
  • Revision ID: brian@tangent.org-20080710193755-f5g761uieqa3wxmt
Merge.

Show diffs side-by-side

added added

removed removed

Lines of Context:
138
138
  uint system_count;
139
139
  uint i;
140
140
 
141
 
  DBUG_ENTER("mysql_lock_tables_check");
142
 
 
143
141
  system_count= 0;
144
142
 
145
143
  for (i=0 ; i<count; i++)
147
145
    TABLE *t= tables[i];
148
146
 
149
147
    /* Protect against 'fake' partially initialized TABLE_SHARE */
150
 
    DBUG_ASSERT(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
 
148
    assert(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
151
149
 
152
150
    if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) &&
153
151
        (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE))
164
162
  if ((system_count > 0) && (system_count < count))
165
163
  {
166
164
    my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
167
 
    DBUG_RETURN(1);
 
165
    return(1);
168
166
  }
169
167
 
170
 
  DBUG_RETURN(0);
 
168
  return(0);
171
169
}
172
170
 
173
171
 
216
214
  TABLE *write_lock_used;
217
215
  int rc;
218
216
 
219
 
  DBUG_ENTER("mysql_lock_tables");
220
 
 
221
 
  *need_reopen= FALSE;
 
217
  *need_reopen= false;
222
218
 
223
219
  if (mysql_lock_tables_check(thd, tables, count, flags))
224
 
    DBUG_RETURN (NULL);
 
220
    return (NULL);
225
221
 
226
222
  for (;;)
227
223
  {
265
261
    }
266
262
 
267
263
    thd_proc_info(thd, "System lock");
268
 
    DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
269
264
    if (sql_lock->table_count && lock_external(thd, sql_lock->table,
270
265
                                               sql_lock->table_count))
271
266
    {
274
269
      break;
275
270
    }
276
271
    thd_proc_info(thd, "Table lock");
277
 
    DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
278
272
    /* Copy the lock data array. thr_multi_lock() reorders its contens. */
279
273
    memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
280
274
           sql_lock->lock_count * sizeof(*sql_lock->locks));
329
323
retry:
330
324
    if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
331
325
    {
332
 
      *need_reopen= TRUE;
 
326
      *need_reopen= true;
333
327
      break;
334
328
    }
335
329
    if (wait_for_tables(thd))
347
341
  }
348
342
 
349
343
  thd->set_time_after_lock();
350
 
  DBUG_RETURN (sql_lock);
 
344
  return (sql_lock);
351
345
}
352
346
 
353
347
 
355
349
{
356
350
  register uint i;
357
351
  int lock_type,error;
358
 
  DBUG_ENTER("lock_external");
359
 
 
360
 
  DBUG_PRINT("info", ("count %d", count));
361
352
  for (i=1 ; i <= count ; i++, tables++)
362
353
  {
363
 
    DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
 
354
    assert((*tables)->reginfo.lock_type >= TL_READ);
364
355
    lock_type=F_WRLCK;                          /* Lock exclusive */
365
356
    if ((*tables)->db_stat & HA_READ_ONLY ||
366
357
        ((*tables)->reginfo.lock_type >= TL_READ &&
376
367
        (*tables)->file->ha_external_lock(thd, F_UNLCK);
377
368
        (*tables)->current_lock=F_UNLCK;
378
369
      }
379
 
      DBUG_RETURN(error);
 
370
      return(error);
380
371
    }
381
372
    else
382
373
    {
384
375
      (*tables)->current_lock= lock_type;
385
376
    }
386
377
  }
387
 
  DBUG_RETURN(0);
 
378
  return(0);
388
379
}
389
380
 
390
381
 
391
382
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
392
383
{
393
 
  DBUG_ENTER("mysql_unlock_tables");
394
384
  if (sql_lock->lock_count)
395
385
    thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
396
386
  if (sql_lock->table_count)
397
387
    VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
398
388
  my_free((uchar*) sql_lock,MYF(0));
399
 
  DBUG_VOID_RETURN;
 
389
  return;
400
390
}
401
391
 
402
392
/**
422
412
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
423
413
{
424
414
  uint i,found;
425
 
  DBUG_ENTER("mysql_unlock_read_tables");
426
415
 
427
416
  /* Move all write locks first */
428
417
  THR_LOCK_DATA **lock=sql_lock->locks;
447
436
  TABLE **table=sql_lock->table;
448
437
  for (i=found=0 ; i < sql_lock->table_count ; i++)
449
438
  {
450
 
    DBUG_ASSERT(sql_lock->table[i]->lock_position == i);
 
439
    assert(sql_lock->table[i]->lock_position == i);
451
440
    if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
452
441
    {
453
442
      swap_variables(TABLE *, *table, sql_lock->table[i]);
472
461
    found+= tbl->lock_count;
473
462
    table++;
474
463
  }
475
 
  DBUG_VOID_RETURN;
 
464
  return;
476
465
}
477
466
 
478
467
 
499
488
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
500
489
                       bool always_unlock)
501
490
{
502
 
  if (always_unlock == TRUE)
 
491
  if (always_unlock == true)
503
492
    mysql_unlock_some_tables(thd, &table, /* table count */ 1);
504
493
  if (locked)
505
494
  {
512
501
        TABLE *tbl;
513
502
        uint lock_data_end;
514
503
 
515
 
        DBUG_ASSERT(table->lock_position == i);
 
504
        assert(table->lock_position == i);
516
505
 
517
506
        /* Unlock if not yet unlocked */
518
 
        if (always_unlock == FALSE)
 
507
        if (always_unlock == false)
519
508
          mysql_unlock_some_tables(thd, &table, /* table count */ 1);
520
509
 
521
510
        /* Decrement table_count in advance, making below expressions easier */
548
537
        {
549
538
          tbl= locked->table[j];
550
539
          tbl->lock_position--;
551
 
          DBUG_ASSERT(tbl->lock_position == j);
 
540
          assert(tbl->lock_position == j);
552
541
          tbl->lock_data_start-= removed_locks;
553
542
        }
554
543
 
583
572
{
584
573
  MYSQL_LOCK *locked;
585
574
  TABLE *write_lock_used;
586
 
  DBUG_ENTER("mysql_lock_abort");
587
575
 
588
576
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
589
577
                             &write_lock_used)))
592
580
      thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
593
581
    my_free((uchar*) locked,MYF(0));
594
582
  }
595
 
  DBUG_VOID_RETURN;
 
583
  return;
596
584
}
597
585
 
598
586
 
612
600
{
613
601
  MYSQL_LOCK *locked;
614
602
  TABLE *write_lock_used;
615
 
  bool result= FALSE;
616
 
  DBUG_ENTER("mysql_lock_abort_for_thread");
 
603
  bool result= false;
617
604
 
618
605
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
619
606
                             &write_lock_used)))
622
609
    {
623
610
      if (thr_abort_locks_for_thread(locked->locks[i]->lock,
624
611
                                     table->in_use->thread_id))
625
 
        result= TRUE;
 
612
        result= true;
626
613
    }
627
614
    my_free((uchar*) locked,MYF(0));
628
615
  }
629
 
  DBUG_RETURN(result);
 
616
  return(result);
630
617
}
631
618
 
632
619
 
634
621
{
635
622
  MYSQL_LOCK *sql_lock;
636
623
  TABLE **table, **end_table;
637
 
  DBUG_ENTER("mysql_lock_merge");
638
624
 
639
625
  if (!(sql_lock= (MYSQL_LOCK*)
640
626
        my_malloc(sizeof(*sql_lock)+
641
627
                  sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
642
628
                  sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
643
 
    DBUG_RETURN(0);                             // Fatal error
 
629
    return(0);                          // Fatal error
644
630
  sql_lock->lock_count=a->lock_count+b->lock_count;
645
631
  sql_lock->table_count=a->table_count+b->table_count;
646
632
  sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
668
654
  /* Delete old, not needed locks */
669
655
  my_free((uchar*) a,MYF(0));
670
656
  my_free((uchar*) b,MYF(0));
671
 
  DBUG_RETURN(sql_lock);
 
657
  return(sql_lock);
672
658
}
673
659
 
674
660
 
707
693
  THR_LOCK_DATA         **end_data;
708
694
  THR_LOCK_DATA         **lock_data2;
709
695
  THR_LOCK_DATA         **end_data2;
710
 
  DBUG_ENTER("mysql_lock_have_duplicate");
711
696
 
712
697
  /*
713
698
    Table may not be defined for derived or view tables.
732
717
  lock_tables= mylock->table;
733
718
 
734
719
  /* Prepare table related variables that don't change in loop. */
735
 
  DBUG_ASSERT((table->lock_position < mylock->table_count) &&
 
720
  assert((table->lock_position < mylock->table_count) &&
736
721
              (table == lock_tables[table->lock_position]));
737
722
  table_lock_data= lock_locks + table->lock_data_start;
738
723
  end_data= table_lock_data + table->lock_count;
746
731
      continue;
747
732
 
748
733
    /* All tables in list must be in lock. */
749
 
    DBUG_ASSERT((table2->lock_position < mylock->table_count) &&
 
734
    assert((table2->lock_position < mylock->table_count) &&
750
735
                (table2 == lock_tables[table2->lock_position]));
751
736
 
752
737
    for (lock_data2=  lock_locks + table2->lock_data_start,
763
748
      {
764
749
        if ((*lock_data)->lock == lock2)
765
750
        {
766
 
          DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
767
 
          DBUG_RETURN(haystack);
 
751
          return(haystack);
768
752
        }
769
753
      }
770
754
    }
771
755
  }
772
756
 
773
757
 end:
774
 
  DBUG_PRINT("info", ("no duplicate found"));
775
 
  DBUG_RETURN(NULL);
 
758
  return(NULL);
776
759
}
777
760
 
778
761
 
781
764
static int unlock_external(THD *thd, TABLE **table,uint count)
782
765
{
783
766
  int error,error_code;
784
 
  DBUG_ENTER("unlock_external");
785
767
 
786
768
  error_code=0;
787
769
  do
797
779
    }
798
780
    table++;
799
781
  } while (--count);
800
 
  DBUG_RETURN(error_code);
 
782
  return(error_code);
801
783
}
802
784
 
803
785
 
819
801
  MYSQL_LOCK *sql_lock;
820
802
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
821
803
  TABLE **to, **table_buf;
822
 
  DBUG_ENTER("get_lock_data");
823
 
 
824
 
  DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
825
 
 
826
 
  DBUG_PRINT("info", ("count %d", count));
 
804
 
 
805
  assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
 
806
 
827
807
  *write_lock_used=0;
828
808
  for (i=tables=lock_count=0 ; i < count ; i++)
829
809
  {
847
827
                  sizeof(THR_LOCK_DATA*) * tables * 2 +
848
828
                  sizeof(table_ptr) * lock_count,
849
829
                  MYF(0))))
850
 
    DBUG_RETURN(0);
 
830
    return(0);
851
831
  locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
852
832
  to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
853
833
  sql_lock->table_count=lock_count;
860
840
    if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
861
841
      continue;
862
842
    lock_type= table->reginfo.lock_type;
863
 
    DBUG_ASSERT (lock_type != TL_WRITE_DEFAULT);
 
843
    assert (lock_type != TL_WRITE_DEFAULT);
864
844
    if (lock_type >= TL_WRITE_ALLOW_WRITE)
865
845
    {
866
846
      *write_lock_used=table;
870
850
        /* Clear the lock type of the lock data that are stored already. */
871
851
        sql_lock->lock_count= locks - sql_lock->locks;
872
852
        reset_lock_data_and_free(&sql_lock);
873
 
        DBUG_RETURN(0);
 
853
        return(0);
874
854
      }
875
855
    }
876
856
    THR_LOCK_DATA **org_locks = locks;
904
884
    And in the FLUSH case, the memory is released quickly anyway.
905
885
  */
906
886
  sql_lock->lock_count= locks - locks_buf;
907
 
  DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
908
 
                      sql_lock->table_count, sql_lock->lock_count));
909
 
  DBUG_RETURN(sql_lock);
 
887
  return(sql_lock);
910
888
}
911
889
 
912
890
 
935
913
{
936
914
  int lock_retcode;
937
915
  int error= -1;
938
 
  DBUG_ENTER("lock_and_wait_for_table_name");
939
916
 
940
917
  if (wait_if_global_read_lock(thd, 0, 1))
941
 
    DBUG_RETURN(1);
 
918
    return(1);
942
919
  VOID(pthread_mutex_lock(&LOCK_open));
943
 
  if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0)
 
920
  if ((lock_retcode = lock_table_name(thd, table_list, true)) < 0)
944
921
    goto end;
945
922
  if (lock_retcode && wait_for_locked_table_names(thd, table_list))
946
923
  {
952
929
end:
953
930
  pthread_mutex_unlock(&LOCK_open);
954
931
  start_waiting_global_read_lock(thd);
955
 
  DBUG_RETURN(error);
 
932
  return(error);
956
933
}
957
934
 
958
935
 
989
966
  char  key[MAX_DBKEY_LENGTH];
990
967
  char *db= table_list->db;
991
968
  uint  key_length;
992
 
  bool  found_locked_table= FALSE;
 
969
  bool  found_locked_table= false;
993
970
  HASH_SEARCH_STATE state;
994
 
  DBUG_ENTER("lock_table_name");
995
 
  DBUG_PRINT("enter",("db: %s  name: %s", db, table_list->table_name));
996
971
 
997
972
  key_length= create_table_def_key(thd, key, table_list, 0);
998
973
 
1008
983
      if (table->reginfo.lock_type < TL_WRITE)
1009
984
      {
1010
985
        if (table->in_use == thd)
1011
 
          found_locked_table= TRUE;
 
986
          found_locked_table= true;
1012
987
        continue;
1013
988
      }
1014
989
 
1015
990
      if (table->in_use == thd)
1016
991
      {
1017
 
        DBUG_PRINT("info", ("Table is in use"));
1018
992
        table->s->version= 0;                  // Ensure no one can use this
1019
993
        table->locked_by_name= 1;
1020
 
        DBUG_RETURN(0);
 
994
        return(0);
1021
995
      }
1022
996
    }
1023
997
  }
1030
1004
    else
1031
1005
      my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
1032
1006
 
1033
 
    DBUG_RETURN(-1);
 
1007
    return(-1);
1034
1008
  }
1035
1009
 
1036
1010
  if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
1037
 
    DBUG_RETURN(-1);
 
1011
    return(-1);
1038
1012
 
1039
1013
  table_list->table=table;
1040
1014
 
1041
1015
  /* Return 1 if table is in use */
1042
 
  DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
 
1016
  return(test(remove_table_from_cache(thd, db, table_list->table_name,
1043
1017
             check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
1044
1018
}
1045
1019
 
1079
1053
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
1080
1054
{
1081
1055
  bool result=0;
1082
 
  DBUG_ENTER("wait_for_locked_table_names");
1083
1056
 
1084
1057
  safe_mutex_assert_owner(&LOCK_open);
1085
1058
 
1093
1066
    wait_for_condition(thd, &LOCK_open, &COND_refresh);
1094
1067
    pthread_mutex_lock(&LOCK_open);
1095
1068
  }
1096
 
  DBUG_RETURN(result);
 
1069
  return(result);
1097
1070
}
1098
1071
 
1099
1072
 
1124
1097
  for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1125
1098
  {
1126
1099
    int got_lock;
1127
 
    if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0)
 
1100
    if ((got_lock=lock_table_name(thd,lock_table, true)) < 0)
1128
1101
      goto end;                                 // Fatal error
1129
1102
    if (got_lock)
1130
1103
      got_all_locks=0;                          // Someone is using table
1163
1136
bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
1164
1137
{
1165
1138
  if (lock_table_names(thd, table_list))
1166
 
    return TRUE;
 
1139
    return true;
1167
1140
 
1168
1141
  /*
1169
1142
    Upgrade the table name locks from semi-exclusive to exclusive locks.
1173
1146
    if (table->table)
1174
1147
      table->table->open_placeholder= 1;
1175
1148
  }
1176
 
  return FALSE;
 
1149
  return false;
1177
1150
}
1178
1151
 
1179
1152
 
1234
1207
    if (table->in_use == thd &&
1235
1208
        table->open_placeholder == 1 &&
1236
1209
        table->s->version == 0)
1237
 
      return TRUE;
 
1210
      return true;
1238
1211
  }
1239
1212
 
1240
 
  return FALSE;
 
1213
  return false;
1241
1214
}
1242
1215
 
1243
1216
/**
1267
1240
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
1268
1241
                        TABLE_LIST *last_table)
1269
1242
{
1270
 
  DBUG_ENTER("unlock_table_names");
1271
1243
  for (TABLE_LIST *table= table_list;
1272
1244
       table != last_table;
1273
1245
       table= table->next_local)
1274
1246
    unlock_table_name(thd,table);
1275
1247
  broadcast_refresh();
1276
 
  DBUG_VOID_RETURN;
 
1248
  return;
1277
1249
}
1278
1250
 
1279
1251
 
1280
1252
static void print_lock_error(int error, const char *table)
1281
1253
{
1282
1254
  int textno;
1283
 
  DBUG_ENTER("print_lock_error");
1284
1255
 
1285
1256
  switch (error) {
1286
1257
  case HA_ERR_LOCK_WAIT_TIMEOUT:
1305
1276
  else
1306
1277
    my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error);
1307
1278
 
1308
 
  DBUG_VOID_RETURN;
 
1279
  return;
1309
1280
}
1310
1281
 
1311
1282
 
1394
1365
 
1395
1366
bool lock_global_read_lock(THD *thd)
1396
1367
{
1397
 
  DBUG_ENTER("lock_global_read_lock");
1398
 
 
1399
1368
  if (!thd->global_read_lock)
1400
1369
  {
1401
1370
    const char *old_message;
1402
1371
    (void) pthread_mutex_lock(&LOCK_global_read_lock);
1403
1372
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1404
1373
                                "Waiting to get readlock");
1405
 
    DBUG_PRINT("info",
1406
 
               ("waiting_for: %d  protect_against: %d",
1407
 
                waiting_for_read_lock, protect_against_global_read_lock));
1408
1374
 
1409
1375
    waiting_for_read_lock++;
1410
1376
    while (protect_against_global_read_lock && !thd->killed)
1413
1379
    if (thd->killed)
1414
1380
    {
1415
1381
      thd->exit_cond(old_message);
1416
 
      DBUG_RETURN(1);
 
1382
      return(1);
1417
1383
    }
1418
1384
    thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
1419
1385
    global_read_lock++;
1427
1393
    forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
1428
1394
    UPDATE and one does FLUSH TABLES WITH READ LOCK).
1429
1395
  */
1430
 
  DBUG_RETURN(0);
 
1396
  return(0);
1431
1397
}
1432
1398
 
1433
1399
 
1434
1400
void unlock_global_read_lock(THD *thd)
1435
1401
{
1436
1402
  uint tmp;
1437
 
  DBUG_ENTER("unlock_global_read_lock");
1438
 
  DBUG_PRINT("info",
1439
 
             ("global_read_lock: %u  global_read_lock_blocks_commit: %u",
1440
 
              global_read_lock, global_read_lock_blocks_commit));
1441
1403
 
1442
1404
  pthread_mutex_lock(&LOCK_global_read_lock);
1443
1405
  tmp= --global_read_lock;
1447
1409
  /* Send the signal outside the mutex to avoid a context switch */
1448
1410
  if (!tmp)
1449
1411
  {
1450
 
    DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
1451
1412
    pthread_cond_broadcast(&COND_global_read_lock);
1452
1413
  }
1453
1414
  thd->global_read_lock= 0;
1454
1415
 
1455
 
  DBUG_VOID_RETURN;
 
1416
  return;
1456
1417
}
1457
1418
 
1458
1419
#define must_wait (global_read_lock &&                             \
1464
1425
{
1465
1426
  const char *old_message= NULL;
1466
1427
  bool result= 0, need_exit_cond;
1467
 
  DBUG_ENTER("wait_if_global_read_lock");
1468
1428
 
1469
1429
  /*
1470
1430
    Assert that we do not own LOCK_open. If we would own it, other
1487
1447
        This allowance is needed to not break existing versions of innobackup
1488
1448
        which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT.
1489
1449
      */
1490
 
      DBUG_RETURN(is_not_commit);
 
1450
      return(is_not_commit);
1491
1451
    }
1492
1452
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1493
1453
                                "Waiting for release of readlock");
1494
1454
    while (must_wait && ! thd->killed &&
1495
1455
           (!abort_on_refresh || thd->version == refresh_version))
1496
1456
    {
1497
 
      DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
1498
1457
      (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1499
 
      DBUG_PRINT("signal", ("Got COND_global_read_lock"));
1500
1458
    }
1501
1459
    if (thd->killed)
1502
1460
      result=1;
1511
1469
    thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1512
1470
  else
1513
1471
    pthread_mutex_unlock(&LOCK_global_read_lock);
1514
 
  DBUG_RETURN(result);
 
1472
  return(result);
1515
1473
}
1516
1474
 
1517
1475
 
1518
1476
void start_waiting_global_read_lock(THD *thd)
1519
1477
{
1520
1478
  bool tmp;
1521
 
  DBUG_ENTER("start_waiting_global_read_lock");
1522
1479
  if (unlikely(thd->global_read_lock))
1523
 
    DBUG_VOID_RETURN;
 
1480
    return;
1524
1481
  (void) pthread_mutex_lock(&LOCK_global_read_lock);
1525
1482
  tmp= (!--protect_against_global_read_lock &&
1526
1483
        (waiting_for_read_lock || global_read_lock_blocks_commit));
1527
1484
  (void) pthread_mutex_unlock(&LOCK_global_read_lock);
1528
1485
  if (tmp)
1529
1486
    pthread_cond_broadcast(&COND_global_read_lock);
1530
 
  DBUG_VOID_RETURN;
 
1487
  return;
1531
1488
}
1532
1489
 
1533
1490
 
1535
1492
{
1536
1493
  bool error;
1537
1494
  const char *old_message;
1538
 
  DBUG_ENTER("make_global_read_lock_block_commit");
1539
1495
  /*
1540
1496
    If we didn't succeed lock_global_read_lock(), or if we already suceeded
1541
1497
    make_global_read_lock_block_commit(), do nothing.
1542
1498
  */
1543
1499
  if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
1544
 
    DBUG_RETURN(0);
 
1500
    return(0);
1545
1501
  pthread_mutex_lock(&LOCK_global_read_lock);
1546
1502
  /* increment this BEFORE waiting on cond (otherwise race cond) */
1547
1503
  global_read_lock_blocks_commit++;
1548
1504
  /* For testing we set up some blocking, to see if we can be killed */
1549
 
  DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
1550
 
                  protect_against_global_read_lock++;);
 
1505
  protect_against_global_read_lock++;
1551
1506
  old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1552
1507
                               "Waiting for all running commits to finish");
1553
1508
  while (protect_against_global_read_lock && !thd->killed)
1554
1509
    pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1555
 
  DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
1556
 
                  protect_against_global_read_lock--;);
 
1510
  protect_against_global_read_lock--;
1557
1511
  if ((error= test(thd->killed)))
1558
1512
    global_read_lock_blocks_commit--; // undo what we did
1559
1513
  else
1560
1514
    thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1561
1515
  thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1562
 
  DBUG_RETURN(error);
 
1516
  return(error);
1563
1517
}
1564
1518
 
1565
1519
 
1612
1566
  uint          dummy_counter;
1613
1567
  int           error;
1614
1568
  int           result= 0;
1615
 
  DBUG_ENTER("try_transactional_lock");
1616
1569
 
1617
1570
  /* Need to open the tables to be able to access engine methods. */
1618
1571
  if (open_tables(thd, &table_list, &dummy_counter, 0))
1619
1572
  {
1620
1573
    /* purecov: begin tested */
1621
 
    DBUG_PRINT("lock_info", ("aborting, open_tables failed"));
1622
 
    DBUG_RETURN(-1);
 
1574
    return(-1);
1623
1575
    /* purecov: end */
1624
1576
  }
1625
1577
 
1626
1578
  /* Required by InnoDB. */
1627
 
  thd->in_lock_tables= TRUE;
 
1579
  thd->in_lock_tables= true;
1628
1580
 
1629
 
  if ((error= set_handler_table_locks(thd, table_list, TRUE)))
 
1581
  if ((error= set_handler_table_locks(thd, table_list, true)))
1630
1582
  {
1631
1583
    /*
1632
1584
      Not all transactional locks could be taken. If the error was
1635
1587
    */
1636
1588
    if (error != HA_ERR_WRONG_COMMAND)
1637
1589
    {
1638
 
      DBUG_PRINT("lock_info", ("aborting, lock_table failed"));
1639
1590
      result= -1;
1640
1591
      goto err;
1641
1592
    }
1645
1596
      successfully taken transactional locks. They go away at end of
1646
1597
      transaction anyway.
1647
1598
    */
1648
 
    DBUG_PRINT("lock_info", ("fall back to non-trans lock: no SE support"));
1649
1599
    result= 1;
1650
1600
  }
1651
1601
 
1654
1604
  (void) ha_autocommit_or_rollback(thd, 0);
1655
1605
  /* Close the tables. The locks (if taken) persist in the storage engines. */
1656
1606
  close_tables_for_reopen(thd, &table_list);
1657
 
  thd->in_lock_tables= FALSE;
1658
 
  DBUG_PRINT("lock_info", ("result: %d", result));
1659
 
  DBUG_RETURN(result);
 
1607
  thd->in_lock_tables= false;
 
1608
  return(result);
1660
1609
}
1661
1610
 
1662
1611
 
1690
1639
  TABLE_LIST    *tlist;
1691
1640
  int           result= 0;
1692
1641
  char          warn_buff[MYSQL_ERRMSG_SIZE];
1693
 
  DBUG_ENTER("check_transactional_lock");
1694
1642
 
1695
1643
  for (tlist= table_list; tlist; tlist= tlist->next_global)
1696
1644
  {
1697
 
    DBUG_PRINT("lock_info", ("checking table: '%s'", tlist->table_name));
1698
1645
 
1699
1646
    /*
1700
1647
      Unfortunately we cannot use tlist->placeholder() here. This method
1704
1651
    */
1705
1652
    if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1706
1653
    {
1707
 
      DBUG_PRINT("lock_info", ("skipping placeholder: %d  transactional: %d",
1708
 
                               tlist->placeholder(),
1709
 
                               tlist->lock_transactional));
1710
1654
      continue;
1711
1655
    }
1712
1656
 
1734
1678
                 ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1735
1679
  }
1736
1680
 
1737
 
  DBUG_PRINT("lock_info", ("result: %d", result));
1738
 
  DBUG_RETURN(result);
 
1681
  return(result);
1739
1682
}
1740
1683
 
1741
1684
 
1758
1701
{
1759
1702
  TABLE_LIST    *tlist;
1760
1703
  int           error= 0;
1761
 
  DBUG_ENTER("set_handler_table_locks");
1762
 
  DBUG_PRINT("lock_info", ("transactional: %d", transactional));
1763
1704
 
1764
1705
  for (tlist= table_list; tlist; tlist= tlist->next_global)
1765
1706
  {
1769
1710
    if (tlist->placeholder())
1770
1711
      continue;
1771
1712
 
1772
 
    DBUG_ASSERT((tlist->lock_type == TL_READ) ||
 
1713
    assert((tlist->lock_type == TL_READ) ||
1773
1714
                (tlist->lock_type == TL_READ_NO_INSERT) ||
1774
1715
                (tlist->lock_type == TL_WRITE_DEFAULT) ||
1775
1716
                (tlist->lock_type == TL_WRITE) ||
1792
1733
        Non-transactional locks do not support a lock_timeout.
1793
1734
      */
1794
1735
      lock_timeout= tlist->top_table()->lock_timeout;
1795
 
      DBUG_PRINT("lock_info",
1796
 
                 ("table: '%s'  tlist==top_table: %d  lock_timeout: %d",
1797
 
                  tlist->table_name, tlist==tlist->top_table(), lock_timeout));
1798
1736
 
1799
1737
      /*
1800
1738
        For warning/error reporting we need to set the intended lock
1805
1743
        called if non-transactional locking was requested for any
1806
1744
        object.
1807
1745
      */
1808
 
      tlist->lock_transactional= TRUE;
 
1746
      tlist->lock_transactional= true;
1809
1747
    }
1810
1748
 
1811
1749
    /*
1823
1761
    }
1824
1762
  }
1825
1763
 
1826
 
  DBUG_RETURN(error);
 
1764
  return(error);
1827
1765
}
1828
1766
 
1829
1767