~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_locking.c

  • Committer: Monty Taylor
  • Date: 2008-07-05 22:08:52 UTC
  • mto: This revision was merged to the branch mainline in revision 77.
  • Revision ID: monty@inaugust.com-20080705220852-cqd9t6tfkhvlcf73
Removed HAVE_LONG_LONG, as this is now assumed.

Show diffs side-by-side

added added

removed removed

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