~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_locking.c

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