~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_locking.cc

Merge Monty.

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 <m_ctype.h>
25
 
#include <my_tree.h>
26
 
#include <queues.h>
 
23
#include "myisam_priv.h"
 
24
#include "drizzled/charset_info.h"
 
25
#include <drizzled/util/test.h>
 
26
 
 
27
using namespace std;
27
28
 
28
29
        /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */
29
30
 
30
31
int mi_lock_database(MI_INFO *info, int lock_type)
31
32
{
32
33
  int error;
33
 
  uint count;
 
34
  uint32_t count;
34
35
  MYISAM_SHARE *share=info->s;
35
 
  uint flag;
36
 
 
37
 
  if (share->options & HA_OPTION_READ_ONLY_DATA ||
38
 
      info->lock_type == lock_type)
39
 
    return(0);
 
36
  uint32_t flag;
 
37
 
 
38
  pthread_mutex_lock(&share->intern_lock);
 
39
  if (!info->s->in_use)
 
40
    info->s->in_use= new list<Session *>;
 
41
 
40
42
  if (lock_type == F_EXTRA_LCK)                 /* Used by TMP tables */
41
43
  {
 
44
    pthread_mutex_unlock(&share->intern_lock);
42
45
    ++share->w_locks;
43
46
    ++share->tot_locks;
44
47
    info->lock_type= lock_type;
45
 
    info->s->in_use= list_add(info->s->in_use, &info->in_use);
 
48
    info->s->in_use->push_front(info->in_use);
46
49
    return(0);
47
50
  }
48
51
 
49
52
  flag=error=0;
50
 
  pthread_mutex_lock(&share->intern_lock);
51
53
  if (share->kfile >= 0)                /* May only be false on windows */
52
54
  {
53
55
    switch (lock_type) {
61
63
          !share->delay_key_write && flush_key_blocks(share->key_cache,
62
64
                                                      share->kfile,FLUSH_KEEP))
63
65
      {
64
 
        error=my_errno;
 
66
        error=errno;
65
67
        mi_print_error(info->s, HA_ERR_CRASHED);
66
68
        mi_mark_crashed(info);          /* Mark that table must be checked */
67
69
      }
69
71
      {
70
72
        if (end_io_cache(&info->rec_cache))
71
73
        {
72
 
          error=my_errno;
 
74
          error=errno;
73
75
          mi_print_error(info->s, HA_ERR_CRASHED);
74
76
          mi_mark_crashed(info);
75
77
        }
78
80
      {
79
81
        if (share->changed && !share->w_locks)
80
82
        {
81
 
#ifdef HAVE_MMAP
82
83
    if ((info->s->mmaped_length != info->s->state.state.data_file_length) &&
83
84
        (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS))
84
85
    {
85
86
      if (info->s->concurrent_insert)
86
 
        rw_wrlock(&info->s->mmap_lock);
 
87
        pthread_rwlock_wrlock(&info->s->mmap_lock);
87
88
      mi_remap_file(info, info->s->state.state.data_file_length);
88
89
      info->s->nonmmaped_inserts= 0;
89
90
      if (info->s->concurrent_insert)
90
 
        rw_unlock(&info->s->mmap_lock);
 
91
        pthread_rwlock_unlock(&info->s->mmap_lock);
91
92
    }
92
 
#endif
93
93
          share->state.process= share->last_process=share->this_process;
94
94
          share->state.unique=   info->last_unique=  info->this_unique;
95
95
          share->state.update_count= info->last_loop= ++info->this_loop;
96
96
          if (mi_state_info_write(share->kfile, &share->state, 1))
97
 
            error=my_errno;
 
97
            error=errno;
98
98
          share->changed=0;
99
 
          if (myisam_flush)
100
 
          {
101
 
            if (my_sync(share->kfile, MYF(0)))
102
 
              error= my_errno;
103
 
            if (my_sync(info->dfile, MYF(0)))
104
 
              error= my_errno;
105
 
          }
106
 
          else
107
 
            share->not_flushed=1;
 
99
          share->not_flushed=1;
108
100
          if (error)
109
101
          {
110
102
            mi_print_error(info->s, HA_ERR_CRASHED);
125
117
      }
126
118
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
127
119
      info->lock_type= F_UNLCK;
128
 
      info->s->in_use= list_delete(info->s->in_use, &info->in_use);
 
120
      info->s->in_use->remove(info->in_use);
129
121
      break;
130
122
    case F_RDLCK:
131
123
      if (info->lock_type == F_WRLCK)
150
142
        flag=1;
151
143
        if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
152
144
        {
153
 
          error=my_errno;
 
145
          error=errno;
154
146
          break;
155
147
        }
156
148
        if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
157
149
        {
158
 
          error=my_errno;
159
 
          my_errno=error;
 
150
          error=errno;
 
151
          errno=error;
160
152
          break;
161
153
        }
162
154
      }
163
 
      VOID(_mi_test_if_changed(info));
 
155
      _mi_test_if_changed(info);
164
156
      share->r_locks++;
165
157
      share->tot_locks++;
166
158
      info->lock_type=lock_type;
167
 
      info->s->in_use= list_add(info->s->in_use, &info->in_use);
 
159
      info->s->in_use->push_front(info->in_use);
168
160
      break;
169
161
    case F_WRLCK:
170
162
      if (info->lock_type == F_RDLCK)
187
179
          {
188
180
            if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
189
181
            {
190
 
              error=my_errno;
191
 
              my_errno=error;
 
182
              error=errno;
 
183
              errno=error;
192
184
              break;
193
185
            }
194
186
          }
195
187
        }
196
188
      }
197
 
      VOID(_mi_test_if_changed(info));
198
 
        
 
189
      _mi_test_if_changed(info);
 
190
 
199
191
      info->lock_type=lock_type;
200
 
      info->invalidator=info->s->invalidator;
201
192
      share->w_locks++;
202
193
      share->tot_locks++;
203
 
      info->s->in_use= list_add(info->s->in_use, &info->in_use);
 
194
      info->s->in_use->push_front(info->in_use);
204
195
      break;
205
196
    default:
206
197
      break;                            /* Impossible */
212
203
    /*
213
204
       Check for bad file descriptors if this table is part
214
205
       of a merge union. Failing to capture this may cause
215
 
       a crash on windows if the table is renamed and 
 
206
       a crash on windows if the table is renamed and
216
207
       later on referenced by the merge table.
217
208
     */
218
209
    if( info->owned_by_merge && (info->s)->kfile < 0 )
224
215
  pthread_mutex_unlock(&share->intern_lock);
225
216
#if defined(FULL_LOG) || defined(_lint)
226
217
  lock_type|=(int) (flag << 8);         /* Set bit to set if real lock */
227
 
  myisam_log_command(MI_LOG_LOCK,info,(uchar*) &lock_type,sizeof(lock_type),
 
218
  myisam_log_command(MI_LOG_LOCK,info,(unsigned char*) &lock_type,sizeof(lock_type),
228
219
                     error);
229
220
#endif
230
221
  return(error);
307
298
 
308
299
  IMPLEMENTATION
309
300
    Allow concurrent inserts if we don't have a hole in the table or
310
 
    if there is no active write lock and there is active read locks and 
 
301
    if there is no active write lock and there is active read locks and
311
302
    myisam_concurrent_insert == 2. In this last case the new
312
303
    row('s) are inserted at end of file instead of filling up the hole.
313
304
 
331
322
    external lock (in other words: w_locks == 1 means no other threads has
332
323
    a write lock)
333
324
  */
334
 
  return (my_bool) !(info->s->state.dellink == HA_OFFSET_ERROR ||
 
325
  return (bool) !(info->s->state.dellink == HA_OFFSET_ERROR ||
335
326
                     (myisam_concurrent_insert == 2 && info->s->r_locks &&
336
327
                      info->s->w_locks == 1));
337
328
}
350
341
    {
351
342
      if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
352
343
      {
353
 
        int error=my_errno ? my_errno : -1;
354
 
        my_errno=error;
 
344
        int error=errno ? errno : -1;
 
345
        errno=error;
355
346
        return(1);
356
347
      }
357
348
    }
358
349
    if (check_keybuffer)
359
 
      VOID(_mi_test_if_changed(info));
360
 
    info->invalidator=info->s->invalidator;
 
350
      _mi_test_if_changed(info);
361
351
  }
362
352
  else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
363
353
  {
364
 
    my_errno=EACCES;                            /* Not allowed to change */
 
354
    errno=EACCES;                               /* Not allowed to change */
365
355
    return(-1);                         /* when have read_lock() */
366
356
  }
367
357
  return(0);
373
363
  request
374
364
*/
375
365
 
376
 
int _mi_writeinfo(register MI_INFO *info, uint operation)
 
366
int _mi_writeinfo(register MI_INFO *info, uint32_t operation)
377
367
{
378
368
  int error,olderror;
379
369
  MYISAM_SHARE *share=info->s;
381
371
  error=0;
382
372
  if (share->tot_locks == 0)
383
373
  {
384
 
    olderror=my_errno;                  /* Remember last error */
 
374
    olderror=errno;                     /* Remember last error */
385
375
    if (operation)
386
376
    {                                   /* Two threads can't be here */
387
377
      share->state.process= share->last_process=   share->this_process;
388
378
      share->state.unique=  info->last_unique=     info->this_unique;
389
379
      share->state.update_count= info->last_loop= ++info->this_loop;
390
380
      if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
391
 
        olderror=my_errno;
392
 
#ifdef __WIN__
393
 
      if (myisam_flush)
394
 
      {
395
 
        _commit(share->kfile);
396
 
        _commit(info->dfile);
397
 
      }
398
 
#endif
 
381
        olderror=errno;
399
382
    }
400
 
    my_errno=olderror;
 
383
    errno=olderror;
401
384
  }
402
385
  else if (operation)
403
386
    share->changed= 1;                  /* Mark keyfile changed */
416
399
      share->state.update_count != info->last_loop)
417
400
  {                                             /* Keyfile has changed */
418
401
    if (share->state.process != share->this_process)
419
 
      VOID(flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE));
 
402
      flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE);
420
403
    share->last_process=share->state.process;
421
404
    info->last_unique=  share->state.unique;
422
405
    info->last_loop=    share->state.update_count;
449
432
 
450
433
int _mi_mark_file_changed(MI_INFO *info)
451
434
{
452
 
  uchar buff[3];
 
435
  unsigned char buff[3];
453
436
  register MYISAM_SHARE *share=info->s;
454
437
 
455
438
  if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed)
481
464
 
482
465
int _mi_decrement_open_count(MI_INFO *info)
483
466
{
484
 
  uchar buff[2];
 
467
  unsigned char buff[2];
485
468
  register MYISAM_SHARE *share=info->s;
486
469
  int lock_error=0,write_error=0;
487
470
  if (share->global_changed)
488
471
  {
489
 
    uint old_lock=info->lock_type;
 
472
    uint32_t old_lock=info->lock_type;
490
473
    share->global_changed=0;
491
474
    lock_error=mi_lock_database(info,F_WRLCK);
492
475
    /* Its not fatal even if we couldn't get the lock ! */