~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_locking.c

Removed/replaced DBUG symbols and standardized TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
*/
22
22
 
23
23
#include "myisamdef.h"
24
 
#include <mystrings/m_ctype.h>
25
 
#include <mysys/my_tree.h>
26
 
#include <mysys/queues.h>
27
 
#include <drizzled/util/test.h>
 
24
#include <m_ctype.h>
 
25
#include <my_tree.h>
 
26
#include <queues.h>
 
27
#include <mysql/plugin.h>
28
28
 
29
29
        /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */
30
30
 
31
31
int mi_lock_database(MI_INFO *info, int lock_type)
32
32
{
33
33
  int error;
34
 
  uint32_t count;
 
34
  uint count;
35
35
  MYISAM_SHARE *share=info->s;
36
 
  uint32_t flag;
37
 
 
 
36
  uint flag;
 
37
  DBUG_ENTER("mi_lock_database");
 
38
  DBUG_PRINT("enter",("lock_type: %d  old lock %d  r_locks: %u  w_locks: %u "
 
39
                      "global_changed:  %d  open_count: %u  name: '%s'",
 
40
                      lock_type, info->lock_type, share->r_locks,
 
41
                      share->w_locks,
 
42
                      share->global_changed, share->state.open_count,
 
43
                      share->index_file_name));
38
44
  if (share->options & HA_OPTION_READ_ONLY_DATA ||
39
45
      info->lock_type == lock_type)
40
 
    return(0);
 
46
    DBUG_RETURN(0);
41
47
  if (lock_type == F_EXTRA_LCK)                 /* Used by TMP tables */
42
48
  {
43
49
    ++share->w_locks;
44
50
    ++share->tot_locks;
45
51
    info->lock_type= lock_type;
46
52
    info->s->in_use= list_add(info->s->in_use, &info->in_use);
47
 
    return(0);
 
53
    DBUG_RETURN(0);
48
54
  }
49
55
 
50
56
  flag=error=0;
77
83
      }
78
84
      if (!count)
79
85
      {
 
86
        DBUG_PRINT("info",("changed: %u  w_locks: %u",
 
87
                           (uint) share->changed, share->w_locks));
80
88
        if (share->changed && !share->w_locks)
81
89
        {
82
90
#ifdef HAVE_MMAP
117
125
          if (share->r_locks)
118
126
          {                                     /* Only read locks left */
119
127
            flag=1;
 
128
            if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
 
129
                        MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
 
130
              error=my_errno;
120
131
          }
121
132
          else if (!share->w_locks)
122
133
          {                                     /* No more locks */
123
134
            flag=1;
 
135
            if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
 
136
                        MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
 
137
              error=my_errno;
124
138
          }
125
139
        }
126
140
      }
140
154
        if (share->w_locks == 1)
141
155
        {
142
156
          flag=1;
 
157
          if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
 
158
                      MYF(MY_SEEK_NOT_DONE)))
 
159
          {
 
160
            error=my_errno;
 
161
            break;
 
162
          }
143
163
        }
144
164
        share->w_locks--;
145
165
        share->r_locks++;
149
169
      if (!share->r_locks && !share->w_locks)
150
170
      {
151
171
        flag=1;
152
 
        if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
 
172
        if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
 
173
                    info->lock_wait | MY_SEEK_NOT_DONE))
153
174
        {
154
175
          error=my_errno;
155
176
          break;
157
178
        if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
158
179
        {
159
180
          error=my_errno;
 
181
          VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
160
182
          my_errno=error;
161
183
          break;
162
184
        }
163
185
      }
164
 
      _mi_test_if_changed(info);
 
186
      VOID(_mi_test_if_changed(info));
165
187
      share->r_locks++;
166
188
      share->tot_locks++;
167
189
      info->lock_type=lock_type;
173
195
        if (share->r_locks == 1)
174
196
        {
175
197
          flag=1;
 
198
          if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
 
199
                      MYF(info->lock_wait | MY_SEEK_NOT_DONE)))
 
200
          {
 
201
            error=my_errno;
 
202
            break;
 
203
          }
176
204
          share->r_locks--;
177
205
          share->w_locks++;
178
206
          info->lock_type=lock_type;
184
212
        if (!share->w_locks)
185
213
        {
186
214
          flag=1;
 
215
          if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
 
216
                      info->lock_wait | MY_SEEK_NOT_DONE))
 
217
          {
 
218
            error=my_errno;
 
219
            break;
 
220
          }
187
221
          if (!share->r_locks)
188
222
          {
189
223
            if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
190
224
            {
191
225
              error=my_errno;
 
226
              VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
 
227
                           info->lock_wait | MY_SEEK_NOT_DONE));
192
228
              my_errno=error;
193
229
              break;
194
230
            }
195
231
          }
196
232
        }
197
233
      }
198
 
      _mi_test_if_changed(info);
 
234
      VOID(_mi_test_if_changed(info));
199
235
        
200
236
      info->lock_type=lock_type;
201
237
      info->invalidator=info->s->invalidator;
225
261
  pthread_mutex_unlock(&share->intern_lock);
226
262
#if defined(FULL_LOG) || defined(_lint)
227
263
  lock_type|=(int) (flag << 8);         /* Set bit to set if real lock */
228
 
  myisam_log_command(MI_LOG_LOCK,info,(unsigned char*) &lock_type,sizeof(lock_type),
 
264
  myisam_log_command(MI_LOG_LOCK,info,(uchar*) &lock_type,sizeof(lock_type),
229
265
                     error);
230
266
#endif
231
 
  return(error);
 
267
  DBUG_RETURN(error);
232
268
} /* mi_lock_database */
233
269
 
234
270
 
249
285
void mi_get_status(void* param, int concurrent_insert)
250
286
{
251
287
  MI_INFO *info=(MI_INFO*) param;
252
 
 
 
288
  DBUG_ENTER("mi_get_status");
 
289
  DBUG_PRINT("info",("key_file: %ld  data_file: %ld  concurrent_insert: %d",
 
290
                     (long) info->s->state.state.key_file_length,
 
291
                     (long) info->s->state.state.data_file_length,
 
292
                     concurrent_insert));
 
293
#ifndef DBUG_OFF
 
294
  if (info->state->key_file_length > info->s->state.state.key_file_length ||
 
295
      info->state->data_file_length > info->s->state.state.data_file_length)
 
296
    DBUG_PRINT("warning",("old info:  key_file: %ld  data_file: %ld",
 
297
                          (long) info->state->key_file_length,
 
298
                          (long) info->state->data_file_length));
 
299
#endif
253
300
  info->save_state=info->s->state.state;
254
301
  info->state= &info->save_state;
255
302
  info->append_insert_at_end= concurrent_insert;
256
 
  return;
 
303
  DBUG_VOID_RETURN;
257
304
}
258
305
 
259
306
 
268
315
  */
269
316
  if (info->state == &info->save_state)
270
317
  {
 
318
#ifndef DBUG_OFF
 
319
    DBUG_PRINT("info",("updating status:  key_file: %ld  data_file: %ld",
 
320
                       (long) info->state->key_file_length,
 
321
                       (long) info->state->data_file_length));
 
322
    if (info->state->key_file_length < info->s->state.state.key_file_length ||
 
323
        info->state->data_file_length < info->s->state.state.data_file_length)
 
324
      DBUG_PRINT("warning",("old info:  key_file: %ld  data_file: %ld",
 
325
                            (long) info->s->state.state.key_file_length,
 
326
                            (long) info->s->state.state.data_file_length));
 
327
#endif
271
328
    info->s->state.state= *info->state;
272
329
    info->state= &info->s->state.state;
273
330
  }
324
381
    1  not ok
325
382
*/
326
383
 
327
 
bool mi_check_status(void *param)
 
384
my_bool mi_check_status(void *param)
328
385
{
329
386
  MI_INFO *info=(MI_INFO*) param;
330
387
  /*
332
389
    external lock (in other words: w_locks == 1 means no other threads has
333
390
    a write lock)
334
391
  */
335
 
  return (bool) !(info->s->state.dellink == HA_OFFSET_ERROR ||
 
392
  DBUG_PRINT("info",("dellink: %ld  r_locks: %u  w_locks: %u",
 
393
                     (long) info->s->state.dellink, (uint) info->s->r_locks,
 
394
                     (uint) info->s->w_locks));
 
395
  return (my_bool) !(info->s->state.dellink == HA_OFFSET_ERROR ||
336
396
                     (myisam_concurrent_insert == 2 && info->s->r_locks &&
337
397
                      info->s->w_locks == 1));
338
398
}
344
404
 
345
405
int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
346
406
{
 
407
  DBUG_ENTER("_mi_readinfo");
 
408
 
347
409
  if (info->lock_type == F_UNLCK)
348
410
  {
349
411
    MYISAM_SHARE *share=info->s;
350
412
    if (!share->tot_locks)
351
413
    {
 
414
      if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
 
415
                  info->lock_wait | MY_SEEK_NOT_DONE))
 
416
        DBUG_RETURN(1);
352
417
      if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
353
418
      {
354
419
        int error=my_errno ? my_errno : -1;
 
420
        VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
 
421
                     MYF(MY_SEEK_NOT_DONE)));
355
422
        my_errno=error;
356
 
        return(1);
 
423
        DBUG_RETURN(1);
357
424
      }
358
425
    }
359
426
    if (check_keybuffer)
360
 
      _mi_test_if_changed(info);
 
427
      VOID(_mi_test_if_changed(info));
361
428
    info->invalidator=info->s->invalidator;
362
429
  }
363
430
  else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
364
431
  {
365
432
    my_errno=EACCES;                            /* Not allowed to change */
366
 
    return(-1);                         /* when have read_lock() */
 
433
    DBUG_RETURN(-1);                            /* when have read_lock() */
367
434
  }
368
 
  return(0);
 
435
  DBUG_RETURN(0);
369
436
} /* _mi_readinfo */
370
437
 
371
438
 
374
441
  request
375
442
*/
376
443
 
377
 
int _mi_writeinfo(register MI_INFO *info, uint32_t operation)
 
444
int _mi_writeinfo(register MI_INFO *info, uint operation)
378
445
{
379
446
  int error,olderror;
380
447
  MYISAM_SHARE *share=info->s;
 
448
  DBUG_ENTER("_mi_writeinfo");
 
449
  DBUG_PRINT("info",("operation: %u  tot_locks: %u", operation,
 
450
                     share->tot_locks));
381
451
 
382
452
  error=0;
383
453
  if (share->tot_locks == 0)
398
468
      }
399
469
#endif
400
470
    }
 
471
    if (!(operation & WRITEINFO_NO_UNLOCK) &&
 
472
        my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
 
473
                MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
 
474
      DBUG_RETURN(1);
401
475
    my_errno=olderror;
402
476
  }
403
477
  else if (operation)
404
478
    share->changed= 1;                  /* Mark keyfile changed */
405
 
  return(error);
 
479
  DBUG_RETURN(error);
406
480
} /* _mi_writeinfo */
407
481
 
408
482
 
416
490
      share->state.unique  != info->last_unique ||
417
491
      share->state.update_count != info->last_loop)
418
492
  {                                             /* Keyfile has changed */
 
493
    DBUG_PRINT("info",("index file changed"));
419
494
    if (share->state.process != share->this_process)
420
 
      flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE);
 
495
      VOID(flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE));
421
496
    share->last_process=share->state.process;
422
497
    info->last_unique=  share->state.unique;
423
498
    info->last_loop=    share->state.update_count;
445
520
    was incremented in the same process.
446
521
 
447
522
  This mean that if we are the only process using the file, the open_count
448
 
  tells us if the MYISAM file wasn't properly closed.*/
 
523
  tells us if the MYISAM file wasn't properly closed. (This is true if
 
524
  my_disable_locking is set).
 
525
*/
449
526
 
450
527
 
451
528
int _mi_mark_file_changed(MI_INFO *info)
452
529
{
453
 
  unsigned char buff[3];
 
530
  uchar buff[3];
454
531
  register MYISAM_SHARE *share=info->s;
 
532
  DBUG_ENTER("_mi_mark_file_changed");
455
533
 
456
534
  if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed)
457
535
  {
466
544
    {
467
545
      mi_int2store(buff,share->state.open_count);
468
546
      buff[2]=1;                                /* Mark that it's changed */
469
 
      return(my_pwrite(share->kfile,buff,sizeof(buff),
 
547
      DBUG_RETURN(my_pwrite(share->kfile,buff,sizeof(buff),
470
548
                            sizeof(share->state.header),
471
549
                            MYF(MY_NABP)));
472
550
    }
473
551
  }
474
 
  return(0);
 
552
  DBUG_RETURN(0);
475
553
}
476
554
 
477
555
 
482
560
 
483
561
int _mi_decrement_open_count(MI_INFO *info)
484
562
{
485
 
  unsigned char buff[2];
 
563
  uchar buff[2];
486
564
  register MYISAM_SHARE *share=info->s;
487
565
  int lock_error=0,write_error=0;
488
566
  if (share->global_changed)
489
567
  {
490
 
    uint32_t old_lock=info->lock_type;
 
568
    uint old_lock=info->lock_type;
491
569
    share->global_changed=0;
492
570
    lock_error=mi_lock_database(info,F_WRLCK);
493
571
    /* Its not fatal even if we couldn't get the lock ! */