~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/lock.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

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