~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/locking/global.cc

  • Committer: Brian Aker
  • Date: 2010-11-27 18:27:58 UTC
  • mfrom: (1948.2.15 catalogs)
  • Revision ID: brian@tangent.org-20101127182758-dmlrboyhsazqa1tm
Merge in additiona fixes, includes a number of bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
163
163
  *mysql_lock= 0;
164
164
}
165
165
 
166
 
void DrizzleLock::reset(void)
167
 
{
168
 
  for (std::vector<THR_LOCK_DATA *>::iterator iter= locks.begin(); iter != locks.end(); iter++)
169
 
  {
170
 
    (*iter)->type= TL_UNLOCK;
171
 
  }
172
 
}
173
 
 
174
 
 
175
166
DrizzleLock *Session::lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen)
176
167
{
177
168
  DrizzleLock *sql_lock;
213
204
     * Here, we advise all storage engines involved in the
214
205
     * statement that we are starting a new statement
215
206
     */
216
 
    if (sql_lock->table_count)
 
207
    if (sql_lock->sizeTable())
217
208
    {
218
 
      size_t num_tables= sql_lock->table_count;
 
209
      size_t num_tables= sql_lock->sizeTable();
219
210
      plugin::StorageEngine *engine;
220
211
      set<size_t> involved_slots;
221
212
      for (size_t x= 1; x <= num_tables; x++, tables++)
239
230
     * of the type of lock that Drizzle intends to take on a 
240
231
     * specific table.
241
232
     */
242
 
    if (sql_lock->table_count && lock_external(sql_lock->getTable(), sql_lock->table_count))
 
233
    if (sql_lock->sizeTable() && lock_external(sql_lock->getTable(), sql_lock->sizeTable()))
243
234
    {
244
235
      /* Clear the lock type of all lock data to avoid reusage. */
245
236
      reset_lock_data_and_free(&sql_lock);
247
238
    }
248
239
    set_proc_info("Table lock");
249
240
    /* Copy the lock data array. thr_multi_lock() reorders its contens. */
250
 
    memcpy(sql_lock->getLocks() + sql_lock->lock_count,
 
241
    memcpy(sql_lock->getLocks() + sql_lock->sizeLock(),
251
242
           sql_lock->getLocks(),
252
 
           sql_lock->lock_count * sizeof(*sql_lock->getLocks()));
 
243
           sql_lock->sizeLock() * sizeof(*sql_lock->getLocks()));
253
244
    /* Lock on the copied half of the lock data array. */
254
245
    rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->getLocks() +
255
 
                                                     sql_lock->lock_count,
256
 
                                                     sql_lock->lock_count,
 
246
                                                     sql_lock->sizeLock(),
 
247
                                                     sql_lock->sizeLock(),
257
248
                                                     this->lock_id)];
258
249
    if (rc > 1)                                 /* a timeout or a deadlock */
259
250
    {
260
 
      if (sql_lock->table_count)
261
 
        unlock_external(sql_lock->getTable(), sql_lock->table_count);
 
251
      if (sql_lock->sizeTable())
 
252
        unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
262
253
      reset_lock_data_and_free(&sql_lock);
263
254
      my_error(rc, MYF(0));
264
255
      break;
265
256
    }
266
257
    else if (rc == 1)                           /* aborted */
267
258
    {
268
 
      some_tables_deleted= 1;           // Try again
269
 
      sql_lock->lock_count= 0;                  // Locks are already freed
 
259
      some_tables_deleted= true;                // Try again
 
260
      sql_lock->setLock(0);                  // Locks are already freed
270
261
      // Fall through: unlock, reset lock data, free and retry
271
262
    }
272
263
    else if (not some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
280
271
    else if (not open_tables)
281
272
    {
282
273
      // Only using temporary tables, no need to unlock
283
 
      some_tables_deleted= 0;
 
274
      some_tables_deleted= false;
284
275
      break;
285
276
    }
286
277
    set_proc_info(0);
287
278
 
288
279
    /* going to retry, unlock all tables */
289
 
    if (sql_lock->lock_count)
290
 
        sql_lock->unlock(sql_lock->lock_count);
 
280
    if (sql_lock->sizeLock())
 
281
        sql_lock->unlock(sql_lock->sizeLock());
291
282
 
292
 
    if (sql_lock->table_count)
293
 
      unlock_external(sql_lock->getTable(), sql_lock->table_count);
 
283
    if (sql_lock->sizeTable())
 
284
      unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
294
285
 
295
286
    /*
296
287
      If thr_multi_lock fails it resets lock type for tables, which
369
360
 
370
361
void Session::unlockTables(DrizzleLock *sql_lock)
371
362
{
372
 
  if (sql_lock->lock_count)
373
 
    sql_lock->unlock(sql_lock->lock_count);
374
 
  if (sql_lock->table_count)
375
 
    unlock_external(sql_lock->getTable(), sql_lock->table_count);
 
363
  if (sql_lock->sizeLock())
 
364
    sql_lock->unlock(sql_lock->sizeLock());
 
365
  if (sql_lock->sizeTable())
 
366
    unlock_external(sql_lock->getTable(), sql_lock->sizeTable());
376
367
  delete sql_lock;
377
368
}
378
369
 
402
393
 
403
394
  /* Move all write locks first */
404
395
  THR_LOCK_DATA **lock_local= sql_lock->getLocks();
405
 
  for (i=found=0 ; i < sql_lock->lock_count ; i++)
 
396
  for (i=found=0 ; i < sql_lock->sizeLock(); i++)
406
397
  {
407
398
    if (sql_lock->getLocks()[i]->type >= TL_WRITE_ALLOW_READ)
408
399
    {
414
405
  /* unlock the read locked tables */
415
406
  if (i != found)
416
407
  {
417
 
    sql_lock->unlock(i - found);
418
 
    sql_lock->lock_count= found;
 
408
    thr_multi_unlock(lock_local, i - found);
 
409
    sql_lock->setLock(found);
419
410
  }
420
411
 
421
412
  /* Then do the same for the external locks */
422
413
  /* Move all write locked tables first */
423
414
  Table **table= sql_lock->getTable();
424
 
  for (i=found=0 ; i < sql_lock->table_count ; i++)
 
415
  for (i=found=0 ; i < sql_lock->sizeTable() ; i++)
425
416
  {
426
417
    assert(sql_lock->getTable()[i]->lock_position == i);
427
418
    if ((uint32_t) sql_lock->getTable()[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
435
426
  if (i != found)
436
427
  {
437
428
    unlock_external(table, i - found);
438
 
    sql_lock->table_count=found;
 
429
    sql_lock->resizeTable(found);
439
430
  }
440
431
  /* Fix the lock positions in Table */
441
432
  table= sql_lock->getTable();
442
433
  found= 0;
443
 
  for (i= 0; i < sql_lock->table_count; i++)
 
434
  for (i= 0; i < sql_lock->sizeTable(); i++)
444
435
  {
445
436
    Table *tbl= *table;
446
437
    tbl->lock_position= table - sql_lock->getTable();
487
478
  if ((locked= get_lock_data(&table, 1, false,
488
479
                             &write_lock_used)))
489
480
  {
490
 
    for (uint32_t x= 0; x < locked->lock_count; x++)
 
481
    for (uint32_t x= 0; x < locked->sizeLock(); x++)
491
482
      locked->getLocks()[x]->lock->abort_locks();
492
483
    delete locked;
493
484
  }
515
506
  if ((locked= get_lock_data(&table, 1, false,
516
507
                             &write_lock_used)))
517
508
  {
518
 
    for (uint32_t i= 0; i < locked->lock_count; i++)
 
509
    for (uint32_t i= 0; i < locked->sizeLock(); i++)
519
510
    {
520
511
      if (locked->getLocks()[i]->lock->abort_locks_for_thread(table->in_use->thread_id))
521
512
        result= true;
564
555
                                    bool should_lock, Table **write_lock_used)
565
556
{
566
557
  uint32_t lock_count;
567
 
  DrizzleLock *sql_lock;
568
558
  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
569
559
  Table **to, **table_buf;
570
560
 
585
575
    update the table values. So the second part of the array is copied
586
576
    from the first part immediately before calling thr_multi_lock().
587
577
  */
588
 
  sql_lock= new DrizzleLock(lock_count, lock_count*2);
 
578
  DrizzleLock *sql_lock= new DrizzleLock(lock_count);
589
579
 
590
580
  if (not sql_lock)
591
581
    return NULL;
611
601
      {
612
602
        my_error(ER_OPEN_AS_READONLY, MYF(0), table->getAlias());
613
603
        /* Clear the lock type of the lock data that are stored already. */
614
 
        sql_lock->lock_count= locks - sql_lock->getLocks();
 
604
        sql_lock->setLock(locks - sql_lock->getLocks());
615
605
        reset_lock_data_and_free(&sql_lock);
616
606
        return NULL;
617
607
      }
641
631
    we may allocate too much, but better safe than memory overrun.
642
632
    And in the FLUSH case, the memory is released quickly anyway.
643
633
  */
644
 
  sql_lock->lock_count= locks - locks_buf;
 
634
  sql_lock->setLock(locks - locks_buf);
645
635
 
646
636
  return sql_lock;
647
637
}
1031
1021
{
1032
1022
  uint32_t tmp;
1033
1023
 
 
1024
  if (not isGlobalReadLock()) // If we have no personal stake in the global lock, just return
 
1025
    return;
 
1026
 
1034
1027
  {
1035
1028
    boost_unique_lock_t scopedLock(LOCK_global_read_lock);
1036
1029
    tmp= --global_read_lock;