~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_locking.cc

Merge Joe, plus I updated the tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
17
  locking of isam-tables.
36
36
  MYISAM_SHARE *share=info->s;
37
37
  uint32_t flag;
38
38
 
 
39
  pthread_mutex_lock(&share->intern_lock);
39
40
  if (!info->s->in_use)
40
41
    info->s->in_use= new list<Session *>;
41
42
 
42
43
  if (lock_type == F_EXTRA_LCK)                 /* Used by TMP tables */
43
44
  {
 
45
    pthread_mutex_unlock(&share->intern_lock);
44
46
    ++share->w_locks;
45
47
    ++share->tot_locks;
46
48
    info->lock_type= lock_type;
59
61
        count= --share->w_locks;
60
62
      --share->tot_locks;
61
63
      if (info->lock_type == F_WRLCK && !share->w_locks &&
62
 
          !share->delay_key_write && flush_key_blocks(share->getKeyCache(),
 
64
          !share->delay_key_write && flush_key_blocks(share->key_cache,
63
65
                                                      share->kfile,FLUSH_KEEP))
64
66
      {
65
67
        error=errno;
68
70
      }
69
71
      if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
70
72
      {
71
 
        if (info->rec_cache.end_io_cache())
 
73
        if (end_io_cache(&info->rec_cache))
72
74
        {
73
75
          error=errno;
74
76
          mi_print_error(info->s, HA_ERR_CRASHED);
82
84
    if ((info->s->mmaped_length != info->s->state.state.data_file_length) &&
83
85
        (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS))
84
86
    {
 
87
      if (info->s->concurrent_insert)
 
88
        pthread_rwlock_wrlock(&info->s->mmap_lock);
85
89
      mi_remap_file(info, info->s->state.state.data_file_length);
86
90
      info->s->nonmmaped_inserts= 0;
 
91
      if (info->s->concurrent_insert)
 
92
        pthread_rwlock_unlock(&info->s->mmap_lock);
87
93
    }
88
94
          share->state.process= share->last_process=share->this_process;
89
95
          share->state.unique=   info->last_unique=  info->this_unique;
207
213
    }
208
214
  }
209
215
#endif
 
216
  pthread_mutex_unlock(&share->intern_lock);
210
217
#if defined(FULL_LOG) || defined(_lint)
211
218
  lock_type|=(int) (flag << 8);         /* Set bit to set if real lock */
212
219
  myisam_log_command(MI_LOG_LOCK,info,(unsigned char*) &lock_type,sizeof(lock_type),
217
224
 
218
225
 
219
226
/****************************************************************************
 
227
  The following functions are called by thr_lock() in threaded applications
 
228
****************************************************************************/
 
229
 
 
230
/*
 
231
  Create a copy of the current status for the table
 
232
 
 
233
  SYNOPSIS
 
234
    mi_get_status()
 
235
    param               Pointer to Myisam handler
 
236
    concurrent_insert   Set to 1 if we are going to do concurrent inserts
 
237
                        (THR_WRITE_CONCURRENT_INSERT was used)
 
238
*/
 
239
 
 
240
void mi_get_status(void* param, int concurrent_insert)
 
241
{
 
242
  MI_INFO *info=(MI_INFO*) param;
 
243
 
 
244
  info->save_state=info->s->state.state;
 
245
  info->state= &info->save_state;
 
246
  info->append_insert_at_end= concurrent_insert;
 
247
  return;
 
248
}
 
249
 
 
250
 
 
251
void mi_update_status(void* param)
 
252
{
 
253
  MI_INFO *info=(MI_INFO*) param;
 
254
  /*
 
255
    Because someone may have closed the table we point at, we only
 
256
    update the state if its our own state.  This isn't a problem as
 
257
    we are always pointing at our own lock or at a read lock.
 
258
    (This is enforced by thr_multi_lock.c)
 
259
  */
 
260
  if (info->state == &info->save_state)
 
261
  {
 
262
    info->s->state.state= *info->state;
 
263
    info->state= &info->s->state.state;
 
264
  }
 
265
  info->append_insert_at_end= 0;
 
266
 
 
267
  /*
 
268
    We have to flush the write cache here as other threads may start
 
269
    reading the table before mi_lock_database() is called
 
270
  */
 
271
  if (info->opt_flag & WRITE_CACHE_USED)
 
272
  {
 
273
    if (end_io_cache(&info->rec_cache))
 
274
    {
 
275
      mi_print_error(info->s, HA_ERR_CRASHED);
 
276
      mi_mark_crashed(info);
 
277
    }
 
278
    info->opt_flag&= ~WRITE_CACHE_USED;
 
279
  }
 
280
}
 
281
 
 
282
 
 
283
void mi_restore_status(void *param)
 
284
{
 
285
  MI_INFO *info= (MI_INFO*) param;
 
286
  info->state= &info->s->state.state;
 
287
  info->append_insert_at_end= 0;
 
288
}
 
289
 
 
290
 
 
291
void mi_copy_status(void* to,void *from)
 
292
{
 
293
  ((MI_INFO*) to)->state= &((MI_INFO*) from)->save_state;
 
294
}
 
295
 
 
296
 
 
297
/*
 
298
  Check if should allow concurrent inserts
 
299
 
 
300
  IMPLEMENTATION
 
301
    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
 
303
    myisam_concurrent_insert == 2. In this last case the new
 
304
    row('s) are inserted at end of file instead of filling up the hole.
 
305
 
 
306
    The last case is to allow one to inserts into a heavily read-used table
 
307
    even if there is holes.
 
308
 
 
309
  NOTES
 
310
    If there is a an rtree indexes in the table, concurrent inserts are
 
311
    disabled in mi_open()
 
312
 
 
313
  RETURN
 
314
    0  ok to use concurrent inserts
 
315
    1  not ok
 
316
*/
 
317
 
 
318
bool mi_check_status(void *param)
 
319
{
 
320
  MI_INFO *info=(MI_INFO*) param;
 
321
  /*
 
322
    The test for w_locks == 1 is here because this thread has already done an
 
323
    external lock (in other words: w_locks == 1 means no other threads has
 
324
    a write lock)
 
325
  */
 
326
  return (bool) !(info->s->state.dellink == HA_OFFSET_ERROR ||
 
327
                     (myisam_concurrent_insert == 2 && info->s->r_locks &&
 
328
                      info->s->w_locks == 1));
 
329
}
 
330
 
 
331
 
 
332
/****************************************************************************
220
333
 ** functions to read / write the state
221
334
****************************************************************************/
222
335
 
287
400
      share->state.update_count != info->last_loop)
288
401
  {                                             /* Keyfile has changed */
289
402
    if (share->state.process != share->this_process)
290
 
      flush_key_blocks(share->getKeyCache(), share->kfile, FLUSH_RELEASE);
 
403
      flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE);
291
404
    share->last_process=share->state.process;
292
405
    info->last_unique=  share->state.unique;
293
406
    info->last_loop=    share->state.update_count;