~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/lock.cc

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
  - For each SQL statement mysql_lock_tables() is called for all involved
31
31
    tables.
32
32
    - mysql_lock_tables() will call
33
 
      table_handler->external_lock(thd,locktype) for each table.
 
33
      table_handler->external_lock(session,locktype) for each table.
34
34
      This is followed by a call to thr_multi_lock() for all tables.
35
35
 
36
36
  - When statement is done, we call mysql_unlock_tables().
37
37
    This will call thr_multi_unlock() followed by
38
 
    table_handler->external_lock(thd, F_UNLCK) for each table.
 
38
    table_handler->external_lock(session, F_UNLCK) for each table.
39
39
 
40
40
  - Note that mysql_unlock_tables() may be called several times as
41
41
    MySQL in some cases can free some tables earlier than others.
43
43
  - The above is true both for normal and temporary tables.
44
44
 
45
45
  - Temporary non transactional tables are never passed to thr_multi_lock()
46
 
    and we never call external_lock(thd, F_UNLOCK) on these.
 
46
    and we never call external_lock(session, F_UNLOCK) on these.
47
47
 
48
48
  When using LOCK TABLES:
49
49
 
50
50
  - LOCK Table will call mysql_lock_tables() for all tables.
51
51
    mysql_lock_tables() will call
52
 
    table_handler->external_lock(thd,locktype) for each table.
 
52
    table_handler->external_lock(session,locktype) for each table.
53
53
    This is followed by a call to thr_multi_lock() for all tables.
54
54
 
55
 
  - For each statement, we will call table_handler->start_stmt(THD)
 
55
  - For each statement, we will call table_handler->start_stmt(Session)
56
56
    to inform the table handler that we are using the table.
57
57
 
58
58
    The tables used can only be tables used in LOCK TABLES or a
59
59
    temporary table.
60
60
 
61
 
  - When statement is done, we will call ha_commit_stmt(thd);
 
61
  - When statement is done, we will call ha_commit_stmt(session);
62
62
 
63
63
  - When calling UNLOCK TABLES we call mysql_unlock_tables() for all
64
64
    tables used in LOCK TABLES
65
65
 
66
 
  If table_handler->external_lock(thd, locktype) fails, we call
67
 
  table_handler->external_lock(thd, F_UNLCK) for each table that was locked,
 
66
  If table_handler->external_lock(session, locktype) fails, we call
 
67
  table_handler->external_lock(session, F_UNLCK) for each table that was locked,
68
68
  excluding one that caused failure. That means handler must cleanup itself
69
69
  in case external_lock() fails.
70
70
 
73
73
  we are forced to use mysql_lock_merge.
74
74
*/
75
75
#include <drizzled/server_includes.h>
76
 
#include <drizzled/drizzled_error_messages.h>
 
76
#include <drizzled/error.h>
77
77
 
78
78
/**
79
79
  @defgroup Locking Locking
86
86
#define GET_LOCK_UNLOCK         1
87
87
#define GET_LOCK_STORE_LOCKS    2
88
88
 
89
 
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table,uint count,
90
 
                                 uint flags, Table **write_locked);
91
 
static int lock_external(THD *thd, Table **table,uint count);
92
 
static int unlock_external(THD *thd, Table **table,uint count);
 
89
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table,uint32_t count,
 
90
                                 uint32_t flags, Table **write_locked);
 
91
static int lock_external(Session *session, Table **table,uint32_t count);
 
92
static int unlock_external(Session *session, Table **table,uint32_t count);
93
93
static void print_lock_error(int error, const char *);
94
94
 
95
95
/*
97
97
 
98
98
  SYNOPSIS
99
99
    mysql_lock_tables()
100
 
    thd                         The current thread.
 
100
    session                         The current thread.
101
101
    tables                      An array of pointers to the tables to lock.
102
102
    count                       The number of tables to lock.
103
103
    flags                       Options:
155
155
    /* Reset lock type. */
156
156
    (*ldata)->type= TL_UNLOCK;
157
157
  }
158
 
  my_free((uchar*) sql_lock, MYF(0));
 
158
  free((unsigned char*) sql_lock);
159
159
  *mysql_lock= 0;
160
160
}
161
161
 
162
162
 
163
 
DRIZZLE_LOCK *mysql_lock_tables(THD *thd, Table **tables, uint count,
164
 
                              uint flags, bool *need_reopen)
 
163
DRIZZLE_LOCK *mysql_lock_tables(Session *session, Table **tables, uint32_t count,
 
164
                              uint32_t flags, bool *need_reopen)
165
165
{
166
166
  DRIZZLE_LOCK *sql_lock;
167
167
  Table *write_lock_used;
171
171
 
172
172
  for (;;)
173
173
  {
174
 
    if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
 
174
    if (! (sql_lock= get_lock_data(session, tables, count, GET_LOCK_STORE_LOCKS,
175
175
                                   &write_lock_used)))
176
176
      break;
177
177
 
182
182
        Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
183
183
        Wait until the lock is gone
184
184
      */
185
 
      if (wait_if_global_read_lock(thd, 1, 1))
 
185
      if (wait_if_global_read_lock(session, 1, 1))
186
186
      {
187
187
        /* Clear the lock type of all lock data to avoid reusage. */
188
188
        reset_lock_data_and_free(&sql_lock);
189
189
        break;
190
190
      }
191
 
      if (thd->version != refresh_version)
 
191
      if (session->version != refresh_version)
192
192
      {
193
193
        /* Clear the lock type of all lock data to avoid reusage. */
194
194
        reset_lock_data_and_free(&sql_lock);
199
199
    if (!(flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
200
200
        write_lock_used &&
201
201
        opt_readonly &&
202
 
        !thd->slave_thread)
 
202
        !session->slave_thread)
203
203
    {
204
204
      /*
205
205
        Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
210
210
      break;
211
211
    }
212
212
 
213
 
    thd_proc_info(thd, "System lock");
214
 
    if (sql_lock->table_count && lock_external(thd, sql_lock->table,
 
213
    session->set_proc_info("System lock");
 
214
    if (sql_lock->table_count && lock_external(session, sql_lock->table,
215
215
                                               sql_lock->table_count))
216
216
    {
217
217
      /* Clear the lock type of all lock data to avoid reusage. */
218
218
      reset_lock_data_and_free(&sql_lock);
219
219
      break;
220
220
    }
221
 
    thd_proc_info(thd, "Table lock");
 
221
    session->set_proc_info("Table lock");
222
222
    /* Copy the lock data array. thr_multi_lock() reorders its contens. */
223
223
    memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
224
224
           sql_lock->lock_count * sizeof(*sql_lock->locks));
226
226
    rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
227
227
                                                     sql_lock->lock_count,
228
228
                                                     sql_lock->lock_count,
229
 
                                                     thd->lock_id)];
 
229
                                                     session->lock_id)];
230
230
    if (rc > 1)                                 /* a timeout or a deadlock */
231
231
    {
232
232
      if (sql_lock->table_count)
233
 
        VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
 
233
        unlock_external(session, sql_lock->table, sql_lock->table_count);
234
234
      reset_lock_data_and_free(&sql_lock);
235
235
      my_error(rc, MYF(0));
236
236
      break;
237
237
    }
238
238
    else if (rc == 1)                           /* aborted */
239
239
    {
240
 
      thd->some_tables_deleted=1;               // Try again
 
240
      session->some_tables_deleted=1;           // Try again
241
241
      sql_lock->lock_count= 0;                  // Locks are already freed
242
242
      // Fall through: unlock, reset lock data, free and retry
243
243
    }
244
 
    else if (!thd->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
 
244
    else if (!session->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
245
245
    {
246
246
      /*
247
247
        Thread was killed or lock aborted. Let upper level close all
249
249
      */
250
250
      break;
251
251
    }
252
 
    else if (!thd->open_tables)
 
252
    else if (!session->open_tables)
253
253
    {
254
254
      // Only using temporary tables, no need to unlock
255
 
      thd->some_tables_deleted=0;
 
255
      session->some_tables_deleted=0;
256
256
      break;
257
257
    }
258
 
    thd_proc_info(thd, 0);
 
258
    session->set_proc_info(0);
259
259
 
260
260
    /* going to retry, unlock all tables */
261
261
    if (sql_lock->lock_count)
262
262
        thr_multi_unlock(sql_lock->locks, sql_lock->lock_count);
263
263
 
264
264
    if (sql_lock->table_count)
265
 
      VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
 
265
      unlock_external(session, sql_lock->table, sql_lock->table_count);
266
266
 
267
267
    /*
268
268
      If thr_multi_lock fails it resets lock type for tables, which
276
276
      *need_reopen= true;
277
277
      break;
278
278
    }
279
 
    if (wait_for_tables(thd))
 
279
    if (wait_for_tables(session))
280
280
      break;                                    // Couldn't open tables
281
281
  }
282
 
  thd_proc_info(thd, 0);
283
 
  if (thd->killed)
 
282
  session->set_proc_info(0);
 
283
  if (session->killed)
284
284
  {
285
 
    thd->send_kill_message();
 
285
    session->send_kill_message();
286
286
    if (sql_lock)
287
287
    {
288
 
      mysql_unlock_tables(thd,sql_lock);
 
288
      mysql_unlock_tables(session,sql_lock);
289
289
      sql_lock=0;
290
290
    }
291
291
  }
292
292
 
293
 
  thd->set_time_after_lock();
 
293
  session->set_time_after_lock();
294
294
  return (sql_lock);
295
295
}
296
296
 
297
297
 
298
 
static int lock_external(THD *thd, Table **tables, uint count)
 
298
static int lock_external(Session *session, Table **tables, uint32_t count)
299
299
{
300
 
  register uint i;
 
300
  register uint32_t i;
301
301
  int lock_type,error;
302
302
  for (i=1 ; i <= count ; i++, tables++)
303
303
  {
308
308
         (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
309
309
      lock_type=F_RDLCK;
310
310
 
311
 
    if ((error=(*tables)->file->ha_external_lock(thd,lock_type)))
 
311
    if ((error=(*tables)->file->ha_external_lock(session,lock_type)))
312
312
    {
313
313
      print_lock_error(error, (*tables)->file->table_type());
314
314
      while (--i)
315
315
      {
316
316
        tables--;
317
 
        (*tables)->file->ha_external_lock(thd, F_UNLCK);
 
317
        (*tables)->file->ha_external_lock(session, F_UNLCK);
318
318
        (*tables)->current_lock=F_UNLCK;
319
319
      }
320
320
      return(error);
329
329
}
330
330
 
331
331
 
332
 
void mysql_unlock_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
 
332
void mysql_unlock_tables(Session *session, DRIZZLE_LOCK *sql_lock)
333
333
{
334
334
  if (sql_lock->lock_count)
335
335
    thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
336
336
  if (sql_lock->table_count)
337
 
    VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
338
 
  my_free((uchar*) sql_lock,MYF(0));
 
337
    unlock_external(session,sql_lock->table,sql_lock->table_count);
 
338
  free((unsigned char*) sql_lock);
339
339
  return;
340
340
}
341
341
 
345
345
  This will work even if get_lock_data fails (next unlock will free all)
346
346
*/
347
347
 
348
 
void mysql_unlock_some_tables(THD *thd, Table **table,uint count)
 
348
void mysql_unlock_some_tables(Session *session, Table **table,uint32_t count)
349
349
{
350
350
  DRIZZLE_LOCK *sql_lock;
351
351
  Table *write_lock_used;
352
 
  if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
 
352
  if ((sql_lock= get_lock_data(session, table, count, GET_LOCK_UNLOCK,
353
353
                               &write_lock_used)))
354
 
    mysql_unlock_tables(thd, sql_lock);
 
354
    mysql_unlock_tables(session, sql_lock);
355
355
}
356
356
 
357
357
 
359
359
  unlock all tables locked for read.
360
360
*/
361
361
 
362
 
void mysql_unlock_read_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
 
362
void mysql_unlock_read_tables(Session *session, DRIZZLE_LOCK *sql_lock)
363
363
{
364
 
  uint i,found;
 
364
  uint32_t i,found;
365
365
 
366
366
  /* Move all write locks first */
367
367
  THR_LOCK_DATA **lock=sql_lock->locks;
397
397
  /* Unlock all read locked tables */
398
398
  if (i != found)
399
399
  {
400
 
    VOID(unlock_external(thd,table,i-found));
 
400
    unlock_external(session,table,i-found);
401
401
    sql_lock->table_count=found;
402
402
  }
403
403
  /* Fix the lock positions in Table */
428
428
  unlock_external() we call handler::external_lock(F_UNLCK) only
429
429
  if table->current_lock is not F_UNLCK.
430
430
 
431
 
  @param  thd             thread context
 
431
  @param  session             thread context
432
432
  @param  locked          list of locked tables
433
433
  @param  table           the table to unlock
434
434
  @param  always_unlock   specify explicitly if the legacy side
435
435
                          effect is desired.
436
436
*/
437
437
 
438
 
void mysql_lock_remove(THD *thd, DRIZZLE_LOCK *locked,Table *table,
 
438
void mysql_lock_remove(Session *session, DRIZZLE_LOCK *locked,Table *table,
439
439
                       bool always_unlock)
440
440
{
441
441
  if (always_unlock == true)
442
 
    mysql_unlock_some_tables(thd, &table, /* table count */ 1);
 
442
    mysql_unlock_some_tables(session, &table, /* table count */ 1);
443
443
  if (locked)
444
444
  {
445
 
    register uint i;
 
445
    register uint32_t i;
446
446
    for (i=0; i < locked->table_count; i++)
447
447
    {
448
448
      if (locked->table[i] == table)
449
449
      {
450
 
        uint  j, removed_locks, old_tables;
 
450
        uint32_t  j, removed_locks, old_tables;
451
451
        Table *tbl;
452
 
        uint lock_data_end;
 
452
        uint32_t lock_data_end;
453
453
 
454
454
        assert(table->lock_position == i);
455
455
 
456
456
        /* Unlock if not yet unlocked */
457
457
        if (always_unlock == false)
458
 
          mysql_unlock_some_tables(thd, &table, /* table count */ 1);
 
458
          mysql_unlock_some_tables(session, &table, /* table count */ 1);
459
459
 
460
460
        /* Decrement table_count in advance, making below expressions easier */
461
461
        old_tables= --locked->table_count;
500
500
 
501
501
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
502
502
 
503
 
void mysql_lock_downgrade_write(THD *thd, Table *table,
 
503
void mysql_lock_downgrade_write(Session *session, Table *table,
504
504
                                thr_lock_type new_lock_type)
505
505
{
506
506
  DRIZZLE_LOCK *locked;
507
507
  Table *write_lock_used;
508
 
  if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
 
508
  if ((locked = get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
509
509
                              &write_lock_used)))
510
510
  {
511
 
    for (uint i=0; i < locked->lock_count; i++)
 
511
    for (uint32_t i=0; i < locked->lock_count; i++)
512
512
      thr_downgrade_write_lock(locked->locks[i], new_lock_type);
513
 
    my_free((uchar*) locked,MYF(0));
 
513
    free((unsigned char*) locked);
514
514
  }
515
515
}
516
516
 
517
517
 
518
518
/** Abort all other threads waiting to get lock in table. */
519
519
 
520
 
void mysql_lock_abort(THD *thd, Table *table, bool upgrade_lock)
 
520
void mysql_lock_abort(Session *session, Table *table, bool upgrade_lock)
521
521
{
522
522
  DRIZZLE_LOCK *locked;
523
523
  Table *write_lock_used;
524
524
 
525
 
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
 
525
  if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
526
526
                             &write_lock_used)))
527
527
  {
528
 
    for (uint i=0; i < locked->lock_count; i++)
 
528
    for (uint32_t i=0; i < locked->lock_count; i++)
529
529
      thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
530
 
    my_free((uchar*) locked,MYF(0));
 
530
    free((unsigned char*) locked);
531
531
  }
532
532
  return;
533
533
}
536
536
/**
537
537
  Abort one thread / table combination.
538
538
 
539
 
  @param thd       Thread handler
 
539
  @param session           Thread handler
540
540
  @param table     Table that should be removed from lock queue
541
541
 
542
542
  @retval
545
545
    1  Table was locked by at least one other thread
546
546
*/
547
547
 
548
 
bool mysql_lock_abort_for_thread(THD *thd, Table *table)
 
548
bool mysql_lock_abort_for_thread(Session *session, Table *table)
549
549
{
550
550
  DRIZZLE_LOCK *locked;
551
551
  Table *write_lock_used;
552
552
  bool result= false;
553
553
 
554
 
  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
 
554
  if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
555
555
                             &write_lock_used)))
556
556
  {
557
 
    for (uint i=0; i < locked->lock_count; i++)
 
557
    for (uint32_t i=0; i < locked->lock_count; i++)
558
558
    {
559
559
      if (thr_abort_locks_for_thread(locked->locks[i]->lock,
560
560
                                     table->in_use->thread_id))
561
561
        result= true;
562
562
    }
563
 
    my_free((uchar*) locked,MYF(0));
 
563
    free((unsigned char*) locked);
564
564
  }
565
565
  return(result);
566
566
}
601
601
  }
602
602
 
603
603
  /* Delete old, not needed locks */
604
 
  my_free((uchar*) a,MYF(0));
605
 
  my_free((uchar*) b,MYF(0));
 
604
  free((unsigned char*) a);
 
605
  free((unsigned char*) b);
606
606
  return(sql_lock);
607
607
}
608
608
 
614
614
  get_lock_data(). If we allow two opens on temporary tables later,
615
615
  both functions should be checked.
616
616
 
617
 
  @param thd                 The current thread.
 
617
  @param session                 The current thread.
618
618
  @param needle              The table to check for duplicate lock.
619
619
  @param haystack            The list of tables to search for the dup lock.
620
620
 
630
630
    !NULL   First table from 'haystack' that matches a lock on 'needle'.
631
631
*/
632
632
 
633
 
TableList *mysql_lock_have_duplicate(THD *thd, TableList *needle,
 
633
TableList *mysql_lock_have_duplicate(Session *session, TableList *needle,
634
634
                                      TableList *haystack)
635
635
{
636
636
  DRIZZLE_LOCK            *mylock;
655
655
    goto end;
656
656
 
657
657
  /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
658
 
  if (! (mylock= thd->lock ? thd->lock : thd->locked_tables))
 
658
  if (! (mylock= session->lock ? session->lock : session->locked_tables))
659
659
    goto end;
660
660
 
661
661
  /* If we have less than two tables, we cannot have duplicates. */
710
710
 
711
711
/** Unlock a set of external. */
712
712
 
713
 
static int unlock_external(THD *thd, Table **table,uint count)
 
713
static int unlock_external(Session *session, Table **table,uint32_t count)
714
714
{
715
715
  int error,error_code;
716
716
 
720
720
    if ((*table)->current_lock != F_UNLCK)
721
721
    {
722
722
      (*table)->current_lock = F_UNLCK;
723
 
      if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK)))
 
723
      if ((error=(*table)->file->ha_external_lock(session, F_UNLCK)))
724
724
      {
725
725
        error_code=error;
726
726
        print_lock_error(error_code, (*table)->file->table_type());
735
735
/**
736
736
  Get lock structures from table structs and initialize locks.
737
737
 
738
 
  @param thd                Thread handler
 
738
  @param session                    Thread handler
739
739
  @param table_ptr          Pointer to tables that should be locks
740
740
  @param flags              One of:
741
741
           - GET_LOCK_UNLOCK      : If we should send TL_IGNORE to store lock
743
743
  @param write_lock_used   Store pointer to last table with WRITE_ALLOW_WRITE
744
744
*/
745
745
 
746
 
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table_ptr, uint count,
747
 
                                 uint flags, Table **write_lock_used)
 
746
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table_ptr, uint32_t count,
 
747
                                 uint32_t flags, Table **write_lock_used)
748
748
{
749
 
  uint i,tables,lock_count;
 
749
  uint32_t i,tables,lock_count;
750
750
  DRIZZLE_LOCK *sql_lock;
751
751
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
752
752
  Table **to, **table_buf;
803
803
      }
804
804
    }
805
805
    locks_start= locks;
806
 
    locks= table->file->store_lock(thd, locks,
 
806
    locks= table->file->store_lock(session, locks,
807
807
                                   (flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
808
808
                                   lock_type);
809
809
    if (flags & GET_LOCK_STORE_LOCKS)
841
841
/**
842
842
  Lock and wait for the named lock.
843
843
 
844
 
  @param thd                    Thread handler
 
844
  @param session                        Thread handler
845
845
  @param table_list             Lock first table in this list
846
846
 
847
847
 
854
854
    1   error
855
855
*/
856
856
 
857
 
int lock_and_wait_for_table_name(THD *thd, TableList *table_list)
 
857
int lock_and_wait_for_table_name(Session *session, TableList *table_list)
858
858
{
859
859
  int lock_retcode;
860
860
  int error= -1;
861
861
 
862
 
  if (wait_if_global_read_lock(thd, 0, 1))
 
862
  if (wait_if_global_read_lock(session, 0, 1))
863
863
    return(1);
864
 
  VOID(pthread_mutex_lock(&LOCK_open));
865
 
  if ((lock_retcode = lock_table_name(thd, table_list, true)) < 0)
 
864
  pthread_mutex_lock(&LOCK_open);
 
865
  if ((lock_retcode = lock_table_name(session, table_list, true)) < 0)
866
866
    goto end;
867
 
  if (lock_retcode && wait_for_locked_table_names(thd, table_list))
 
867
  if (lock_retcode && wait_for_locked_table_names(session, table_list))
868
868
  {
869
 
    unlock_table_name(thd, table_list);
 
869
    unlock_table_name(session, table_list);
870
870
    goto end;
871
871
  }
872
872
  error=0;
873
873
 
874
874
end:
875
875
  pthread_mutex_unlock(&LOCK_open);
876
 
  start_waiting_global_read_lock(thd);
 
876
  start_waiting_global_read_lock(session);
877
877
  return(error);
878
878
}
879
879
 
881
881
/**
882
882
  Put a not open table with an old refresh version in the table cache.
883
883
 
884
 
  @param thd                    Thread handler
 
884
  @param session                        Thread handler
885
885
  @param table_list             Lock first table in this list
886
886
  @param check_in_use           Do we need to check if table already in use by us
887
887
 
905
905
    > 0  table locked, but someone is using it
906
906
*/
907
907
 
908
 
int lock_table_name(THD *thd, TableList *table_list, bool check_in_use)
 
908
int lock_table_name(Session *session, TableList *table_list, bool check_in_use)
909
909
{
910
910
  Table *table;
911
911
  char  key[MAX_DBKEY_LENGTH];
912
912
  char *db= table_list->db;
913
 
  uint  key_length;
 
913
  uint32_t  key_length;
914
914
  bool  found_locked_table= false;
915
915
  HASH_SEARCH_STATE state;
916
916
 
917
 
  key_length= create_table_def_key(thd, key, table_list, 0);
 
917
  key_length= create_table_def_key(session, key, table_list, 0);
918
918
 
919
919
  if (check_in_use)
920
920
  {
921
921
    /* Only insert the table if we haven't insert it already */
922
 
    for (table=(Table*) hash_first(&open_cache, (uchar*)key,
 
922
    for (table=(Table*) hash_first(&open_cache, (unsigned char*)key,
923
923
                                   key_length, &state);
924
924
         table ;
925
 
         table = (Table*) hash_next(&open_cache,(uchar*) key,
 
925
         table = (Table*) hash_next(&open_cache,(unsigned char*) key,
926
926
                                    key_length, &state))
927
927
    {
928
928
      if (table->reginfo.lock_type < TL_WRITE)
929
929
      {
930
 
        if (table->in_use == thd)
 
930
        if (table->in_use == session)
931
931
          found_locked_table= true;
932
932
        continue;
933
933
      }
934
934
 
935
 
      if (table->in_use == thd)
 
935
      if (table->in_use == session)
936
936
      {
937
937
        table->s->version= 0;                  // Ensure no one can use this
938
938
        table->locked_by_name= 1;
941
941
    }
942
942
  }
943
943
 
944
 
  if (thd->locked_tables && thd->locked_tables->table_count &&
945
 
      ! find_temporary_table(thd, table_list->db, table_list->table_name))
 
944
  if (session->locked_tables && session->locked_tables->table_count &&
 
945
      ! find_temporary_table(session, table_list->db, table_list->table_name))
946
946
  {
947
947
    if (found_locked_table)
948
948
      my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
952
952
    return(-1);
953
953
  }
954
954
 
955
 
  if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
 
955
  if (!(table= table_cache_insert_placeholder(session, key, key_length)))
956
956
    return(-1);
957
957
 
958
958
  table_list->table=table;
959
959
 
960
960
  /* Return 1 if table is in use */
961
 
  return(test(remove_table_from_cache(thd, db, table_list->table_name,
 
961
  return(test(remove_table_from_cache(session, db, table_list->table_name,
962
962
             check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
963
963
}
964
964
 
965
965
 
966
 
void unlock_table_name(THD *thd __attribute__((unused)),
 
966
void unlock_table_name(Session *session __attribute__((unused)),
967
967
                       TableList *table_list)
968
968
{
969
969
  if (table_list->table)
970
970
  {
971
 
    hash_delete(&open_cache, (uchar*) table_list->table);
 
971
    hash_delete(&open_cache, (unsigned char*) table_list->table);
972
972
    broadcast_refresh();
973
973
  }
974
974
}
975
975
 
976
976
 
977
 
static bool locked_named_table(THD *thd __attribute__((unused)),
 
977
static bool locked_named_table(Session *session __attribute__((unused)),
978
978
                               TableList *table_list)
979
979
{
980
980
  for (; table_list ; table_list=table_list->next_local)
995
995
}
996
996
 
997
997
 
998
 
bool wait_for_locked_table_names(THD *thd, TableList *table_list)
 
998
bool wait_for_locked_table_names(Session *session, TableList *table_list)
999
999
{
1000
1000
  bool result=0;
1001
1001
 
1002
1002
  safe_mutex_assert_owner(&LOCK_open);
1003
1003
 
1004
 
  while (locked_named_table(thd,table_list))
 
1004
  while (locked_named_table(session,table_list))
1005
1005
  {
1006
 
    if (thd->killed)
 
1006
    if (session->killed)
1007
1007
    {
1008
1008
      result=1;
1009
1009
      break;
1010
1010
    }
1011
 
    wait_for_condition(thd, &LOCK_open, &COND_refresh);
 
1011
    wait_for_condition(session, &LOCK_open, &COND_refresh);
1012
1012
    pthread_mutex_lock(&LOCK_open);
1013
1013
  }
1014
1014
  return(result);
1021
1021
  REQUIREMENTS
1022
1022
  - One must have a lock on LOCK_open when calling this
1023
1023
 
1024
 
  @param thd                    Thread handle
 
1024
  @param session                        Thread handle
1025
1025
  @param table_list             Names of tables to lock
1026
1026
 
1027
1027
  @note
1034
1034
    1   Fatal error (end of memory ?)
1035
1035
*/
1036
1036
 
1037
 
bool lock_table_names(THD *thd, TableList *table_list)
 
1037
bool lock_table_names(Session *session, TableList *table_list)
1038
1038
{
1039
1039
  bool got_all_locks=1;
1040
1040
  TableList *lock_table;
1042
1042
  for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1043
1043
  {
1044
1044
    int got_lock;
1045
 
    if ((got_lock=lock_table_name(thd,lock_table, true)) < 0)
 
1045
    if ((got_lock=lock_table_name(session,lock_table, true)) < 0)
1046
1046
      goto end;                                 // Fatal error
1047
1047
    if (got_lock)
1048
1048
      got_all_locks=0;                          // Someone is using table
1049
1049
  }
1050
1050
 
1051
1051
  /* If some table was in use, wait until we got the lock */
1052
 
  if (!got_all_locks && wait_for_locked_table_names(thd, table_list))
 
1052
  if (!got_all_locks && wait_for_locked_table_names(session, table_list))
1053
1053
    goto end;
1054
1054
  return 0;
1055
1055
 
1056
1056
end:
1057
 
  unlock_table_names(thd, table_list, lock_table);
 
1057
  unlock_table_names(session, table_list, lock_table);
1058
1058
  return 1;
1059
1059
}
1060
1060
 
1062
1062
/**
1063
1063
  Unlock all tables in list with a name lock.
1064
1064
 
1065
 
  @param thd        Thread handle.
 
1065
  @param session        Thread handle.
1066
1066
  @param table_list Names of tables to lock.
1067
1067
 
1068
1068
  @note 
1078
1078
  @retval FALSE Name lock successfully acquired.
1079
1079
*/
1080
1080
 
1081
 
bool lock_table_names_exclusively(THD *thd, TableList *table_list)
 
1081
bool lock_table_names_exclusively(Session *session, TableList *table_list)
1082
1082
{
1083
 
  if (lock_table_names(thd, table_list))
 
1083
  if (lock_table_names(session, table_list))
1084
1084
    return true;
1085
1085
 
1086
1086
  /*
1098
1098
/**
1099
1099
  Test is 'table' is protected by an exclusive name lock.
1100
1100
 
1101
 
  @param[in] thd        The current thread handler
 
1101
  @param[in] session        The current thread handler
1102
1102
  @param[in] table_list Table container containing the single table to be
1103
1103
                        tested
1104
1104
 
1110
1110
*/
1111
1111
 
1112
1112
bool
1113
 
is_table_name_exclusively_locked_by_this_thread(THD *thd,
 
1113
is_table_name_exclusively_locked_by_this_thread(Session *session,
1114
1114
                                                TableList *table_list)
1115
1115
{
1116
1116
  char  key[MAX_DBKEY_LENGTH];
1117
 
  uint  key_length;
1118
 
 
1119
 
  key_length= create_table_def_key(thd, key, table_list, 0);
1120
 
 
1121
 
  return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
 
1117
  uint32_t  key_length;
 
1118
 
 
1119
  key_length= create_table_def_key(session, key, table_list, 0);
 
1120
 
 
1121
  return is_table_name_exclusively_locked_by_this_thread(session, (unsigned char *)key,
1122
1122
                                                         key_length);
1123
1123
}
1124
1124
 
1126
1126
/**
1127
1127
  Test is 'table key' is protected by an exclusive name lock.
1128
1128
 
1129
 
  @param[in] thd        The current thread handler.
 
1129
  @param[in] session        The current thread handler.
1130
1130
  @param[in] key
1131
1131
  @param[in] key_length
1132
1132
 
1137
1137
 */
1138
1138
 
1139
1139
bool
1140
 
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
 
1140
is_table_name_exclusively_locked_by_this_thread(Session *session, unsigned char *key,
1141
1141
                                                int key_length)
1142
1142
{
1143
1143
  HASH_SEARCH_STATE state;
1149
1149
       table= (Table*) hash_next(&open_cache, key,
1150
1150
                                 key_length, &state))
1151
1151
  {
1152
 
    if (table->in_use == thd &&
 
1152
    if (table->in_use == session &&
1153
1153
        table->open_placeholder == 1 &&
1154
1154
        table->s->version == 0)
1155
1155
      return true;
1162
1162
  Unlock all tables in list with a name lock.
1163
1163
 
1164
1164
  @param
1165
 
    thd                 Thread handle
 
1165
    session                     Thread handle
1166
1166
  @param
1167
1167
    table_list          Names of tables to unlock
1168
1168
  @param
1182
1182
    1   Fatal error (end of memory ?)
1183
1183
*/
1184
1184
 
1185
 
void unlock_table_names(THD *thd, TableList *table_list,
 
1185
void unlock_table_names(Session *session, TableList *table_list,
1186
1186
                        TableList *last_table)
1187
1187
{
1188
1188
  for (TableList *table= table_list;
1189
1189
       table != last_table;
1190
1190
       table= table->next_local)
1191
 
    unlock_table_name(thd,table);
 
1191
    unlock_table_name(session,table);
1192
1192
  broadcast_refresh();
1193
1193
  return;
1194
1194
}
1285
1285
  If we have merged 1) and 3) into 1), we would have had this deadlock:
1286
1286
  imagine thread 1 and 2, in non-autocommit mode, thread 3, and an InnoDB
1287
1287
  table t.
1288
 
  thd1: SELECT * FROM t FOR UPDATE;
1289
 
  thd2: UPDATE t SET a=1; # blocked by row-level locks of thd1
1290
 
  thd3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
1291
 
  table instance of thd2
1292
 
  thd1: COMMIT; # blocked by thd3.
1293
 
  thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock.
 
1288
  session1: SELECT * FROM t FOR UPDATE;
 
1289
  session2: UPDATE t SET a=1; # blocked by row-level locks of session1
 
1290
  session3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
 
1291
  table instance of session2
 
1292
  session1: COMMIT; # blocked by session3.
 
1293
  session1 blocks session2 which blocks session3 which blocks session1: deadlock.
1294
1294
 
1295
1295
  Note that we need to support that one thread does
1296
1296
  FLUSH TABLES WITH READ LOCK; and then COMMIT;
1300
1300
 
1301
1301
****************************************************************************/
1302
1302
 
1303
 
volatile uint global_read_lock=0;
1304
 
volatile uint global_read_lock_blocks_commit=0;
1305
 
static volatile uint protect_against_global_read_lock=0;
1306
 
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;
1307
1307
 
1308
1308
#define GOT_GLOBAL_READ_LOCK               1
1309
1309
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
1310
1310
 
1311
 
bool lock_global_read_lock(THD *thd)
 
1311
bool lock_global_read_lock(Session *session)
1312
1312
{
1313
 
  if (!thd->global_read_lock)
 
1313
  if (!session->global_read_lock)
1314
1314
  {
1315
1315
    const char *old_message;
1316
1316
    (void) pthread_mutex_lock(&LOCK_global_read_lock);
1317
 
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
 
1317
    old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1318
1318
                                "Waiting to get readlock");
1319
1319
 
1320
1320
    waiting_for_read_lock++;
1321
 
    while (protect_against_global_read_lock && !thd->killed)
 
1321
    while (protect_against_global_read_lock && !session->killed)
1322
1322
      pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1323
1323
    waiting_for_read_lock--;
1324
 
    if (thd->killed)
 
1324
    if (session->killed)
1325
1325
    {
1326
 
      thd->exit_cond(old_message);
 
1326
      session->exit_cond(old_message);
1327
1327
      return(1);
1328
1328
    }
1329
 
    thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
 
1329
    session->global_read_lock= GOT_GLOBAL_READ_LOCK;
1330
1330
    global_read_lock++;
1331
 
    thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
 
1331
    session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1332
1332
  }
1333
1333
  /*
1334
1334
    We DON'T set global_read_lock_blocks_commit now, it will be set after
1342
1342
}
1343
1343
 
1344
1344
 
1345
 
void unlock_global_read_lock(THD *thd)
 
1345
void unlock_global_read_lock(Session *session)
1346
1346
{
1347
 
  uint tmp;
 
1347
  uint32_t tmp;
1348
1348
 
1349
1349
  pthread_mutex_lock(&LOCK_global_read_lock);
1350
1350
  tmp= --global_read_lock;
1351
 
  if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
 
1351
  if (session->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
1352
1352
    --global_read_lock_blocks_commit;
1353
1353
  pthread_mutex_unlock(&LOCK_global_read_lock);
1354
1354
  /* Send the signal outside the mutex to avoid a context switch */
1356
1356
  {
1357
1357
    pthread_cond_broadcast(&COND_global_read_lock);
1358
1358
  }
1359
 
  thd->global_read_lock= 0;
 
1359
  session->global_read_lock= 0;
1360
1360
 
1361
1361
  return;
1362
1362
}
1365
1365
                   (is_not_commit ||                               \
1366
1366
                    global_read_lock_blocks_commit))
1367
1367
 
1368
 
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
 
1368
bool wait_if_global_read_lock(Session *session, bool abort_on_refresh,
1369
1369
                              bool is_not_commit)
1370
1370
{
1371
1371
  const char *old_message= NULL;
1381
1381
  (void) pthread_mutex_lock(&LOCK_global_read_lock);
1382
1382
  if ((need_exit_cond= must_wait))
1383
1383
  {
1384
 
    if (thd->global_read_lock)          // This thread had the read locks
 
1384
    if (session->global_read_lock)              // This thread had the read locks
1385
1385
    {
1386
1386
      if (is_not_commit)
1387
1387
        my_message(ER_CANT_UPDATE_WITH_READLOCK,
1394
1394
      */
1395
1395
      return(is_not_commit);
1396
1396
    }
1397
 
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
 
1397
    old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1398
1398
                                "Waiting for release of readlock");
1399
 
    while (must_wait && ! thd->killed &&
1400
 
           (!abort_on_refresh || thd->version == refresh_version))
 
1399
    while (must_wait && ! session->killed &&
 
1400
           (!abort_on_refresh || session->version == refresh_version))
1401
1401
    {
1402
1402
      (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1403
1403
    }
1404
 
    if (thd->killed)
 
1404
    if (session->killed)
1405
1405
      result=1;
1406
1406
  }
1407
1407
  if (!abort_on_refresh && !result)
1411
1411
    and if old_message is set
1412
1412
  */
1413
1413
  if (unlikely(need_exit_cond))
1414
 
    thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
 
1414
    session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1415
1415
  else
1416
1416
    pthread_mutex_unlock(&LOCK_global_read_lock);
1417
1417
  return(result);
1418
1418
}
1419
1419
 
1420
1420
 
1421
 
void start_waiting_global_read_lock(THD *thd)
 
1421
void start_waiting_global_read_lock(Session *session)
1422
1422
{
1423
1423
  bool tmp;
1424
 
  if (unlikely(thd->global_read_lock))
 
1424
  if (unlikely(session->global_read_lock))
1425
1425
    return;
1426
1426
  (void) pthread_mutex_lock(&LOCK_global_read_lock);
1427
1427
  tmp= (!--protect_against_global_read_lock &&
1433
1433
}
1434
1434
 
1435
1435
 
1436
 
bool make_global_read_lock_block_commit(THD *thd)
 
1436
bool make_global_read_lock_block_commit(Session *session)
1437
1437
{
1438
1438
  bool error;
1439
1439
  const char *old_message;
1441
1441
    If we didn't succeed lock_global_read_lock(), or if we already suceeded
1442
1442
    make_global_read_lock_block_commit(), do nothing.
1443
1443
  */
1444
 
  if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
 
1444
  if (session->global_read_lock != GOT_GLOBAL_READ_LOCK)
1445
1445
    return(0);
1446
1446
  pthread_mutex_lock(&LOCK_global_read_lock);
1447
1447
  /* increment this BEFORE waiting on cond (otherwise race cond) */
1448
1448
  global_read_lock_blocks_commit++;
1449
1449
  /* For testing we set up some blocking, to see if we can be killed */
1450
1450
  protect_against_global_read_lock++;
1451
 
  old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
 
1451
  old_message= session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1452
1452
                               "Waiting for all running commits to finish");
1453
 
  while (protect_against_global_read_lock && !thd->killed)
 
1453
  while (protect_against_global_read_lock && !session->killed)
1454
1454
    pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1455
1455
  protect_against_global_read_lock--;
1456
 
  if ((error= test(thd->killed)))
 
1456
  if ((error= test(session->killed)))
1457
1457
    global_read_lock_blocks_commit--; // undo what we did
1458
1458
  else
1459
 
    thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1460
 
  thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
 
1459
    session->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
 
1460
  session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1461
1461
  return(error);
1462
1462
}
1463
1463
 
1483
1483
 
1484
1484
void broadcast_refresh(void)
1485
1485
{
1486
 
  VOID(pthread_cond_broadcast(&COND_refresh));
1487
 
  VOID(pthread_cond_broadcast(&COND_global_read_lock));
 
1486
  pthread_cond_broadcast(&COND_refresh);
 
1487
  pthread_cond_broadcast(&COND_global_read_lock);
1488
1488
}
1489
1489
 
1490
1490
 
1493
1493
 
1494
1494
  SYNOPSIS
1495
1495
    try_transactional_lock()
1496
 
      thd                       Thread handle
 
1496
      session                       Thread handle
1497
1497
      table_list                List of tables to lock
1498
1498
 
1499
1499
  DESCRIPTION
1506
1506
    -1                  Error: no recovery possible.
1507
1507
*/
1508
1508
 
1509
 
int try_transactional_lock(THD *thd, TableList *table_list)
 
1509
int try_transactional_lock(Session *session, TableList *table_list)
1510
1510
{
1511
 
  uint          dummy_counter;
 
1511
  uint32_t          dummy_counter;
1512
1512
  int           error;
1513
1513
  int           result= 0;
1514
1514
 
1515
1515
  /* Need to open the tables to be able to access engine methods. */
1516
 
  if (open_tables(thd, &table_list, &dummy_counter, 0))
 
1516
  if (open_tables(session, &table_list, &dummy_counter, 0))
1517
1517
  {
1518
1518
    /* purecov: begin tested */
1519
1519
    return(-1);
1521
1521
  }
1522
1522
 
1523
1523
  /* Required by InnoDB. */
1524
 
  thd->in_lock_tables= true;
 
1524
  session->in_lock_tables= true;
1525
1525
 
1526
 
  if ((error= set_handler_table_locks(thd, table_list, true)))
 
1526
  if ((error= set_handler_table_locks(session, table_list, true)))
1527
1527
  {
1528
1528
    /*
1529
1529
      Not all transactional locks could be taken. If the error was
1546
1546
 
1547
1547
 err:
1548
1548
  /* We need to explicitly commit if autocommit mode is active. */
1549
 
  (void) ha_autocommit_or_rollback(thd, 0);
 
1549
  (void) ha_autocommit_or_rollback(session, 0);
1550
1550
  /* Close the tables. The locks (if taken) persist in the storage engines. */
1551
 
  close_tables_for_reopen(thd, &table_list);
1552
 
  thd->in_lock_tables= false;
 
1551
  close_tables_for_reopen(session, &table_list);
 
1552
  session->in_lock_tables= false;
1553
1553
  return(result);
1554
1554
}
1555
1555
 
1559
1559
 
1560
1560
  SYNOPSIS
1561
1561
    check_transactional_lock()
1562
 
      thd                       Thread handle
 
1562
      session                       Thread handle
1563
1563
      table_list                List of tables to lock
1564
1564
 
1565
1565
  DESCRIPTION
1579
1579
    -1                  Error: Lock conversion is prohibited.
1580
1580
*/
1581
1581
 
1582
 
int check_transactional_lock(THD *thd, TableList *table_list)
 
1582
int check_transactional_lock(Session *session, TableList *table_list)
1583
1583
{
1584
1584
  TableList    *tlist;
1585
1585
  int           result= 0;
1608
1608
    }
1609
1609
 
1610
1610
    /* We must not convert the lock method within an active transaction. */
1611
 
    if (thd->active_transaction())
 
1611
    if (session->active_transaction())
1612
1612
    {
1613
1613
      my_error(ER_NO_AUTO_CONVERT_LOCK_TRANSACTION, MYF(0),
1614
1614
               tlist->alias ? tlist->alias : tlist->table_name);
1619
1619
    /* Warn about the conversion. */
1620
1620
    snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1621
1621
             tlist->alias ? tlist->alias : tlist->table_name);
1622
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1622
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1623
1623
                 ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1624
1624
  }
1625
1625
 
1632
1632
 
1633
1633
  SYNOPSIS
1634
1634
    set_handler_table_locks()
1635
 
      thd                       Thread handle
 
1635
      session                       Thread handle
1636
1636
      table_list                List of tables to lock
1637
1637
      transactional             If to lock transactional or non-transactional
1638
1638
 
1641
1641
    != 0                Error code from handler::lock_table().
1642
1642
*/
1643
1643
 
1644
 
int set_handler_table_locks(THD *thd, TableList *table_list,
 
1644
int set_handler_table_locks(Session *session, TableList *table_list,
1645
1645
                            bool transactional)
1646
1646
{
1647
1647
  TableList    *tlist;
1700
1700
    */
1701
1701
    if (!error || !transactional)
1702
1702
    {
1703
 
      error= tlist->table->file->lock_table(thd, lock_type, lock_timeout);
 
1703
      error= tlist->table->file->lock_table(session, lock_type, lock_timeout);
1704
1704
      if (error && transactional && (error != HA_ERR_WRONG_COMMAND))
1705
1705
        tlist->table->file->print_error(error, MYF(0));
1706
1706
    }