~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/lock.cc

  • Committer: Brian Aker
  • Date: 2008-07-14 22:40:46 UTC
  • Revision ID: brian@tangent.org-20080714224046-x183907w9wp1txwv
Removed sql_manager. Ever heard of just setting up the OS to sync when you
want it to?

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
 
48
48
  When using LOCK TABLES:
49
49
 
50
 
  - LOCK Table will call mysql_lock_tables() for all tables.
 
50
  - LOCK TABLE will call mysql_lock_tables() for all tables.
51
51
    mysql_lock_tables() will call
52
52
    table_handler->external_lock(thd,locktype) for each table.
53
53
    This is followed by a call to thr_multi_lock() for all tables.
72
72
  Change to use my_malloc() ONLY when using LOCK TABLES command or when
73
73
  we are forced to use mysql_lock_merge.
74
74
*/
75
 
#include <drizzled/server_includes.h>
76
 
#include <drizzled/drizzled_error_messages.h>
 
75
 
 
76
#include "mysql_priv.h"
 
77
#include <hash.h>
 
78
#include <assert.h>
77
79
 
78
80
/**
79
81
  @defgroup Locking Locking
86
88
#define GET_LOCK_UNLOCK         1
87
89
#define GET_LOCK_STORE_LOCKS    2
88
90
 
89
 
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table,uint32_t count,
90
 
                                 uint32_t flags, Table **write_locked);
91
 
static int lock_external(THD *thd, Table **table,uint32_t count);
92
 
static int unlock_external(THD *thd, Table **table,uint32_t count);
 
91
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
 
92
                                 uint flags, TABLE **write_locked);
 
93
static int lock_external(THD *thd, TABLE **table,uint count);
 
94
static int unlock_external(THD *thd, TABLE **table,uint count);
93
95
static void print_lock_error(int error, const char *);
94
96
 
95
97
/*
101
103
    tables                      An array of pointers to the tables to lock.
102
104
    count                       The number of tables to lock.
103
105
    flags                       Options:
104
 
      DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK      Ignore a global read lock
105
 
      DRIZZLE_LOCK_IGNORE_GLOBAL_READ_ONLY      Ignore SET GLOBAL READ_ONLY
106
 
      DRIZZLE_LOCK_IGNORE_FLUSH                 Ignore a flush tables.
107
 
      DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN        Instead of reopening altered
 
106
      MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK      Ignore a global read lock
 
107
      MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY      Ignore SET GLOBAL READ_ONLY
 
108
      MYSQL_LOCK_IGNORE_FLUSH                 Ignore a flush tables.
 
109
      MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN        Instead of reopening altered
108
110
                                              or dropped tables by itself,
109
111
                                              mysql_lock_tables() should
110
112
                                              notify upper level and rely
121
123
static int thr_lock_errno_to_mysql[]=
122
124
{ 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
123
125
 
 
126
/**
 
127
  Perform semantic checks for mysql_lock_tables.
 
128
  @param thd The current thread
 
129
  @param tables The tables to lock
 
130
  @param count The number of tables to lock
 
131
  @param flags Lock flags
 
132
  @return 0 if all the check passed, non zero if a check failed.
 
133
*/
 
134
int mysql_lock_tables_check(THD *thd __attribute__((__unused__)),
 
135
                            TABLE **tables, uint count,
 
136
                            uint flags __attribute__((__unused__)))
 
137
{
 
138
  uint system_count;
 
139
  uint i;
 
140
 
 
141
  system_count= 0;
 
142
 
 
143
  for (i=0 ; i<count; i++)
 
144
  {
 
145
    TABLE *t= tables[i];
 
146
 
 
147
    /* Protect against 'fake' partially initialized TABLE_SHARE */
 
148
    assert(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
 
149
 
 
150
    if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) &&
 
151
        (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE))
 
152
    {
 
153
      system_count++;
 
154
    }
 
155
  }
 
156
 
 
157
  /*
 
158
    Locking of system tables is restricted:
 
159
    locking a mix of system and non-system tables in the same lock
 
160
    is prohibited, to prevent contention.
 
161
  */
 
162
  if ((system_count > 0) && (system_count < count))
 
163
  {
 
164
    my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
 
165
    return(1);
 
166
  }
 
167
 
 
168
  return(0);
 
169
}
 
170
 
124
171
 
125
172
/**
126
173
  Reset lock type in lock data and free.
142
189
        lock request will set its lock type properly.
143
190
*/
144
191
 
145
 
static void reset_lock_data_and_free(DRIZZLE_LOCK **mysql_lock)
 
192
static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
146
193
{
147
 
  DRIZZLE_LOCK *sql_lock= *mysql_lock;
 
194
  MYSQL_LOCK *sql_lock= *mysql_lock;
148
195
  THR_LOCK_DATA **ldata, **ldata_end;
149
196
 
150
197
  /* Clear the lock type of all lock data to avoid reusage. */
155
202
    /* Reset lock type. */
156
203
    (*ldata)->type= TL_UNLOCK;
157
204
  }
158
 
  free((unsigned char*) sql_lock);
 
205
  my_free((uchar*) sql_lock, MYF(0));
159
206
  *mysql_lock= 0;
160
207
}
161
208
 
162
209
 
163
 
DRIZZLE_LOCK *mysql_lock_tables(THD *thd, Table **tables, uint32_t count,
164
 
                              uint32_t flags, bool *need_reopen)
 
210
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
 
211
                              uint flags, bool *need_reopen)
165
212
{
166
 
  DRIZZLE_LOCK *sql_lock;
167
 
  Table *write_lock_used;
 
213
  MYSQL_LOCK *sql_lock;
 
214
  TABLE *write_lock_used;
168
215
  int rc;
169
216
 
170
217
  *need_reopen= false;
171
218
 
 
219
  if (mysql_lock_tables_check(thd, tables, count, flags))
 
220
    return (NULL);
 
221
 
172
222
  for (;;)
173
223
  {
174
224
    if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
176
226
      break;
177
227
 
178
228
    if (global_read_lock && write_lock_used &&
179
 
        ! (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK))
 
229
        ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
180
230
    {
181
231
      /*
182
232
        Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
196
246
      }
197
247
    }
198
248
 
199
 
    if (!(flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
 
249
    if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
200
250
        write_lock_used &&
201
251
        opt_readonly &&
202
252
        !thd->slave_thread)
210
260
      break;
211
261
    }
212
262
 
213
 
    thd->set_proc_info("System lock");
 
263
    thd_proc_info(thd, "System lock");
214
264
    if (sql_lock->table_count && lock_external(thd, sql_lock->table,
215
265
                                               sql_lock->table_count))
216
266
    {
218
268
      reset_lock_data_and_free(&sql_lock);
219
269
      break;
220
270
    }
221
 
    thd->set_proc_info("Table lock");
 
271
    thd_proc_info(thd, "Table lock");
222
272
    /* Copy the lock data array. thr_multi_lock() reorders its contens. */
223
273
    memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
224
274
           sql_lock->lock_count * sizeof(*sql_lock->locks));
230
280
    if (rc > 1)                                 /* a timeout or a deadlock */
231
281
    {
232
282
      if (sql_lock->table_count)
233
 
        unlock_external(thd, sql_lock->table, sql_lock->table_count);
 
283
        VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
234
284
      reset_lock_data_and_free(&sql_lock);
235
285
      my_error(rc, MYF(0));
236
286
      break;
241
291
      sql_lock->lock_count= 0;                  // Locks are already freed
242
292
      // Fall through: unlock, reset lock data, free and retry
243
293
    }
244
 
    else if (!thd->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
 
294
    else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
245
295
    {
246
296
      /*
247
297
        Thread was killed or lock aborted. Let upper level close all
255
305
      thd->some_tables_deleted=0;
256
306
      break;
257
307
    }
258
 
    thd->set_proc_info(0);
 
308
    thd_proc_info(thd, 0);
259
309
 
260
310
    /* going to retry, unlock all tables */
261
311
    if (sql_lock->lock_count)
262
312
        thr_multi_unlock(sql_lock->locks, sql_lock->lock_count);
263
313
 
264
314
    if (sql_lock->table_count)
265
 
      unlock_external(thd, sql_lock->table, sql_lock->table_count);
 
315
      VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
266
316
 
267
317
    /*
268
318
      If thr_multi_lock fails it resets lock type for tables, which
271
321
    */
272
322
    reset_lock_data_and_free(&sql_lock);
273
323
retry:
274
 
    if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN)
 
324
    if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
275
325
    {
276
326
      *need_reopen= true;
277
327
      break;
279
329
    if (wait_for_tables(thd))
280
330
      break;                                    // Couldn't open tables
281
331
  }
282
 
  thd->set_proc_info(0);
 
332
  thd_proc_info(thd, 0);
283
333
  if (thd->killed)
284
334
  {
285
335
    thd->send_kill_message();
295
345
}
296
346
 
297
347
 
298
 
static int lock_external(THD *thd, Table **tables, uint32_t count)
 
348
static int lock_external(THD *thd, TABLE **tables, uint count)
299
349
{
300
 
  register uint32_t i;
 
350
  register uint i;
301
351
  int lock_type,error;
302
352
  for (i=1 ; i <= count ; i++, tables++)
303
353
  {
329
379
}
330
380
 
331
381
 
332
 
void mysql_unlock_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
 
382
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
333
383
{
334
384
  if (sql_lock->lock_count)
335
385
    thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
336
386
  if (sql_lock->table_count)
337
 
    unlock_external(thd,sql_lock->table,sql_lock->table_count);
338
 
  free((unsigned char*) sql_lock);
 
387
    VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
 
388
  my_free((uchar*) sql_lock,MYF(0));
339
389
  return;
340
390
}
341
391
 
345
395
  This will work even if get_lock_data fails (next unlock will free all)
346
396
*/
347
397
 
348
 
void mysql_unlock_some_tables(THD *thd, Table **table,uint32_t count)
 
398
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
349
399
{
350
 
  DRIZZLE_LOCK *sql_lock;
351
 
  Table *write_lock_used;
 
400
  MYSQL_LOCK *sql_lock;
 
401
  TABLE *write_lock_used;
352
402
  if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
353
403
                               &write_lock_used)))
354
404
    mysql_unlock_tables(thd, sql_lock);
359
409
  unlock all tables locked for read.
360
410
*/
361
411
 
362
 
void mysql_unlock_read_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
 
412
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
363
413
{
364
 
  uint32_t i,found;
 
414
  uint i,found;
365
415
 
366
416
  /* Move all write locks first */
367
417
  THR_LOCK_DATA **lock=sql_lock->locks;
369
419
  {
370
420
    if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ)
371
421
    {
372
 
      std::swap(*lock, sql_lock->locks[i]);
 
422
      swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]);
373
423
      lock++;
374
424
      found++;
375
425
    }
383
433
 
384
434
  /* Then do the same for the external locks */
385
435
  /* Move all write locked tables first */
386
 
  Table **table=sql_lock->table;
 
436
  TABLE **table=sql_lock->table;
387
437
  for (i=found=0 ; i < sql_lock->table_count ; i++)
388
438
  {
389
439
    assert(sql_lock->table[i]->lock_position == i);
390
440
    if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
391
441
    {
392
 
      std::swap(*table, sql_lock->table[i]);
 
442
      swap_variables(TABLE *, *table, sql_lock->table[i]);
393
443
      table++;
394
444
      found++;
395
445
    }
397
447
  /* Unlock all read locked tables */
398
448
  if (i != found)
399
449
  {
400
 
    unlock_external(thd,table,i-found);
 
450
    VOID(unlock_external(thd,table,i-found));
401
451
    sql_lock->table_count=found;
402
452
  }
403
 
  /* Fix the lock positions in Table */
 
453
  /* Fix the lock positions in TABLE */
404
454
  table= sql_lock->table;
405
455
  found= 0;
406
456
  for (i= 0; i < sql_lock->table_count; i++)
407
457
  {
408
 
    Table *tbl= *table;
 
458
    TABLE *tbl= *table;
409
459
    tbl->lock_position= table - sql_lock->table;
410
460
    tbl->lock_data_start= found;
411
461
    found+= tbl->lock_count;
435
485
                          effect is desired.
436
486
*/
437
487
 
438
 
void mysql_lock_remove(THD *thd, DRIZZLE_LOCK *locked,Table *table,
 
488
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
439
489
                       bool always_unlock)
440
490
{
441
491
  if (always_unlock == true)
442
492
    mysql_unlock_some_tables(thd, &table, /* table count */ 1);
443
493
  if (locked)
444
494
  {
445
 
    register uint32_t i;
 
495
    register uint i;
446
496
    for (i=0; i < locked->table_count; i++)
447
497
    {
448
498
      if (locked->table[i] == table)
449
499
      {
450
 
        uint32_t  j, removed_locks, old_tables;
451
 
        Table *tbl;
452
 
        uint32_t lock_data_end;
 
500
        uint  j, removed_locks, old_tables;
 
501
        TABLE *tbl;
 
502
        uint lock_data_end;
453
503
 
454
504
        assert(table->lock_position == i);
455
505
 
464
514
        removed_locks= table->lock_count;
465
515
 
466
516
        /* Move down all table pointers above 'i'. */
467
 
        memcpy((locked->table+i), (locked->table+i+1),
468
 
               (old_tables - i) * sizeof(Table*));
 
517
        bmove((char*) (locked->table+i),
 
518
              (char*) (locked->table+i+1),
 
519
              (old_tables - i) * sizeof(TABLE*));
469
520
 
470
521
        lock_data_end= table->lock_data_start + table->lock_count;
471
522
        /* Move down all lock data pointers above 'table->lock_data_end-1' */
472
 
        memcpy((locked->locks + table->lock_data_start),
473
 
               (locked->locks + lock_data_end),
474
 
               (locked->lock_count - lock_data_end) *
475
 
               sizeof(THR_LOCK_DATA*));
 
523
        bmove((char*) (locked->locks + table->lock_data_start),
 
524
              (char*) (locked->locks + lock_data_end),
 
525
              (locked->lock_count - lock_data_end) *
 
526
              sizeof(THR_LOCK_DATA*));
476
527
 
477
528
        /*
478
529
          Fix moved table elements.
500
551
 
501
552
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
502
553
 
503
 
void mysql_lock_downgrade_write(THD *thd, Table *table,
 
554
void mysql_lock_downgrade_write(THD *thd, TABLE *table,
504
555
                                thr_lock_type new_lock_type)
505
556
{
506
 
  DRIZZLE_LOCK *locked;
507
 
  Table *write_lock_used;
 
557
  MYSQL_LOCK *locked;
 
558
  TABLE *write_lock_used;
508
559
  if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
509
560
                              &write_lock_used)))
510
561
  {
511
 
    for (uint32_t i=0; i < locked->lock_count; i++)
 
562
    for (uint i=0; i < locked->lock_count; i++)
512
563
      thr_downgrade_write_lock(locked->locks[i], new_lock_type);
513
 
    free((unsigned char*) locked);
 
564
    my_free((uchar*) locked,MYF(0));
514
565
  }
515
566
}
516
567
 
517
568
 
518
569
/** Abort all other threads waiting to get lock in table. */
519
570
 
520
 
void mysql_lock_abort(THD *thd, Table *table, bool upgrade_lock)
 
571
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
521
572
{
522
 
  DRIZZLE_LOCK *locked;
523
 
  Table *write_lock_used;
 
573
  MYSQL_LOCK *locked;
 
574
  TABLE *write_lock_used;
524
575
 
525
576
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
526
577
                             &write_lock_used)))
527
578
  {
528
 
    for (uint32_t i=0; i < locked->lock_count; i++)
 
579
    for (uint i=0; i < locked->lock_count; i++)
529
580
      thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
530
 
    free((unsigned char*) locked);
 
581
    my_free((uchar*) locked,MYF(0));
531
582
  }
532
583
  return;
533
584
}
545
596
    1  Table was locked by at least one other thread
546
597
*/
547
598
 
548
 
bool mysql_lock_abort_for_thread(THD *thd, Table *table)
 
599
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
549
600
{
550
 
  DRIZZLE_LOCK *locked;
551
 
  Table *write_lock_used;
 
601
  MYSQL_LOCK *locked;
 
602
  TABLE *write_lock_used;
552
603
  bool result= false;
553
604
 
554
605
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
555
606
                             &write_lock_used)))
556
607
  {
557
 
    for (uint32_t i=0; i < locked->lock_count; i++)
 
608
    for (uint i=0; i < locked->lock_count; i++)
558
609
    {
559
610
      if (thr_abort_locks_for_thread(locked->locks[i]->lock,
560
611
                                     table->in_use->thread_id))
561
612
        result= true;
562
613
    }
563
 
    free((unsigned char*) locked);
 
614
    my_free((uchar*) locked,MYF(0));
564
615
  }
565
616
  return(result);
566
617
}
567
618
 
568
619
 
569
 
DRIZZLE_LOCK *mysql_lock_merge(DRIZZLE_LOCK *a,DRIZZLE_LOCK *b)
 
620
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
570
621
{
571
 
  DRIZZLE_LOCK *sql_lock;
572
 
  Table **table, **end_table;
 
622
  MYSQL_LOCK *sql_lock;
 
623
  TABLE **table, **end_table;
573
624
 
574
 
  if (!(sql_lock= (DRIZZLE_LOCK*)
 
625
  if (!(sql_lock= (MYSQL_LOCK*)
575
626
        my_malloc(sizeof(*sql_lock)+
576
627
                  sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
577
 
                  sizeof(Table*)*(a->table_count+b->table_count),MYF(MY_WME))))
 
628
                  sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
578
629
    return(0);                          // Fatal error
579
630
  sql_lock->lock_count=a->lock_count+b->lock_count;
580
631
  sql_lock->table_count=a->table_count+b->table_count;
581
632
  sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
582
 
  sql_lock->table=(Table**) (sql_lock->locks+sql_lock->lock_count);
 
633
  sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
583
634
  memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
584
635
  memcpy(sql_lock->locks+a->lock_count,b->locks,
585
636
         b->lock_count*sizeof(*b->locks));
586
637
  memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
587
638
  memcpy(sql_lock->table+a->table_count,b->table,
588
 
         b->table_count*sizeof(*b->table));
 
639
         b->table_count*sizeof(*b->table));
589
640
 
590
641
  /*
591
642
    Now adjust lock_position and lock_data_start for all objects that was
601
652
  }
602
653
 
603
654
  /* Delete old, not needed locks */
604
 
  free((unsigned char*) a);
605
 
  free((unsigned char*) b);
 
655
  my_free((uchar*) a,MYF(0));
 
656
  my_free((uchar*) b,MYF(0));
606
657
  return(sql_lock);
607
658
}
608
659
 
630
681
    !NULL   First table from 'haystack' that matches a lock on 'needle'.
631
682
*/
632
683
 
633
 
TableList *mysql_lock_have_duplicate(THD *thd, TableList *needle,
634
 
                                      TableList *haystack)
 
684
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
 
685
                                      TABLE_LIST *haystack)
635
686
{
636
 
  DRIZZLE_LOCK            *mylock;
637
 
  Table                 **lock_tables;
638
 
  Table                 *table;
639
 
  Table                 *table2;
 
687
  MYSQL_LOCK            *mylock;
 
688
  TABLE                 **lock_tables;
 
689
  TABLE                 *table;
 
690
  TABLE                 *table2;
640
691
  THR_LOCK_DATA         **lock_locks;
641
692
  THR_LOCK_DATA         **table_lock_data;
642
693
  THR_LOCK_DATA         **end_data;
710
761
 
711
762
/** Unlock a set of external. */
712
763
 
713
 
static int unlock_external(THD *thd, Table **table,uint32_t count)
 
764
static int unlock_external(THD *thd, TABLE **table,uint count)
714
765
{
715
766
  int error,error_code;
716
767
 
739
790
  @param table_ptr          Pointer to tables that should be locks
740
791
  @param flags              One of:
741
792
           - GET_LOCK_UNLOCK      : If we should send TL_IGNORE to store lock
742
 
           - GET_LOCK_STORE_LOCKS : Store lock info in Table
 
793
           - GET_LOCK_STORE_LOCKS : Store lock info in TABLE
743
794
  @param write_lock_used   Store pointer to last table with WRITE_ALLOW_WRITE
744
795
*/
745
796
 
746
 
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table_ptr, uint32_t count,
747
 
                                 uint32_t flags, Table **write_lock_used)
 
797
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
 
798
                                 uint flags, TABLE **write_lock_used)
748
799
{
749
 
  uint32_t i,tables,lock_count;
750
 
  DRIZZLE_LOCK *sql_lock;
 
800
  uint i,tables,lock_count;
 
801
  MYSQL_LOCK *sql_lock;
751
802
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
752
 
  Table **to, **table_buf;
 
803
  TABLE **to, **table_buf;
753
804
 
754
805
  assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
755
806
 
756
807
  *write_lock_used=0;
757
808
  for (i=tables=lock_count=0 ; i < count ; i++)
758
809
  {
759
 
    Table *t= table_ptr[i];
 
810
    TABLE *t= table_ptr[i];
760
811
 
761
812
    if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
762
813
    {
771
822
    update the table values. So the second part of the array is copied
772
823
    from the first part immediately before calling thr_multi_lock().
773
824
  */
774
 
  if (!(sql_lock= (DRIZZLE_LOCK*)
 
825
  if (!(sql_lock= (MYSQL_LOCK*)
775
826
        my_malloc(sizeof(*sql_lock) +
776
827
                  sizeof(THR_LOCK_DATA*) * tables * 2 +
777
828
                  sizeof(table_ptr) * lock_count,
778
829
                  MYF(0))))
779
830
    return(0);
780
831
  locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
781
 
  to= table_buf= sql_lock->table= (Table**) (locks + tables * 2);
 
832
  to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
782
833
  sql_lock->table_count=lock_count;
783
834
 
784
835
  for (i=0 ; i < count ; i++)
785
836
  {
786
 
    Table *table;
 
837
    TABLE *table;
787
838
    enum thr_lock_type lock_type;
788
839
 
789
840
    if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
802
853
        return(0);
803
854
      }
804
855
    }
 
856
    THR_LOCK_DATA **org_locks = locks;
805
857
    locks_start= locks;
806
858
    locks= table->file->store_lock(thd, locks,
807
859
                                   (flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
813
865
      table->lock_count=      (uint) (locks - locks_start);
814
866
    }
815
867
    *to++= table;
 
868
    if (locks)
 
869
      for ( ; org_locks != locks ; org_locks++)
 
870
        (*org_locks)->debug_print_param= (void *) table;
816
871
  }
817
872
  /*
818
873
    We do not use 'tables', because there are cases where store_lock()
854
909
    1   error
855
910
*/
856
911
 
857
 
int lock_and_wait_for_table_name(THD *thd, TableList *table_list)
 
912
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
858
913
{
859
914
  int lock_retcode;
860
915
  int error= -1;
861
916
 
862
917
  if (wait_if_global_read_lock(thd, 0, 1))
863
918
    return(1);
864
 
  pthread_mutex_lock(&LOCK_open);
 
919
  VOID(pthread_mutex_lock(&LOCK_open));
865
920
  if ((lock_retcode = lock_table_name(thd, table_list, true)) < 0)
866
921
    goto end;
867
922
  if (lock_retcode && wait_for_locked_table_names(thd, table_list))
905
960
    > 0  table locked, but someone is using it
906
961
*/
907
962
 
908
 
int lock_table_name(THD *thd, TableList *table_list, bool check_in_use)
 
963
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
909
964
{
910
 
  Table *table;
 
965
  TABLE *table;
911
966
  char  key[MAX_DBKEY_LENGTH];
912
967
  char *db= table_list->db;
913
 
  uint32_t  key_length;
 
968
  uint  key_length;
914
969
  bool  found_locked_table= false;
915
970
  HASH_SEARCH_STATE state;
916
971
 
919
974
  if (check_in_use)
920
975
  {
921
976
    /* Only insert the table if we haven't insert it already */
922
 
    for (table=(Table*) hash_first(&open_cache, (unsigned char*)key,
 
977
    for (table=(TABLE*) hash_first(&open_cache, (uchar*)key,
923
978
                                   key_length, &state);
924
979
         table ;
925
 
         table = (Table*) hash_next(&open_cache,(unsigned char*) key,
 
980
         table = (TABLE*) hash_next(&open_cache,(uchar*) key,
926
981
                                    key_length, &state))
927
982
    {
928
983
      if (table->reginfo.lock_type < TL_WRITE)
963
1018
}
964
1019
 
965
1020
 
966
 
void unlock_table_name(THD *thd __attribute__((unused)),
967
 
                       TableList *table_list)
 
1021
void unlock_table_name(THD *thd __attribute__((__unused__)),
 
1022
                       TABLE_LIST *table_list)
968
1023
{
969
1024
  if (table_list->table)
970
1025
  {
971
 
    hash_delete(&open_cache, (unsigned char*) table_list->table);
 
1026
    hash_delete(&open_cache, (uchar*) table_list->table);
972
1027
    broadcast_refresh();
973
1028
  }
974
1029
}
975
1030
 
976
1031
 
977
 
static bool locked_named_table(THD *thd __attribute__((unused)),
978
 
                               TableList *table_list)
 
1032
static bool locked_named_table(THD *thd __attribute__((__unused__)),
 
1033
                               TABLE_LIST *table_list)
979
1034
{
980
1035
  for (; table_list ; table_list=table_list->next_local)
981
1036
  {
982
 
    Table *table= table_list->table;
 
1037
    TABLE *table= table_list->table;
983
1038
    if (table)
984
1039
    {
985
 
      Table *save_next= table->next;
 
1040
      TABLE *save_next= table->next;
986
1041
      bool result;
987
1042
      table->next= 0;
988
1043
      result= table_is_used(table_list->table, 0);
995
1050
}
996
1051
 
997
1052
 
998
 
bool wait_for_locked_table_names(THD *thd, TableList *table_list)
 
1053
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
999
1054
{
1000
1055
  bool result=0;
1001
1056
 
1034
1089
    1   Fatal error (end of memory ?)
1035
1090
*/
1036
1091
 
1037
 
bool lock_table_names(THD *thd, TableList *table_list)
 
1092
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
1038
1093
{
1039
1094
  bool got_all_locks=1;
1040
 
  TableList *lock_table;
 
1095
  TABLE_LIST *lock_table;
1041
1096
 
1042
1097
  for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1043
1098
  {
1078
1133
  @retval FALSE Name lock successfully acquired.
1079
1134
*/
1080
1135
 
1081
 
bool lock_table_names_exclusively(THD *thd, TableList *table_list)
 
1136
bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
1082
1137
{
1083
1138
  if (lock_table_names(thd, table_list))
1084
1139
    return true;
1086
1141
  /*
1087
1142
    Upgrade the table name locks from semi-exclusive to exclusive locks.
1088
1143
  */
1089
 
  for (TableList *table= table_list; table; table= table->next_global)
 
1144
  for (TABLE_LIST *table= table_list; table; table= table->next_global)
1090
1145
  {
1091
1146
    if (table->table)
1092
1147
      table->table->open_placeholder= 1;
1111
1166
 
1112
1167
bool
1113
1168
is_table_name_exclusively_locked_by_this_thread(THD *thd,
1114
 
                                                TableList *table_list)
 
1169
                                                TABLE_LIST *table_list)
1115
1170
{
1116
1171
  char  key[MAX_DBKEY_LENGTH];
1117
 
  uint32_t  key_length;
 
1172
  uint  key_length;
1118
1173
 
1119
1174
  key_length= create_table_def_key(thd, key, table_list, 0);
1120
1175
 
1121
 
  return is_table_name_exclusively_locked_by_this_thread(thd, (unsigned char *)key,
 
1176
  return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
1122
1177
                                                         key_length);
1123
1178
}
1124
1179
 
1137
1192
 */
1138
1193
 
1139
1194
bool
1140
 
is_table_name_exclusively_locked_by_this_thread(THD *thd, unsigned char *key,
 
1195
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
1141
1196
                                                int key_length)
1142
1197
{
1143
1198
  HASH_SEARCH_STATE state;
1144
 
  Table *table;
 
1199
  TABLE *table;
1145
1200
 
1146
 
  for (table= (Table*) hash_first(&open_cache, key,
 
1201
  for (table= (TABLE*) hash_first(&open_cache, key,
1147
1202
                                  key_length, &state);
1148
1203
       table ;
1149
 
       table= (Table*) hash_next(&open_cache, key,
 
1204
       table= (TABLE*) hash_next(&open_cache, key,
1150
1205
                                 key_length, &state))
1151
1206
  {
1152
1207
    if (table->in_use == thd &&
1182
1237
    1   Fatal error (end of memory ?)
1183
1238
*/
1184
1239
 
1185
 
void unlock_table_names(THD *thd, TableList *table_list,
1186
 
                        TableList *last_table)
 
1240
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
 
1241
                        TABLE_LIST *last_table)
1187
1242
{
1188
 
  for (TableList *table= table_list;
 
1243
  for (TABLE_LIST *table= table_list;
1189
1244
       table != last_table;
1190
1245
       table= table->next_local)
1191
1246
    unlock_table_name(thd,table);
1300
1355
 
1301
1356
****************************************************************************/
1302
1357
 
1303
 
volatile uint32_t global_read_lock=0;
1304
 
volatile uint32_t global_read_lock_blocks_commit=0;
1305
 
static volatile uint32_t protect_against_global_read_lock=0;
1306
 
static volatile uint32_t waiting_for_read_lock=0;
 
1358
volatile uint global_read_lock=0;
 
1359
volatile uint global_read_lock_blocks_commit=0;
 
1360
static volatile uint protect_against_global_read_lock=0;
 
1361
static volatile uint waiting_for_read_lock=0;
1307
1362
 
1308
1363
#define GOT_GLOBAL_READ_LOCK               1
1309
1364
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
1344
1399
 
1345
1400
void unlock_global_read_lock(THD *thd)
1346
1401
{
1347
 
  uint32_t tmp;
 
1402
  uint tmp;
1348
1403
 
1349
1404
  pthread_mutex_lock(&LOCK_global_read_lock);
1350
1405
  tmp= --global_read_lock;
1483
1538
 
1484
1539
void broadcast_refresh(void)
1485
1540
{
1486
 
  pthread_cond_broadcast(&COND_refresh);
1487
 
  pthread_cond_broadcast(&COND_global_read_lock);
 
1541
  VOID(pthread_cond_broadcast(&COND_refresh));
 
1542
  VOID(pthread_cond_broadcast(&COND_global_read_lock));
1488
1543
}
1489
1544
 
1490
1545
 
1506
1561
    -1                  Error: no recovery possible.
1507
1562
*/
1508
1563
 
1509
 
int try_transactional_lock(THD *thd, TableList *table_list)
 
1564
int try_transactional_lock(THD *thd, TABLE_LIST *table_list)
1510
1565
{
1511
 
  uint32_t          dummy_counter;
 
1566
  uint          dummy_counter;
1512
1567
  int           error;
1513
1568
  int           result= 0;
1514
1569
 
1579
1634
    -1                  Error: Lock conversion is prohibited.
1580
1635
*/
1581
1636
 
1582
 
int check_transactional_lock(THD *thd, TableList *table_list)
 
1637
int check_transactional_lock(THD *thd, TABLE_LIST *table_list)
1583
1638
{
1584
 
  TableList    *tlist;
 
1639
  TABLE_LIST    *tlist;
1585
1640
  int           result= 0;
1586
 
  char          warn_buff[DRIZZLE_ERRMSG_SIZE];
 
1641
  char          warn_buff[MYSQL_ERRMSG_SIZE];
1587
1642
 
1588
1643
  for (tlist= table_list; tlist; tlist= tlist->next_global)
1589
1644
  {
1591
1646
    /*
1592
1647
      Unfortunately we cannot use tlist->placeholder() here. This method
1593
1648
      returns TRUE if the table is not open, which is always the case
1594
 
      here. Whenever the definition of TableList::placeholder() is
 
1649
      here. Whenever the definition of TABLE_LIST::placeholder() is
1595
1650
      changed, probably this condition needs to be changed too.
1596
1651
    */
1597
1652
    if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1619
1674
    /* Warn about the conversion. */
1620
1675
    snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1621
1676
             tlist->alias ? tlist->alias : tlist->table_name);
1622
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1677
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1623
1678
                 ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1624
1679
  }
1625
1680
 
1641
1696
    != 0                Error code from handler::lock_table().
1642
1697
*/
1643
1698
 
1644
 
int set_handler_table_locks(THD *thd, TableList *table_list,
 
1699
int set_handler_table_locks(THD *thd, TABLE_LIST *table_list,
1645
1700
                            bool transactional)
1646
1701
{
1647
 
  TableList    *tlist;
 
1702
  TABLE_LIST    *tlist;
1648
1703
  int           error= 0;
1649
1704
 
1650
1705
  for (tlist= table_list; tlist; tlist= tlist->next_global)
1681
1736
 
1682
1737
      /*
1683
1738
        For warning/error reporting we need to set the intended lock
1684
 
        method in the TableList object. It will be used later by
 
1739
        method in the TABLE_LIST object. It will be used later by
1685
1740
        check_transactional_lock(). The lock method is not set if this
1686
1741
        table belongs to a view. We can safely set it to transactional
1687
1742
        locking here. Even for non-view tables. This function is not