~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/lock.cc

Removed SCCS references.

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, TABLE **tables, uint count, uint flags)
 
135
{
 
136
  uint system_count;
 
137
  uint i;
 
138
 
 
139
  DBUG_ENTER("mysql_lock_tables_check");
 
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
    DBUG_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
    DBUG_RETURN(1);
 
166
  }
 
167
 
 
168
  DBUG_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
 
  *need_reopen= false;
 
217
  DBUG_ENTER("mysql_lock_tables");
 
218
 
 
219
  *need_reopen= FALSE;
 
220
 
 
221
  if (mysql_lock_tables_check(thd, tables, count, flags))
 
222
    DBUG_RETURN (NULL);
171
223
 
172
224
  for (;;)
173
225
  {
176
228
      break;
177
229
 
178
230
    if (global_read_lock && write_lock_used &&
179
 
        ! (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK))
 
231
        ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
180
232
    {
181
233
      /*
182
234
        Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
196
248
      }
197
249
    }
198
250
 
199
 
    if (!(flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
 
251
    if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
200
252
        write_lock_used &&
201
253
        opt_readonly &&
202
254
        !thd->slave_thread)
210
262
      break;
211
263
    }
212
264
 
213
 
    thd->set_proc_info("System lock");
 
265
    thd_proc_info(thd, "System lock");
 
266
    DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
214
267
    if (sql_lock->table_count && lock_external(thd, sql_lock->table,
215
268
                                               sql_lock->table_count))
216
269
    {
218
271
      reset_lock_data_and_free(&sql_lock);
219
272
      break;
220
273
    }
221
 
    thd->set_proc_info("Table lock");
 
274
    thd_proc_info(thd, "Table lock");
 
275
    DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
222
276
    /* Copy the lock data array. thr_multi_lock() reorders its contens. */
223
277
    memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
224
278
           sql_lock->lock_count * sizeof(*sql_lock->locks));
230
284
    if (rc > 1)                                 /* a timeout or a deadlock */
231
285
    {
232
286
      if (sql_lock->table_count)
233
 
        unlock_external(thd, sql_lock->table, sql_lock->table_count);
 
287
        VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
234
288
      reset_lock_data_and_free(&sql_lock);
235
289
      my_error(rc, MYF(0));
236
290
      break;
241
295
      sql_lock->lock_count= 0;                  // Locks are already freed
242
296
      // Fall through: unlock, reset lock data, free and retry
243
297
    }
244
 
    else if (!thd->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
 
298
    else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
245
299
    {
246
300
      /*
247
301
        Thread was killed or lock aborted. Let upper level close all
255
309
      thd->some_tables_deleted=0;
256
310
      break;
257
311
    }
258
 
    thd->set_proc_info(0);
 
312
    thd_proc_info(thd, 0);
259
313
 
260
314
    /* going to retry, unlock all tables */
261
315
    if (sql_lock->lock_count)
262
316
        thr_multi_unlock(sql_lock->locks, sql_lock->lock_count);
263
317
 
264
318
    if (sql_lock->table_count)
265
 
      unlock_external(thd, sql_lock->table, sql_lock->table_count);
 
319
      VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
266
320
 
267
321
    /*
268
322
      If thr_multi_lock fails it resets lock type for tables, which
271
325
    */
272
326
    reset_lock_data_and_free(&sql_lock);
273
327
retry:
274
 
    if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN)
 
328
    if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
275
329
    {
276
 
      *need_reopen= true;
 
330
      *need_reopen= TRUE;
277
331
      break;
278
332
    }
279
333
    if (wait_for_tables(thd))
280
334
      break;                                    // Couldn't open tables
281
335
  }
282
 
  thd->set_proc_info(0);
 
336
  thd_proc_info(thd, 0);
283
337
  if (thd->killed)
284
338
  {
285
339
    thd->send_kill_message();
291
345
  }
292
346
 
293
347
  thd->set_time_after_lock();
294
 
  return (sql_lock);
 
348
  DBUG_RETURN (sql_lock);
295
349
}
296
350
 
297
351
 
298
 
static int lock_external(THD *thd, Table **tables, uint32_t count)
 
352
static int lock_external(THD *thd, TABLE **tables, uint count)
299
353
{
300
 
  register uint32_t i;
 
354
  register uint i;
301
355
  int lock_type,error;
 
356
  DBUG_ENTER("lock_external");
 
357
 
 
358
  DBUG_PRINT("info", ("count %d", count));
302
359
  for (i=1 ; i <= count ; i++, tables++)
303
360
  {
304
 
    assert((*tables)->reginfo.lock_type >= TL_READ);
 
361
    DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
305
362
    lock_type=F_WRLCK;                          /* Lock exclusive */
306
363
    if ((*tables)->db_stat & HA_READ_ONLY ||
307
364
        ((*tables)->reginfo.lock_type >= TL_READ &&
317
374
        (*tables)->file->ha_external_lock(thd, F_UNLCK);
318
375
        (*tables)->current_lock=F_UNLCK;
319
376
      }
320
 
      return(error);
 
377
      DBUG_RETURN(error);
321
378
    }
322
379
    else
323
380
    {
325
382
      (*tables)->current_lock= lock_type;
326
383
    }
327
384
  }
328
 
  return(0);
 
385
  DBUG_RETURN(0);
329
386
}
330
387
 
331
388
 
332
 
void mysql_unlock_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
 
389
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
333
390
{
 
391
  DBUG_ENTER("mysql_unlock_tables");
334
392
  if (sql_lock->lock_count)
335
393
    thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
336
394
  if (sql_lock->table_count)
337
 
    unlock_external(thd,sql_lock->table,sql_lock->table_count);
338
 
  free((unsigned char*) sql_lock);
339
 
  return;
 
395
    VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
 
396
  my_free((uchar*) sql_lock,MYF(0));
 
397
  DBUG_VOID_RETURN;
340
398
}
341
399
 
342
400
/**
345
403
  This will work even if get_lock_data fails (next unlock will free all)
346
404
*/
347
405
 
348
 
void mysql_unlock_some_tables(THD *thd, Table **table,uint32_t count)
 
406
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
349
407
{
350
 
  DRIZZLE_LOCK *sql_lock;
351
 
  Table *write_lock_used;
 
408
  MYSQL_LOCK *sql_lock;
 
409
  TABLE *write_lock_used;
352
410
  if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
353
411
                               &write_lock_used)))
354
412
    mysql_unlock_tables(thd, sql_lock);
359
417
  unlock all tables locked for read.
360
418
*/
361
419
 
362
 
void mysql_unlock_read_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
 
420
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
363
421
{
364
 
  uint32_t i,found;
 
422
  uint i,found;
 
423
  DBUG_ENTER("mysql_unlock_read_tables");
365
424
 
366
425
  /* Move all write locks first */
367
426
  THR_LOCK_DATA **lock=sql_lock->locks;
369
428
  {
370
429
    if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ)
371
430
    {
372
 
      std::swap(*lock, sql_lock->locks[i]);
 
431
      swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]);
373
432
      lock++;
374
433
      found++;
375
434
    }
383
442
 
384
443
  /* Then do the same for the external locks */
385
444
  /* Move all write locked tables first */
386
 
  Table **table=sql_lock->table;
 
445
  TABLE **table=sql_lock->table;
387
446
  for (i=found=0 ; i < sql_lock->table_count ; i++)
388
447
  {
389
 
    assert(sql_lock->table[i]->lock_position == i);
 
448
    DBUG_ASSERT(sql_lock->table[i]->lock_position == i);
390
449
    if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
391
450
    {
392
 
      std::swap(*table, sql_lock->table[i]);
 
451
      swap_variables(TABLE *, *table, sql_lock->table[i]);
393
452
      table++;
394
453
      found++;
395
454
    }
397
456
  /* Unlock all read locked tables */
398
457
  if (i != found)
399
458
  {
400
 
    unlock_external(thd,table,i-found);
 
459
    VOID(unlock_external(thd,table,i-found));
401
460
    sql_lock->table_count=found;
402
461
  }
403
 
  /* Fix the lock positions in Table */
 
462
  /* Fix the lock positions in TABLE */
404
463
  table= sql_lock->table;
405
464
  found= 0;
406
465
  for (i= 0; i < sql_lock->table_count; i++)
407
466
  {
408
 
    Table *tbl= *table;
 
467
    TABLE *tbl= *table;
409
468
    tbl->lock_position= table - sql_lock->table;
410
469
    tbl->lock_data_start= found;
411
470
    found+= tbl->lock_count;
412
471
    table++;
413
472
  }
414
 
  return;
 
473
  DBUG_VOID_RETURN;
415
474
}
416
475
 
417
476
 
435
494
                          effect is desired.
436
495
*/
437
496
 
438
 
void mysql_lock_remove(THD *thd, DRIZZLE_LOCK *locked,Table *table,
 
497
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
439
498
                       bool always_unlock)
440
499
{
441
 
  if (always_unlock == true)
 
500
  if (always_unlock == TRUE)
442
501
    mysql_unlock_some_tables(thd, &table, /* table count */ 1);
443
502
  if (locked)
444
503
  {
445
 
    register uint32_t i;
 
504
    register uint i;
446
505
    for (i=0; i < locked->table_count; i++)
447
506
    {
448
507
      if (locked->table[i] == table)
449
508
      {
450
 
        uint32_t  j, removed_locks, old_tables;
451
 
        Table *tbl;
452
 
        uint32_t lock_data_end;
 
509
        uint  j, removed_locks, old_tables;
 
510
        TABLE *tbl;
 
511
        uint lock_data_end;
453
512
 
454
 
        assert(table->lock_position == i);
 
513
        DBUG_ASSERT(table->lock_position == i);
455
514
 
456
515
        /* Unlock if not yet unlocked */
457
 
        if (always_unlock == false)
 
516
        if (always_unlock == FALSE)
458
517
          mysql_unlock_some_tables(thd, &table, /* table count */ 1);
459
518
 
460
519
        /* Decrement table_count in advance, making below expressions easier */
464
523
        removed_locks= table->lock_count;
465
524
 
466
525
        /* Move down all table pointers above 'i'. */
467
 
        memcpy((locked->table+i), (locked->table+i+1),
468
 
               (old_tables - i) * sizeof(Table*));
 
526
        bmove((char*) (locked->table+i),
 
527
              (char*) (locked->table+i+1),
 
528
              (old_tables - i) * sizeof(TABLE*));
469
529
 
470
530
        lock_data_end= table->lock_data_start + table->lock_count;
471
531
        /* 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*));
 
532
        bmove((char*) (locked->locks + table->lock_data_start),
 
533
              (char*) (locked->locks + lock_data_end),
 
534
              (locked->lock_count - lock_data_end) *
 
535
              sizeof(THR_LOCK_DATA*));
476
536
 
477
537
        /*
478
538
          Fix moved table elements.
486
546
        {
487
547
          tbl= locked->table[j];
488
548
          tbl->lock_position--;
489
 
          assert(tbl->lock_position == j);
 
549
          DBUG_ASSERT(tbl->lock_position == j);
490
550
          tbl->lock_data_start-= removed_locks;
491
551
        }
492
552
 
500
560
 
501
561
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
502
562
 
503
 
void mysql_lock_downgrade_write(THD *thd, Table *table,
 
563
void mysql_lock_downgrade_write(THD *thd, TABLE *table,
504
564
                                thr_lock_type new_lock_type)
505
565
{
506
 
  DRIZZLE_LOCK *locked;
507
 
  Table *write_lock_used;
 
566
  MYSQL_LOCK *locked;
 
567
  TABLE *write_lock_used;
508
568
  if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
509
569
                              &write_lock_used)))
510
570
  {
511
 
    for (uint32_t i=0; i < locked->lock_count; i++)
 
571
    for (uint i=0; i < locked->lock_count; i++)
512
572
      thr_downgrade_write_lock(locked->locks[i], new_lock_type);
513
 
    free((unsigned char*) locked);
 
573
    my_free((uchar*) locked,MYF(0));
514
574
  }
515
575
}
516
576
 
517
577
 
518
578
/** Abort all other threads waiting to get lock in table. */
519
579
 
520
 
void mysql_lock_abort(THD *thd, Table *table, bool upgrade_lock)
 
580
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
521
581
{
522
 
  DRIZZLE_LOCK *locked;
523
 
  Table *write_lock_used;
 
582
  MYSQL_LOCK *locked;
 
583
  TABLE *write_lock_used;
 
584
  DBUG_ENTER("mysql_lock_abort");
524
585
 
525
586
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
526
587
                             &write_lock_used)))
527
588
  {
528
 
    for (uint32_t i=0; i < locked->lock_count; i++)
 
589
    for (uint i=0; i < locked->lock_count; i++)
529
590
      thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
530
 
    free((unsigned char*) locked);
 
591
    my_free((uchar*) locked,MYF(0));
531
592
  }
532
 
  return;
 
593
  DBUG_VOID_RETURN;
533
594
}
534
595
 
535
596
 
545
606
    1  Table was locked by at least one other thread
546
607
*/
547
608
 
548
 
bool mysql_lock_abort_for_thread(THD *thd, Table *table)
 
609
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
549
610
{
550
 
  DRIZZLE_LOCK *locked;
551
 
  Table *write_lock_used;
552
 
  bool result= false;
 
611
  MYSQL_LOCK *locked;
 
612
  TABLE *write_lock_used;
 
613
  bool result= FALSE;
 
614
  DBUG_ENTER("mysql_lock_abort_for_thread");
553
615
 
554
616
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
555
617
                             &write_lock_used)))
556
618
  {
557
 
    for (uint32_t i=0; i < locked->lock_count; i++)
 
619
    for (uint i=0; i < locked->lock_count; i++)
558
620
    {
559
621
      if (thr_abort_locks_for_thread(locked->locks[i]->lock,
560
622
                                     table->in_use->thread_id))
561
 
        result= true;
 
623
        result= TRUE;
562
624
    }
563
 
    free((unsigned char*) locked);
 
625
    my_free((uchar*) locked,MYF(0));
564
626
  }
565
 
  return(result);
 
627
  DBUG_RETURN(result);
566
628
}
567
629
 
568
630
 
569
 
DRIZZLE_LOCK *mysql_lock_merge(DRIZZLE_LOCK *a,DRIZZLE_LOCK *b)
 
631
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
570
632
{
571
 
  DRIZZLE_LOCK *sql_lock;
572
 
  Table **table, **end_table;
 
633
  MYSQL_LOCK *sql_lock;
 
634
  TABLE **table, **end_table;
 
635
  DBUG_ENTER("mysql_lock_merge");
573
636
 
574
 
  if (!(sql_lock= (DRIZZLE_LOCK*)
 
637
  if (!(sql_lock= (MYSQL_LOCK*)
575
638
        my_malloc(sizeof(*sql_lock)+
576
639
                  sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
577
 
                  sizeof(Table*)*(a->table_count+b->table_count),MYF(MY_WME))))
578
 
    return(0);                          // Fatal error
 
640
                  sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
 
641
    DBUG_RETURN(0);                             // Fatal error
579
642
  sql_lock->lock_count=a->lock_count+b->lock_count;
580
643
  sql_lock->table_count=a->table_count+b->table_count;
581
644
  sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
582
 
  sql_lock->table=(Table**) (sql_lock->locks+sql_lock->lock_count);
 
645
  sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
583
646
  memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
584
647
  memcpy(sql_lock->locks+a->lock_count,b->locks,
585
648
         b->lock_count*sizeof(*b->locks));
586
649
  memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
587
650
  memcpy(sql_lock->table+a->table_count,b->table,
588
 
         b->table_count*sizeof(*b->table));
 
651
         b->table_count*sizeof(*b->table));
589
652
 
590
653
  /*
591
654
    Now adjust lock_position and lock_data_start for all objects that was
601
664
  }
602
665
 
603
666
  /* Delete old, not needed locks */
604
 
  free((unsigned char*) a);
605
 
  free((unsigned char*) b);
606
 
  return(sql_lock);
 
667
  my_free((uchar*) a,MYF(0));
 
668
  my_free((uchar*) b,MYF(0));
 
669
  DBUG_RETURN(sql_lock);
607
670
}
608
671
 
609
672
 
630
693
    !NULL   First table from 'haystack' that matches a lock on 'needle'.
631
694
*/
632
695
 
633
 
TableList *mysql_lock_have_duplicate(THD *thd, TableList *needle,
634
 
                                      TableList *haystack)
 
696
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
 
697
                                      TABLE_LIST *haystack)
635
698
{
636
 
  DRIZZLE_LOCK            *mylock;
637
 
  Table                 **lock_tables;
638
 
  Table                 *table;
639
 
  Table                 *table2;
 
699
  MYSQL_LOCK            *mylock;
 
700
  TABLE                 **lock_tables;
 
701
  TABLE                 *table;
 
702
  TABLE                 *table2;
640
703
  THR_LOCK_DATA         **lock_locks;
641
704
  THR_LOCK_DATA         **table_lock_data;
642
705
  THR_LOCK_DATA         **end_data;
643
706
  THR_LOCK_DATA         **lock_data2;
644
707
  THR_LOCK_DATA         **end_data2;
 
708
  DBUG_ENTER("mysql_lock_have_duplicate");
645
709
 
646
710
  /*
647
711
    Table may not be defined for derived or view tables.
666
730
  lock_tables= mylock->table;
667
731
 
668
732
  /* Prepare table related variables that don't change in loop. */
669
 
  assert((table->lock_position < mylock->table_count) &&
 
733
  DBUG_ASSERT((table->lock_position < mylock->table_count) &&
670
734
              (table == lock_tables[table->lock_position]));
671
735
  table_lock_data= lock_locks + table->lock_data_start;
672
736
  end_data= table_lock_data + table->lock_count;
680
744
      continue;
681
745
 
682
746
    /* All tables in list must be in lock. */
683
 
    assert((table2->lock_position < mylock->table_count) &&
 
747
    DBUG_ASSERT((table2->lock_position < mylock->table_count) &&
684
748
                (table2 == lock_tables[table2->lock_position]));
685
749
 
686
750
    for (lock_data2=  lock_locks + table2->lock_data_start,
697
761
      {
698
762
        if ((*lock_data)->lock == lock2)
699
763
        {
700
 
          return(haystack);
 
764
          DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
 
765
          DBUG_RETURN(haystack);
701
766
        }
702
767
      }
703
768
    }
704
769
  }
705
770
 
706
771
 end:
707
 
  return(NULL);
 
772
  DBUG_PRINT("info", ("no duplicate found"));
 
773
  DBUG_RETURN(NULL);
708
774
}
709
775
 
710
776
 
711
777
/** Unlock a set of external. */
712
778
 
713
 
static int unlock_external(THD *thd, Table **table,uint32_t count)
 
779
static int unlock_external(THD *thd, TABLE **table,uint count)
714
780
{
715
781
  int error,error_code;
 
782
  DBUG_ENTER("unlock_external");
716
783
 
717
784
  error_code=0;
718
785
  do
728
795
    }
729
796
    table++;
730
797
  } while (--count);
731
 
  return(error_code);
 
798
  DBUG_RETURN(error_code);
732
799
}
733
800
 
734
801
 
739
806
  @param table_ptr          Pointer to tables that should be locks
740
807
  @param flags              One of:
741
808
           - GET_LOCK_UNLOCK      : If we should send TL_IGNORE to store lock
742
 
           - GET_LOCK_STORE_LOCKS : Store lock info in Table
 
809
           - GET_LOCK_STORE_LOCKS : Store lock info in TABLE
743
810
  @param write_lock_used   Store pointer to last table with WRITE_ALLOW_WRITE
744
811
*/
745
812
 
746
 
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table_ptr, uint32_t count,
747
 
                                 uint32_t flags, Table **write_lock_used)
 
813
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
 
814
                                 uint flags, TABLE **write_lock_used)
748
815
{
749
 
  uint32_t i,tables,lock_count;
750
 
  DRIZZLE_LOCK *sql_lock;
 
816
  uint i,tables,lock_count;
 
817
  MYSQL_LOCK *sql_lock;
751
818
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
752
 
  Table **to, **table_buf;
753
 
 
754
 
  assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
755
 
 
 
819
  TABLE **to, **table_buf;
 
820
  DBUG_ENTER("get_lock_data");
 
821
 
 
822
  DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
 
823
 
 
824
  DBUG_PRINT("info", ("count %d", count));
756
825
  *write_lock_used=0;
757
826
  for (i=tables=lock_count=0 ; i < count ; i++)
758
827
  {
759
 
    Table *t= table_ptr[i];
 
828
    TABLE *t= table_ptr[i];
760
829
 
761
830
    if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
762
831
    {
771
840
    update the table values. So the second part of the array is copied
772
841
    from the first part immediately before calling thr_multi_lock().
773
842
  */
774
 
  if (!(sql_lock= (DRIZZLE_LOCK*)
 
843
  if (!(sql_lock= (MYSQL_LOCK*)
775
844
        my_malloc(sizeof(*sql_lock) +
776
845
                  sizeof(THR_LOCK_DATA*) * tables * 2 +
777
846
                  sizeof(table_ptr) * lock_count,
778
847
                  MYF(0))))
779
 
    return(0);
 
848
    DBUG_RETURN(0);
780
849
  locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
781
 
  to= table_buf= sql_lock->table= (Table**) (locks + tables * 2);
 
850
  to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
782
851
  sql_lock->table_count=lock_count;
783
852
 
784
853
  for (i=0 ; i < count ; i++)
785
854
  {
786
 
    Table *table;
 
855
    TABLE *table;
787
856
    enum thr_lock_type lock_type;
788
857
 
789
858
    if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
790
859
      continue;
791
860
    lock_type= table->reginfo.lock_type;
792
 
    assert (lock_type != TL_WRITE_DEFAULT);
 
861
    DBUG_ASSERT (lock_type != TL_WRITE_DEFAULT);
793
862
    if (lock_type >= TL_WRITE_ALLOW_WRITE)
794
863
    {
795
864
      *write_lock_used=table;
799
868
        /* Clear the lock type of the lock data that are stored already. */
800
869
        sql_lock->lock_count= locks - sql_lock->locks;
801
870
        reset_lock_data_and_free(&sql_lock);
802
 
        return(0);
 
871
        DBUG_RETURN(0);
803
872
      }
804
873
    }
 
874
    THR_LOCK_DATA **org_locks = locks;
805
875
    locks_start= locks;
806
876
    locks= table->file->store_lock(thd, locks,
807
877
                                   (flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
813
883
      table->lock_count=      (uint) (locks - locks_start);
814
884
    }
815
885
    *to++= table;
 
886
    if (locks)
 
887
      for ( ; org_locks != locks ; org_locks++)
 
888
        (*org_locks)->debug_print_param= (void *) table;
816
889
  }
817
890
  /*
818
891
    We do not use 'tables', because there are cases where store_lock()
829
902
    And in the FLUSH case, the memory is released quickly anyway.
830
903
  */
831
904
  sql_lock->lock_count= locks - locks_buf;
832
 
  return(sql_lock);
 
905
  DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
 
906
                      sql_lock->table_count, sql_lock->lock_count));
 
907
  DBUG_RETURN(sql_lock);
833
908
}
834
909
 
835
910
 
854
929
    1   error
855
930
*/
856
931
 
857
 
int lock_and_wait_for_table_name(THD *thd, TableList *table_list)
 
932
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
858
933
{
859
934
  int lock_retcode;
860
935
  int error= -1;
 
936
  DBUG_ENTER("lock_and_wait_for_table_name");
861
937
 
862
938
  if (wait_if_global_read_lock(thd, 0, 1))
863
 
    return(1);
864
 
  pthread_mutex_lock(&LOCK_open);
865
 
  if ((lock_retcode = lock_table_name(thd, table_list, true)) < 0)
 
939
    DBUG_RETURN(1);
 
940
  VOID(pthread_mutex_lock(&LOCK_open));
 
941
  if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0)
866
942
    goto end;
867
943
  if (lock_retcode && wait_for_locked_table_names(thd, table_list))
868
944
  {
874
950
end:
875
951
  pthread_mutex_unlock(&LOCK_open);
876
952
  start_waiting_global_read_lock(thd);
877
 
  return(error);
 
953
  DBUG_RETURN(error);
878
954
}
879
955
 
880
956
 
905
981
    > 0  table locked, but someone is using it
906
982
*/
907
983
 
908
 
int lock_table_name(THD *thd, TableList *table_list, bool check_in_use)
 
984
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
909
985
{
910
 
  Table *table;
 
986
  TABLE *table;
911
987
  char  key[MAX_DBKEY_LENGTH];
912
988
  char *db= table_list->db;
913
 
  uint32_t  key_length;
914
 
  bool  found_locked_table= false;
 
989
  uint  key_length;
 
990
  bool  found_locked_table= FALSE;
915
991
  HASH_SEARCH_STATE state;
 
992
  DBUG_ENTER("lock_table_name");
 
993
  DBUG_PRINT("enter",("db: %s  name: %s", db, table_list->table_name));
916
994
 
917
995
  key_length= create_table_def_key(thd, key, table_list, 0);
918
996
 
919
997
  if (check_in_use)
920
998
  {
921
999
    /* Only insert the table if we haven't insert it already */
922
 
    for (table=(Table*) hash_first(&open_cache, (unsigned char*)key,
 
1000
    for (table=(TABLE*) hash_first(&open_cache, (uchar*)key,
923
1001
                                   key_length, &state);
924
1002
         table ;
925
 
         table = (Table*) hash_next(&open_cache,(unsigned char*) key,
 
1003
         table = (TABLE*) hash_next(&open_cache,(uchar*) key,
926
1004
                                    key_length, &state))
927
1005
    {
928
1006
      if (table->reginfo.lock_type < TL_WRITE)
929
1007
      {
930
1008
        if (table->in_use == thd)
931
 
          found_locked_table= true;
 
1009
          found_locked_table= TRUE;
932
1010
        continue;
933
1011
      }
934
1012
 
935
1013
      if (table->in_use == thd)
936
1014
      {
 
1015
        DBUG_PRINT("info", ("Table is in use"));
937
1016
        table->s->version= 0;                  // Ensure no one can use this
938
1017
        table->locked_by_name= 1;
939
 
        return(0);
 
1018
        DBUG_RETURN(0);
940
1019
      }
941
1020
    }
942
1021
  }
949
1028
    else
950
1029
      my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
951
1030
 
952
 
    return(-1);
 
1031
    DBUG_RETURN(-1);
953
1032
  }
954
1033
 
955
1034
  if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
956
 
    return(-1);
 
1035
    DBUG_RETURN(-1);
957
1036
 
958
1037
  table_list->table=table;
959
1038
 
960
1039
  /* Return 1 if table is in use */
961
 
  return(test(remove_table_from_cache(thd, db, table_list->table_name,
 
1040
  DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
962
1041
             check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
963
1042
}
964
1043
 
965
1044
 
966
 
void unlock_table_name(THD *thd __attribute__((unused)),
967
 
                       TableList *table_list)
 
1045
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
968
1046
{
969
1047
  if (table_list->table)
970
1048
  {
971
 
    hash_delete(&open_cache, (unsigned char*) table_list->table);
 
1049
    hash_delete(&open_cache, (uchar*) table_list->table);
972
1050
    broadcast_refresh();
973
1051
  }
974
1052
}
975
1053
 
976
1054
 
977
 
static bool locked_named_table(THD *thd __attribute__((unused)),
978
 
                               TableList *table_list)
 
1055
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
979
1056
{
980
1057
  for (; table_list ; table_list=table_list->next_local)
981
1058
  {
982
 
    Table *table= table_list->table;
 
1059
    TABLE *table= table_list->table;
983
1060
    if (table)
984
1061
    {
985
 
      Table *save_next= table->next;
 
1062
      TABLE *save_next= table->next;
986
1063
      bool result;
987
1064
      table->next= 0;
988
1065
      result= table_is_used(table_list->table, 0);
995
1072
}
996
1073
 
997
1074
 
998
 
bool wait_for_locked_table_names(THD *thd, TableList *table_list)
 
1075
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
999
1076
{
1000
1077
  bool result=0;
 
1078
  DBUG_ENTER("wait_for_locked_table_names");
1001
1079
 
1002
1080
  safe_mutex_assert_owner(&LOCK_open);
1003
1081
 
1011
1089
    wait_for_condition(thd, &LOCK_open, &COND_refresh);
1012
1090
    pthread_mutex_lock(&LOCK_open);
1013
1091
  }
1014
 
  return(result);
 
1092
  DBUG_RETURN(result);
1015
1093
}
1016
1094
 
1017
1095
 
1034
1112
    1   Fatal error (end of memory ?)
1035
1113
*/
1036
1114
 
1037
 
bool lock_table_names(THD *thd, TableList *table_list)
 
1115
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
1038
1116
{
1039
1117
  bool got_all_locks=1;
1040
 
  TableList *lock_table;
 
1118
  TABLE_LIST *lock_table;
1041
1119
 
1042
1120
  for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1043
1121
  {
1044
1122
    int got_lock;
1045
 
    if ((got_lock=lock_table_name(thd,lock_table, true)) < 0)
 
1123
    if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0)
1046
1124
      goto end;                                 // Fatal error
1047
1125
    if (got_lock)
1048
1126
      got_all_locks=0;                          // Someone is using table
1078
1156
  @retval FALSE Name lock successfully acquired.
1079
1157
*/
1080
1158
 
1081
 
bool lock_table_names_exclusively(THD *thd, TableList *table_list)
 
1159
bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
1082
1160
{
1083
1161
  if (lock_table_names(thd, table_list))
1084
 
    return true;
 
1162
    return TRUE;
1085
1163
 
1086
1164
  /*
1087
1165
    Upgrade the table name locks from semi-exclusive to exclusive locks.
1088
1166
  */
1089
 
  for (TableList *table= table_list; table; table= table->next_global)
 
1167
  for (TABLE_LIST *table= table_list; table; table= table->next_global)
1090
1168
  {
1091
1169
    if (table->table)
1092
1170
      table->table->open_placeholder= 1;
1093
1171
  }
1094
 
  return false;
 
1172
  return FALSE;
1095
1173
}
1096
1174
 
1097
1175
 
1111
1189
 
1112
1190
bool
1113
1191
is_table_name_exclusively_locked_by_this_thread(THD *thd,
1114
 
                                                TableList *table_list)
 
1192
                                                TABLE_LIST *table_list)
1115
1193
{
1116
1194
  char  key[MAX_DBKEY_LENGTH];
1117
 
  uint32_t  key_length;
 
1195
  uint  key_length;
1118
1196
 
1119
1197
  key_length= create_table_def_key(thd, key, table_list, 0);
1120
1198
 
1121
 
  return is_table_name_exclusively_locked_by_this_thread(thd, (unsigned char *)key,
 
1199
  return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
1122
1200
                                                         key_length);
1123
1201
}
1124
1202
 
1137
1215
 */
1138
1216
 
1139
1217
bool
1140
 
is_table_name_exclusively_locked_by_this_thread(THD *thd, unsigned char *key,
 
1218
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
1141
1219
                                                int key_length)
1142
1220
{
1143
1221
  HASH_SEARCH_STATE state;
1144
 
  Table *table;
 
1222
  TABLE *table;
1145
1223
 
1146
 
  for (table= (Table*) hash_first(&open_cache, key,
 
1224
  for (table= (TABLE*) hash_first(&open_cache, key,
1147
1225
                                  key_length, &state);
1148
1226
       table ;
1149
 
       table= (Table*) hash_next(&open_cache, key,
 
1227
       table= (TABLE*) hash_next(&open_cache, key,
1150
1228
                                 key_length, &state))
1151
1229
  {
1152
1230
    if (table->in_use == thd &&
1153
1231
        table->open_placeholder == 1 &&
1154
1232
        table->s->version == 0)
1155
 
      return true;
 
1233
      return TRUE;
1156
1234
  }
1157
1235
 
1158
 
  return false;
 
1236
  return FALSE;
1159
1237
}
1160
1238
 
1161
1239
/**
1182
1260
    1   Fatal error (end of memory ?)
1183
1261
*/
1184
1262
 
1185
 
void unlock_table_names(THD *thd, TableList *table_list,
1186
 
                        TableList *last_table)
 
1263
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
 
1264
                        TABLE_LIST *last_table)
1187
1265
{
1188
 
  for (TableList *table= table_list;
 
1266
  DBUG_ENTER("unlock_table_names");
 
1267
  for (TABLE_LIST *table= table_list;
1189
1268
       table != last_table;
1190
1269
       table= table->next_local)
1191
1270
    unlock_table_name(thd,table);
1192
1271
  broadcast_refresh();
1193
 
  return;
 
1272
  DBUG_VOID_RETURN;
1194
1273
}
1195
1274
 
1196
1275
 
1197
1276
static void print_lock_error(int error, const char *table)
1198
1277
{
1199
1278
  int textno;
 
1279
  DBUG_ENTER("print_lock_error");
1200
1280
 
1201
1281
  switch (error) {
1202
1282
  case HA_ERR_LOCK_WAIT_TIMEOUT:
1221
1301
  else
1222
1302
    my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error);
1223
1303
 
1224
 
  return;
 
1304
  DBUG_VOID_RETURN;
1225
1305
}
1226
1306
 
1227
1307
 
1300
1380
 
1301
1381
****************************************************************************/
1302
1382
 
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;
 
1383
volatile uint global_read_lock=0;
 
1384
volatile uint global_read_lock_blocks_commit=0;
 
1385
static volatile uint protect_against_global_read_lock=0;
 
1386
static volatile uint waiting_for_read_lock=0;
1307
1387
 
1308
1388
#define GOT_GLOBAL_READ_LOCK               1
1309
1389
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
1310
1390
 
1311
1391
bool lock_global_read_lock(THD *thd)
1312
1392
{
 
1393
  DBUG_ENTER("lock_global_read_lock");
 
1394
 
1313
1395
  if (!thd->global_read_lock)
1314
1396
  {
1315
1397
    const char *old_message;
1316
1398
    (void) pthread_mutex_lock(&LOCK_global_read_lock);
1317
1399
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1318
1400
                                "Waiting to get readlock");
 
1401
    DBUG_PRINT("info",
 
1402
               ("waiting_for: %d  protect_against: %d",
 
1403
                waiting_for_read_lock, protect_against_global_read_lock));
1319
1404
 
1320
1405
    waiting_for_read_lock++;
1321
1406
    while (protect_against_global_read_lock && !thd->killed)
1324
1409
    if (thd->killed)
1325
1410
    {
1326
1411
      thd->exit_cond(old_message);
1327
 
      return(1);
 
1412
      DBUG_RETURN(1);
1328
1413
    }
1329
1414
    thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
1330
1415
    global_read_lock++;
1338
1423
    forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
1339
1424
    UPDATE and one does FLUSH TABLES WITH READ LOCK).
1340
1425
  */
1341
 
  return(0);
 
1426
  DBUG_RETURN(0);
1342
1427
}
1343
1428
 
1344
1429
 
1345
1430
void unlock_global_read_lock(THD *thd)
1346
1431
{
1347
 
  uint32_t tmp;
 
1432
  uint tmp;
 
1433
  DBUG_ENTER("unlock_global_read_lock");
 
1434
  DBUG_PRINT("info",
 
1435
             ("global_read_lock: %u  global_read_lock_blocks_commit: %u",
 
1436
              global_read_lock, global_read_lock_blocks_commit));
1348
1437
 
1349
1438
  pthread_mutex_lock(&LOCK_global_read_lock);
1350
1439
  tmp= --global_read_lock;
1354
1443
  /* Send the signal outside the mutex to avoid a context switch */
1355
1444
  if (!tmp)
1356
1445
  {
 
1446
    DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
1357
1447
    pthread_cond_broadcast(&COND_global_read_lock);
1358
1448
  }
1359
1449
  thd->global_read_lock= 0;
1360
1450
 
1361
 
  return;
 
1451
  DBUG_VOID_RETURN;
1362
1452
}
1363
1453
 
1364
1454
#define must_wait (global_read_lock &&                             \
1370
1460
{
1371
1461
  const char *old_message= NULL;
1372
1462
  bool result= 0, need_exit_cond;
 
1463
  DBUG_ENTER("wait_if_global_read_lock");
1373
1464
 
1374
1465
  /*
1375
1466
    Assert that we do not own LOCK_open. If we would own it, other
1392
1483
        This allowance is needed to not break existing versions of innobackup
1393
1484
        which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT.
1394
1485
      */
1395
 
      return(is_not_commit);
 
1486
      DBUG_RETURN(is_not_commit);
1396
1487
    }
1397
1488
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1398
1489
                                "Waiting for release of readlock");
1399
1490
    while (must_wait && ! thd->killed &&
1400
1491
           (!abort_on_refresh || thd->version == refresh_version))
1401
1492
    {
 
1493
      DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
1402
1494
      (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
 
1495
      DBUG_PRINT("signal", ("Got COND_global_read_lock"));
1403
1496
    }
1404
1497
    if (thd->killed)
1405
1498
      result=1;
1414
1507
    thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1415
1508
  else
1416
1509
    pthread_mutex_unlock(&LOCK_global_read_lock);
1417
 
  return(result);
 
1510
  DBUG_RETURN(result);
1418
1511
}
1419
1512
 
1420
1513
 
1421
1514
void start_waiting_global_read_lock(THD *thd)
1422
1515
{
1423
1516
  bool tmp;
 
1517
  DBUG_ENTER("start_waiting_global_read_lock");
1424
1518
  if (unlikely(thd->global_read_lock))
1425
 
    return;
 
1519
    DBUG_VOID_RETURN;
1426
1520
  (void) pthread_mutex_lock(&LOCK_global_read_lock);
1427
1521
  tmp= (!--protect_against_global_read_lock &&
1428
1522
        (waiting_for_read_lock || global_read_lock_blocks_commit));
1429
1523
  (void) pthread_mutex_unlock(&LOCK_global_read_lock);
1430
1524
  if (tmp)
1431
1525
    pthread_cond_broadcast(&COND_global_read_lock);
1432
 
  return;
 
1526
  DBUG_VOID_RETURN;
1433
1527
}
1434
1528
 
1435
1529
 
1437
1531
{
1438
1532
  bool error;
1439
1533
  const char *old_message;
 
1534
  DBUG_ENTER("make_global_read_lock_block_commit");
1440
1535
  /*
1441
1536
    If we didn't succeed lock_global_read_lock(), or if we already suceeded
1442
1537
    make_global_read_lock_block_commit(), do nothing.
1443
1538
  */
1444
1539
  if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
1445
 
    return(0);
 
1540
    DBUG_RETURN(0);
1446
1541
  pthread_mutex_lock(&LOCK_global_read_lock);
1447
1542
  /* increment this BEFORE waiting on cond (otherwise race cond) */
1448
1543
  global_read_lock_blocks_commit++;
1449
1544
  /* For testing we set up some blocking, to see if we can be killed */
1450
 
  protect_against_global_read_lock++;
 
1545
  DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
 
1546
                  protect_against_global_read_lock++;);
1451
1547
  old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1452
1548
                               "Waiting for all running commits to finish");
1453
1549
  while (protect_against_global_read_lock && !thd->killed)
1454
1550
    pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1455
 
  protect_against_global_read_lock--;
 
1551
  DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
 
1552
                  protect_against_global_read_lock--;);
1456
1553
  if ((error= test(thd->killed)))
1457
1554
    global_read_lock_blocks_commit--; // undo what we did
1458
1555
  else
1459
1556
    thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1460
1557
  thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1461
 
  return(error);
 
1558
  DBUG_RETURN(error);
1462
1559
}
1463
1560
 
1464
1561
 
1483
1580
 
1484
1581
void broadcast_refresh(void)
1485
1582
{
1486
 
  pthread_cond_broadcast(&COND_refresh);
1487
 
  pthread_cond_broadcast(&COND_global_read_lock);
 
1583
  VOID(pthread_cond_broadcast(&COND_refresh));
 
1584
  VOID(pthread_cond_broadcast(&COND_global_read_lock));
1488
1585
}
1489
1586
 
1490
1587
 
1506
1603
    -1                  Error: no recovery possible.
1507
1604
*/
1508
1605
 
1509
 
int try_transactional_lock(THD *thd, TableList *table_list)
 
1606
int try_transactional_lock(THD *thd, TABLE_LIST *table_list)
1510
1607
{
1511
 
  uint32_t          dummy_counter;
 
1608
  uint          dummy_counter;
1512
1609
  int           error;
1513
1610
  int           result= 0;
 
1611
  DBUG_ENTER("try_transactional_lock");
1514
1612
 
1515
1613
  /* Need to open the tables to be able to access engine methods. */
1516
1614
  if (open_tables(thd, &table_list, &dummy_counter, 0))
1517
1615
  {
1518
1616
    /* purecov: begin tested */
1519
 
    return(-1);
 
1617
    DBUG_PRINT("lock_info", ("aborting, open_tables failed"));
 
1618
    DBUG_RETURN(-1);
1520
1619
    /* purecov: end */
1521
1620
  }
1522
1621
 
1523
1622
  /* Required by InnoDB. */
1524
 
  thd->in_lock_tables= true;
 
1623
  thd->in_lock_tables= TRUE;
1525
1624
 
1526
 
  if ((error= set_handler_table_locks(thd, table_list, true)))
 
1625
  if ((error= set_handler_table_locks(thd, table_list, TRUE)))
1527
1626
  {
1528
1627
    /*
1529
1628
      Not all transactional locks could be taken. If the error was
1532
1631
    */
1533
1632
    if (error != HA_ERR_WRONG_COMMAND)
1534
1633
    {
 
1634
      DBUG_PRINT("lock_info", ("aborting, lock_table failed"));
1535
1635
      result= -1;
1536
1636
      goto err;
1537
1637
    }
1541
1641
      successfully taken transactional locks. They go away at end of
1542
1642
      transaction anyway.
1543
1643
    */
 
1644
    DBUG_PRINT("lock_info", ("fall back to non-trans lock: no SE support"));
1544
1645
    result= 1;
1545
1646
  }
1546
1647
 
1549
1650
  (void) ha_autocommit_or_rollback(thd, 0);
1550
1651
  /* Close the tables. The locks (if taken) persist in the storage engines. */
1551
1652
  close_tables_for_reopen(thd, &table_list);
1552
 
  thd->in_lock_tables= false;
1553
 
  return(result);
 
1653
  thd->in_lock_tables= FALSE;
 
1654
  DBUG_PRINT("lock_info", ("result: %d", result));
 
1655
  DBUG_RETURN(result);
1554
1656
}
1555
1657
 
1556
1658
 
1579
1681
    -1                  Error: Lock conversion is prohibited.
1580
1682
*/
1581
1683
 
1582
 
int check_transactional_lock(THD *thd, TableList *table_list)
 
1684
int check_transactional_lock(THD *thd, TABLE_LIST *table_list)
1583
1685
{
1584
 
  TableList    *tlist;
 
1686
  TABLE_LIST    *tlist;
1585
1687
  int           result= 0;
1586
 
  char          warn_buff[DRIZZLE_ERRMSG_SIZE];
 
1688
  char          warn_buff[MYSQL_ERRMSG_SIZE];
 
1689
  DBUG_ENTER("check_transactional_lock");
1587
1690
 
1588
1691
  for (tlist= table_list; tlist; tlist= tlist->next_global)
1589
1692
  {
 
1693
    DBUG_PRINT("lock_info", ("checking table: '%s'", tlist->table_name));
1590
1694
 
1591
1695
    /*
1592
1696
      Unfortunately we cannot use tlist->placeholder() here. This method
1593
1697
      returns TRUE if the table is not open, which is always the case
1594
 
      here. Whenever the definition of TableList::placeholder() is
 
1698
      here. Whenever the definition of TABLE_LIST::placeholder() is
1595
1699
      changed, probably this condition needs to be changed too.
1596
1700
    */
1597
1701
    if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1598
1702
    {
 
1703
      DBUG_PRINT("lock_info", ("skipping placeholder: %d  transactional: %d",
 
1704
                               tlist->placeholder(),
 
1705
                               tlist->lock_transactional));
1599
1706
      continue;
1600
1707
    }
1601
1708
 
1617
1724
    }
1618
1725
 
1619
1726
    /* Warn about the conversion. */
1620
 
    snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1621
 
             tlist->alias ? tlist->alias : tlist->table_name);
1622
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1727
    my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
 
1728
                tlist->alias ? tlist->alias : tlist->table_name);
 
1729
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1623
1730
                 ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1624
1731
  }
1625
1732
 
1626
 
  return(result);
 
1733
  DBUG_PRINT("lock_info", ("result: %d", result));
 
1734
  DBUG_RETURN(result);
1627
1735
}
1628
1736
 
1629
1737
 
1641
1749
    != 0                Error code from handler::lock_table().
1642
1750
*/
1643
1751
 
1644
 
int set_handler_table_locks(THD *thd, TableList *table_list,
 
1752
int set_handler_table_locks(THD *thd, TABLE_LIST *table_list,
1645
1753
                            bool transactional)
1646
1754
{
1647
 
  TableList    *tlist;
 
1755
  TABLE_LIST    *tlist;
1648
1756
  int           error= 0;
 
1757
  DBUG_ENTER("set_handler_table_locks");
 
1758
  DBUG_PRINT("lock_info", ("transactional: %d", transactional));
1649
1759
 
1650
1760
  for (tlist= table_list; tlist; tlist= tlist->next_global)
1651
1761
  {
1655
1765
    if (tlist->placeholder())
1656
1766
      continue;
1657
1767
 
1658
 
    assert((tlist->lock_type == TL_READ) ||
 
1768
    DBUG_ASSERT((tlist->lock_type == TL_READ) ||
1659
1769
                (tlist->lock_type == TL_READ_NO_INSERT) ||
1660
1770
                (tlist->lock_type == TL_WRITE_DEFAULT) ||
1661
1771
                (tlist->lock_type == TL_WRITE) ||
1678
1788
        Non-transactional locks do not support a lock_timeout.
1679
1789
      */
1680
1790
      lock_timeout= tlist->top_table()->lock_timeout;
 
1791
      DBUG_PRINT("lock_info",
 
1792
                 ("table: '%s'  tlist==top_table: %d  lock_timeout: %d",
 
1793
                  tlist->table_name, tlist==tlist->top_table(), lock_timeout));
1681
1794
 
1682
1795
      /*
1683
1796
        For warning/error reporting we need to set the intended lock
1684
 
        method in the TableList object. It will be used later by
 
1797
        method in the TABLE_LIST object. It will be used later by
1685
1798
        check_transactional_lock(). The lock method is not set if this
1686
1799
        table belongs to a view. We can safely set it to transactional
1687
1800
        locking here. Even for non-view tables. This function is not
1688
1801
        called if non-transactional locking was requested for any
1689
1802
        object.
1690
1803
      */
1691
 
      tlist->lock_transactional= true;
 
1804
      tlist->lock_transactional= TRUE;
1692
1805
    }
1693
1806
 
1694
1807
    /*
1706
1819
    }
1707
1820
  }
1708
1821
 
1709
 
  return(error);
 
1822
  DBUG_RETURN(error);
1710
1823
}
1711
1824
 
1712
1825