~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_locking.c

  • Committer: Monty Taylor
  • Date: 2008-11-16 23:47:43 UTC
  • mto: (584.1.10 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116234743-c38gmv0pa2kdefaj
BrokeĀ outĀ cached_item.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
  isamdatabase.
21
21
*/
22
22
 
23
 
#include "myisam_priv.h"
24
 
#include "drizzled/charset_info.h"
 
23
#include "myisamdef.h"
 
24
#include <mystrings/m_ctype.h>
 
25
#include <mysys/my_tree.h>
 
26
#include <mysys/queues.h>
25
27
#include <drizzled/util/test.h>
26
28
 
27
 
using namespace std;
28
 
using namespace drizzled;
29
 
 
30
29
        /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */
31
30
 
32
31
int mi_lock_database(MI_INFO *info, int lock_type)
36
35
  MYISAM_SHARE *share=info->s;
37
36
  uint32_t flag;
38
37
 
39
 
  pthread_mutex_lock(&share->intern_lock);
40
 
  if (!info->s->in_use)
41
 
    info->s->in_use= new list<Session *>;
42
 
 
 
38
  if (share->options & HA_OPTION_READ_ONLY_DATA ||
 
39
      info->lock_type == lock_type)
 
40
    return(0);
43
41
  if (lock_type == F_EXTRA_LCK)                 /* Used by TMP tables */
44
42
  {
45
 
    pthread_mutex_unlock(&share->intern_lock);
46
43
    ++share->w_locks;
47
44
    ++share->tot_locks;
48
45
    info->lock_type= lock_type;
49
 
    info->s->in_use->push_front(info->in_use);
 
46
    info->s->in_use= list_add(info->s->in_use, &info->in_use);
50
47
    return(0);
51
48
  }
52
49
 
53
50
  flag=error=0;
 
51
  pthread_mutex_lock(&share->intern_lock);
54
52
  if (share->kfile >= 0)                /* May only be false on windows */
55
53
  {
56
54
    switch (lock_type) {
64
62
          !share->delay_key_write && flush_key_blocks(share->key_cache,
65
63
                                                      share->kfile,FLUSH_KEEP))
66
64
      {
67
 
        error=errno;
 
65
        error=my_errno;
68
66
        mi_print_error(info->s, HA_ERR_CRASHED);
69
67
        mi_mark_crashed(info);          /* Mark that table must be checked */
70
68
      }
72
70
      {
73
71
        if (end_io_cache(&info->rec_cache))
74
72
        {
75
 
          error=errno;
 
73
          error=my_errno;
76
74
          mi_print_error(info->s, HA_ERR_CRASHED);
77
75
          mi_mark_crashed(info);
78
76
        }
81
79
      {
82
80
        if (share->changed && !share->w_locks)
83
81
        {
 
82
#ifdef HAVE_MMAP
84
83
    if ((info->s->mmaped_length != info->s->state.state.data_file_length) &&
85
84
        (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS))
86
85
    {
87
86
      if (info->s->concurrent_insert)
88
 
        pthread_rwlock_wrlock(&info->s->mmap_lock);
 
87
        rw_wrlock(&info->s->mmap_lock);
89
88
      mi_remap_file(info, info->s->state.state.data_file_length);
90
89
      info->s->nonmmaped_inserts= 0;
91
90
      if (info->s->concurrent_insert)
92
 
        pthread_rwlock_unlock(&info->s->mmap_lock);
 
91
        rw_unlock(&info->s->mmap_lock);
93
92
    }
 
93
#endif
94
94
          share->state.process= share->last_process=share->this_process;
95
95
          share->state.unique=   info->last_unique=  info->this_unique;
96
96
          share->state.update_count= info->last_loop= ++info->this_loop;
97
97
          if (mi_state_info_write(share->kfile, &share->state, 1))
98
 
            error=errno;
 
98
            error=my_errno;
99
99
          share->changed=0;
100
 
          share->not_flushed=1;
 
100
          if (myisam_flush)
 
101
          {
 
102
            if (my_sync(share->kfile, MYF(0)))
 
103
              error= my_errno;
 
104
            if (my_sync(info->dfile, MYF(0)))
 
105
              error= my_errno;
 
106
          }
 
107
          else
 
108
            share->not_flushed=1;
101
109
          if (error)
102
110
          {
103
111
            mi_print_error(info->s, HA_ERR_CRASHED);
118
126
      }
119
127
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
120
128
      info->lock_type= F_UNLCK;
121
 
      info->s->in_use->remove(info->in_use);
 
129
      info->s->in_use= list_delete(info->s->in_use, &info->in_use);
122
130
      break;
123
131
    case F_RDLCK:
124
132
      if (info->lock_type == F_WRLCK)
143
151
        flag=1;
144
152
        if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
145
153
        {
146
 
          error=errno;
 
154
          error=my_errno;
147
155
          break;
148
156
        }
149
157
        if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
150
158
        {
151
 
          error=errno;
152
 
          errno=error;
 
159
          error=my_errno;
 
160
          my_errno=error;
153
161
          break;
154
162
        }
155
163
      }
157
165
      share->r_locks++;
158
166
      share->tot_locks++;
159
167
      info->lock_type=lock_type;
160
 
      info->s->in_use->push_front(info->in_use);
 
168
      info->s->in_use= list_add(info->s->in_use, &info->in_use);
161
169
      break;
162
170
    case F_WRLCK:
163
171
      if (info->lock_type == F_RDLCK)
180
188
          {
181
189
            if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
182
190
            {
183
 
              error=errno;
184
 
              errno=error;
 
191
              error=my_errno;
 
192
              my_errno=error;
185
193
              break;
186
194
            }
187
195
          }
188
196
        }
189
197
      }
190
198
      _mi_test_if_changed(info);
191
 
 
 
199
        
192
200
      info->lock_type=lock_type;
 
201
      info->invalidator=info->s->invalidator;
193
202
      share->w_locks++;
194
203
      share->tot_locks++;
195
 
      info->s->in_use->push_front(info->in_use);
 
204
      info->s->in_use= list_add(info->s->in_use, &info->in_use);
196
205
      break;
197
206
    default:
198
207
      break;                            /* Impossible */
204
213
    /*
205
214
       Check for bad file descriptors if this table is part
206
215
       of a merge union. Failing to capture this may cause
207
 
       a crash on windows if the table is renamed and
 
216
       a crash on windows if the table is renamed and 
208
217
       later on referenced by the merge table.
209
218
     */
210
219
    if( info->owned_by_merge && (info->s)->kfile < 0 )
299
308
 
300
309
  IMPLEMENTATION
301
310
    Allow concurrent inserts if we don't have a hole in the table or
302
 
    if there is no active write lock and there is active read locks and
 
311
    if there is no active write lock and there is active read locks and 
303
312
    myisam_concurrent_insert == 2. In this last case the new
304
313
    row('s) are inserted at end of file instead of filling up the hole.
305
314
 
342
351
    {
343
352
      if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
344
353
      {
345
 
        int error=errno ? errno : -1;
346
 
        errno=error;
 
354
        int error=my_errno ? my_errno : -1;
 
355
        my_errno=error;
347
356
        return(1);
348
357
      }
349
358
    }
350
359
    if (check_keybuffer)
351
360
      _mi_test_if_changed(info);
 
361
    info->invalidator=info->s->invalidator;
352
362
  }
353
363
  else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
354
364
  {
355
 
    errno=EACCES;                               /* Not allowed to change */
 
365
    my_errno=EACCES;                            /* Not allowed to change */
356
366
    return(-1);                         /* when have read_lock() */
357
367
  }
358
368
  return(0);
372
382
  error=0;
373
383
  if (share->tot_locks == 0)
374
384
  {
375
 
    olderror=errno;                     /* Remember last error */
 
385
    olderror=my_errno;                  /* Remember last error */
376
386
    if (operation)
377
387
    {                                   /* Two threads can't be here */
378
388
      share->state.process= share->last_process=   share->this_process;
379
389
      share->state.unique=  info->last_unique=     info->this_unique;
380
390
      share->state.update_count= info->last_loop= ++info->this_loop;
381
391
      if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
382
 
        olderror=errno;
 
392
        olderror=my_errno;
 
393
#ifdef __WIN__
 
394
      if (myisam_flush)
 
395
      {
 
396
        _commit(share->kfile);
 
397
        _commit(info->dfile);
 
398
      }
 
399
#endif
383
400
    }
384
 
    errno=olderror;
 
401
    my_errno=olderror;
385
402
  }
386
403
  else if (operation)
387
404
    share->changed= 1;                  /* Mark keyfile changed */