~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/lock.cc

  • Committer: Brian Aker
  • Date: 2009-06-04 00:43:09 UTC
  • mfrom: (1046.1.7 merge)
  • Revision ID: brian@gaz-20090604004309-mwem4f1a8v1ma2k1
Additional Style cleanup (small merge to resolve code in my branch).

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
 
88
88
extern HASH open_cache;
89
89
 
90
 
/* flags for get_lock_data */
91
 
#define GET_LOCK_UNLOCK         1
92
 
#define GET_LOCK_STORE_LOCKS    2
93
 
 
94
90
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table,
95
91
                                   uint32_t count,
96
 
                                   uint32_t flags, Table **write_locked);
 
92
                                   bool should_lock, Table **write_locked);
97
93
static int lock_external(Session *session, Table **table,uint32_t count);
98
94
static int unlock_external(Session *session, Table **table,uint32_t count);
99
95
static void print_lock_error(int error, const char *);
176
172
 
177
173
  for (;;)
178
174
  {
179
 
    if (! (sql_lock= get_lock_data(session, tables, count, GET_LOCK_STORE_LOCKS,
 
175
    if (! (sql_lock= get_lock_data(session, tables, count, true,
180
176
                                   &write_lock_used)))
181
177
      break;
182
178
 
308
304
        (*tables)->file->ha_external_lock(session, F_UNLCK);
309
305
        (*tables)->current_lock=F_UNLCK;
310
306
      }
311
 
      return(error);
 
307
      return error;
312
308
    }
313
309
    else
314
310
    {
316
312
      (*tables)->current_lock= lock_type;
317
313
    }
318
314
  }
319
 
  return(0);
 
315
  return 0;
320
316
}
321
317
 
322
318
 
340
336
{
341
337
  DRIZZLE_LOCK *sql_lock;
342
338
  Table *write_lock_used;
343
 
  if ((sql_lock= get_lock_data(session, table, count, GET_LOCK_UNLOCK,
 
339
  if ((sql_lock= get_lock_data(session, table, count, false,
344
340
                               &write_lock_used)))
345
341
    mysql_unlock_tables(session, sql_lock);
346
342
}
497
493
  DRIZZLE_LOCK *locked;
498
494
  Table *write_lock_used;
499
495
 
500
 
  if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
 
496
  if ((locked= get_lock_data(session, &table, 1, false,
501
497
                             &write_lock_used)))
502
498
  {
503
499
    for (uint32_t i=0; i < locked->lock_count; i++)
525
521
  Table *write_lock_used;
526
522
  bool result= false;
527
523
 
528
 
  if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
 
524
  if ((locked= get_lock_data(session, &table, 1, false,
529
525
                             &write_lock_used)))
530
526
  {
531
527
    for (uint32_t i=0; i < locked->lock_count; i++)
536
532
    }
537
533
    free((unsigned char*) locked);
538
534
  }
539
 
  return(result);
 
535
  return result;
540
536
}
541
537
 
542
538
 
549
545
        malloc(sizeof(*sql_lock)+
550
546
               sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
551
547
               sizeof(Table*)*(a->table_count+b->table_count))))
552
 
    return(0);                          // Fatal error
 
548
    return NULL;                                // Fatal error
553
549
  sql_lock->lock_count=a->lock_count+b->lock_count;
554
550
  sql_lock->table_count=a->table_count+b->table_count;
555
551
  sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
577
573
  /* Delete old, not needed locks */
578
574
  free((unsigned char*) a);
579
575
  free((unsigned char*) b);
580
 
  return(sql_lock);
 
576
 
 
577
  return sql_lock;
581
578
}
582
579
 
583
580
 
670
667
           lock_data++)
671
668
      {
672
669
        if ((*lock_data)->lock == lock2)
673
 
        {
674
 
          return(haystack);
675
 
        }
 
670
          return haystack;
676
671
      }
677
672
    }
678
673
  }
702
697
    }
703
698
    table++;
704
699
  } while (--count);
705
 
  return(error_code);
 
700
  return error_code;
706
701
}
707
702
 
708
703
 
711
706
 
712
707
  @param session                    Thread handler
713
708
  @param table_ptr          Pointer to tables that should be locks
714
 
  @param flags              One of:
715
 
           - GET_LOCK_UNLOCK      : If we should send TL_IGNORE to store lock
716
 
           - GET_LOCK_STORE_LOCKS : Store lock info in Table
 
709
  @param should_lock                One of:
 
710
           - false      : If we should send TL_IGNORE to store lock
 
711
           - true       : Store lock info in Table
717
712
  @param write_lock_used   Store pointer to last table with WRITE_ALLOW_WRITE
718
713
*/
719
714
 
720
715
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table_ptr, uint32_t count,
721
 
                                 uint32_t flags, Table **write_lock_used)
 
716
                                 bool should_lock, Table **write_lock_used)
722
717
{
723
718
  uint32_t i,tables,lock_count;
724
719
  DRIZZLE_LOCK *sql_lock;
725
720
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
726
721
  Table **to, **table_buf;
727
722
 
728
 
  assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
729
 
 
730
723
  *write_lock_used=0;
731
 
  for (i=tables=lock_count=0 ; i < count ; i++)
 
724
  for (i= tables= lock_count= 0 ; i < count ; i++)
732
725
  {
733
726
    Table *t= table_ptr[i];
734
727
 
749
742
        malloc(sizeof(*sql_lock) +
750
743
               sizeof(THR_LOCK_DATA*) * tables * 2 +
751
744
               sizeof(table_ptr) * lock_count)))
752
 
    return(0);
 
745
    return NULL;
753
746
  locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
754
747
  to= table_buf= sql_lock->table= (Table**) (locks + tables * 2);
755
 
  sql_lock->table_count=lock_count;
 
748
  sql_lock->table_count= lock_count;
756
749
 
757
750
  for (i=0 ; i < count ; i++)
758
751
  {
772
765
        /* Clear the lock type of the lock data that are stored already. */
773
766
        sql_lock->lock_count= locks - sql_lock->locks;
774
767
        reset_lock_data_and_free(&sql_lock);
775
 
        return(0);
 
768
        return NULL;
776
769
      }
777
770
    }
778
771
    locks_start= locks;
779
772
    locks= table->file->store_lock(session, locks,
780
 
                                   (flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
781
 
                                   lock_type);
782
 
    if (flags & GET_LOCK_STORE_LOCKS)
 
773
                                   should_lock == false ? TL_IGNORE : lock_type);
 
774
    if (should_lock)
783
775
    {
784
776
      table->lock_position=   (uint32_t) (to - table_buf);
785
777
      table->lock_data_start= (uint32_t) (locks_start - locks_buf);
786
778
      table->lock_count=      (uint32_t) (locks - locks_start);
 
779
      assert(table->lock_count == 1);
 
780
      printf(" LOCK POSITION %u\n", table->lock_position);
 
781
      printf(" LOCK DATA START %u\n", table->lock_data_start);
787
782
    }
788
783
    *to++= table;
789
784
  }
802
797
    And in the FLUSH case, the memory is released quickly anyway.
803
798
  */
804
799
  sql_lock->lock_count= locks - locks_buf;
805
 
  return(sql_lock);
 
800
 
 
801
  return sql_lock;
806
802
}
807
803
 
808
804
 
833
829
  int error= -1;
834
830
 
835
831
  if (wait_if_global_read_lock(session, 0, 1))
836
 
    return(1);
 
832
    return 1;
837
833
  pthread_mutex_lock(&LOCK_open); /* lock and wait for table when we need total access to table */
838
834
  if ((lock_retcode = lock_table_name(session, table_list, true)) < 0)
839
835
    goto end;
847
843
end:
848
844
  pthread_mutex_unlock(&LOCK_open);
849
845
  start_waiting_global_read_lock(session);
850
 
  return(error);
 
846
  return error;
851
847
}
852
848
 
853
849
 
909
905
      {
910
906
        table->s->version= 0;                  // Ensure no one can use this
911
907
        table->locked_by_name= 1;
912
 
        return(0);
 
908
        return 0;
913
909
      }
914
910
    }
915
911
  }
922
918
    else
923
919
      my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
924
920
 
925
 
    return(-1);
 
921
    return -1;
926
922
  }
927
923
 
928
924
  if (!(table= table_cache_insert_placeholder(session, key, key_length)))
929
 
    return(-1);
 
925
    return -1;
930
926
 
931
927
  table_list->table=table;
932
928
 
968
964
 
969
965
bool wait_for_locked_table_names(Session *session, TableList *table_list)
970
966
{
971
 
  bool result=0;
 
967
  bool result= false;
972
968
 
973
969
  safe_mutex_assert_owner(&LOCK_open);
974
970
 
982
978
    wait_for_condition(session, &LOCK_open, &COND_refresh);
983
979
    pthread_mutex_lock(&LOCK_open); /* Wait for a table to unlock and then lock it */
984
980
  }
985
 
  return(result);
 
981
  return result;
986
982
}
987
983
 
988
984
 
1187
1183
    my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), table);
1188
1184
  else
1189
1185
    my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error);
1190
 
 
1191
 
  return;
1192
1186
}
1193
1187
 
1194
1188
 
1291
1285
    if (session->killed)
1292
1286
    {
1293
1287
      session->exit_cond(old_message);
1294
 
      return(1);
 
1288
      return true;
1295
1289
    }
1296
1290
    session->global_read_lock= GOT_GLOBAL_READ_LOCK;
1297
1291
    global_read_lock++;
1305
1299
    forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
1306
1300
    UPDATE and one does FLUSH TABLES WITH READ LOCK).
1307
1301
  */
1308
 
  return(0);
 
1302
  return false;
1309
1303
}
1310
1304
 
1311
1305
 
1324
1318
    pthread_cond_broadcast(&COND_global_read_lock);
1325
1319
  }
1326
1320
  session->global_read_lock= 0;
1327
 
 
1328
 
  return;
1329
1321
}
1330
1322
 
1331
1323
#define must_wait (global_read_lock &&                             \
1359
1351
        This allowance is needed to not break existing versions of innobackup
1360
1352
        which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT.
1361
1353
      */
1362
 
      return(is_not_commit);
 
1354
      return is_not_commit;
1363
1355
    }
1364
1356
    old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1365
1357
                                "Waiting for release of readlock");
1381
1373
    session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1382
1374
  else
1383
1375
    pthread_mutex_unlock(&LOCK_global_read_lock);
1384
 
  return(result);
 
1376
  return result;
1385
1377
}
1386
1378
 
1387
1379
 
1409
1401
    make_global_read_lock_block_commit(), do nothing.
1410
1402
  */
1411
1403
  if (session->global_read_lock != GOT_GLOBAL_READ_LOCK)
1412
 
    return(0);
 
1404
    return false;
1413
1405
  pthread_mutex_lock(&LOCK_global_read_lock);
1414
1406
  /* increment this BEFORE waiting on cond (otherwise race cond) */
1415
1407
  global_read_lock_blocks_commit++;
1422
1414
  else
1423
1415
    session->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1424
1416
  session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1425
 
  return(error);
 
1417
  return error;
1426
1418
}
1427
1419
 
1428
1420
 
1480
1472
  if (open_tables(session, &table_list, &dummy_counter, 0))
1481
1473
  {
1482
1474
    /* purecov: begin tested */
1483
 
    return(-1);
 
1475
    return -1;
1484
1476
    /* purecov: end */
1485
1477
  }
1486
1478
 
1514
1506
  /* Close the tables. The locks (if taken) persist in the storage engines. */
1515
1507
  close_tables_for_reopen(session, &table_list);
1516
1508
  session->in_lock_tables= false;
1517
 
  return(result);
 
1509
 
 
1510
  return result;
1518
1511
}
1519
1512
 
1520
1513
 
1572
1565
 
1573
1566
  }
1574
1567
 
1575
 
  return(result);
 
1568
  return result;
1576
1569
}
1577
1570
 
1578
1571
 
1654
1647
    }
1655
1648
  }
1656
1649
 
1657
 
  return(error);
 
1650
  return error;
1658
1651
}
1659
1652
 
1660
1653