~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to mysys/mf_iocache.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
129
129
}
130
130
 
131
131
 
 
132
/* FUNCTIONS TO SET UP OR RESET A CACHE */
 
133
 
 
134
 
132
135
/*
133
136
  Initialize an IO_CACHE object
134
137
 
160
163
  my_off_t pos;
161
164
  my_off_t end_of_file= ~(my_off_t) 0;
162
165
  DBUG_ENTER("init_io_cache");
163
 
  DBUG_PRINT("enter",("cache: 0x%lx  type: %d  pos: %ld",
164
 
                      (ulong) info, (int) type, (ulong) seek_offset));
 
166
  DBUG_PRINT("enter",("cache: %p  type: %d  pos: %ld",
 
167
                      info, (int) type, (ulong) seek_offset));
165
168
 
166
169
  info->file= file;
167
170
  info->type= TYPE_NOT_SET;         /* Don't set it until mutex are created */
168
171
  info->pos_in_file= seek_offset;
169
 
  info->pre_close = info->pre_read = info->post_read = 0;
 
172
  info->pre_close= info->pre_read= info->post_read= info->post_write= NULL;
170
173
  info->arg = 0;
171
174
  info->alloced_buffer = 0;
172
175
  info->buffer=0;
278
281
 
279
282
  /* End_of_file may be changed by user later */
280
283
  info->end_of_file= end_of_file;
281
 
  info->error=0;
 
284
  info->error= info->hard_write_error_in_the_past= 0;
282
285
  info->type= type;
283
286
  init_functions(info);
284
287
#ifdef HAVE_AIOWAIT
334
337
                        pbool clear_cache)
335
338
{
336
339
  DBUG_ENTER("reinit_io_cache");
337
 
  DBUG_PRINT("enter",("cache: 0x%lx type: %d  seek_offset: %lu  clear_cache: %d",
338
 
                      (ulong) info, type, (ulong) seek_offset,
 
340
  DBUG_PRINT("enter",("cache: %p type: %d  seek_offset: %lu  clear_cache: %d",
 
341
                      info, type, (ulong) seek_offset,
339
342
                      (int) clear_cache));
340
343
 
341
344
  /* One can't do reinit with the following types */
405
408
    }
406
409
  }
407
410
  info->type=type;
408
 
  info->error=0;
 
411
  info->error= info->hard_write_error_in_the_past= 0;
409
412
  init_functions(info);
410
413
 
411
414
#ifdef HAVE_AIOWAIT
422
425
} /* reinit_io_cache */
423
426
 
424
427
 
 
428
/* FUNCTIONS TO DO READS FROM THE CACHE */
 
429
 
425
430
 
426
431
/*
427
432
  Read buffered.
527
532
  {
528
533
    if (Count)
529
534
    {
530
 
      info->error= left_length;         /* We only got this many char */
 
535
      info->error= (int) left_length; /* We only got this many char */
531
536
      DBUG_RETURN(1);
532
537
    }
533
538
    length=0;                           /* Didn't read any chars */
624
629
                         IO_CACHE *write_cache, uint num_threads)
625
630
{
626
631
  DBUG_ENTER("init_io_cache_share");
627
 
  DBUG_PRINT("io_cache_share", ("read_cache: 0x%lx  share: 0x%lx  "
628
 
                                "write_cache: 0x%lx  threads: %u",
629
 
                                (long) read_cache, (long) cshare,
630
 
                                (long) write_cache, num_threads));
 
632
  DBUG_PRINT("io_cache_share", ("read_cache: %p  share: %p  "
 
633
                                "write_cache: %p  threads: %u",
 
634
                                read_cache, cshare,
 
635
                                write_cache, num_threads));
631
636
 
632
637
  DBUG_ASSERT(num_threads > 1);
633
638
  DBUG_ASSERT(read_cache->type == READ_CACHE);
687
692
    flush_io_cache(cache);
688
693
 
689
694
  pthread_mutex_lock(&cshare->mutex);
690
 
  DBUG_PRINT("io_cache_share", ("%s: 0x%lx",
 
695
  DBUG_PRINT("io_cache_share", ("%s: %p",
691
696
                                (cache == cshare->source_cache) ?
692
 
                                "writer" : "reader", (long) cache));
 
697
                                "writer" : "reader", cache));
693
698
 
694
699
  /* Remove from share. */
695
700
  total= --cshare->total_threads;
763
768
  /* Enter the lock. */
764
769
  pthread_mutex_lock(&cshare->mutex);
765
770
  cshare->running_threads--;
766
 
  DBUG_PRINT("io_cache_share", ("%s: 0x%lx  pos: %lu  running: %u",
 
771
  DBUG_PRINT("io_cache_share", ("%s: %p  pos: %lu  running: %u",
767
772
                                (cache == cshare->source_cache) ?
768
 
                                "writer" : "reader", (long) cache, (ulong) pos,
 
773
                                "writer" : "reader", cache, (ulong) pos,
769
774
                                cshare->running_threads));
770
775
 
771
776
  if (cshare->source_cache)
902
907
{
903
908
  IO_CACHE_SHARE *cshare= cache->share;
904
909
  DBUG_ENTER("unlock_io_cache");
905
 
  DBUG_PRINT("io_cache_share", ("%s: 0x%lx  pos: %lu  running: %u",
 
910
  DBUG_PRINT("io_cache_share", ("%s: %p  pos: %lu  running: %u",
906
911
                                (cache == cshare->source_cache) ?
907
912
                                "writer" : "reader",
908
 
                                (long) cache, (ulong) cshare->pos_in_file,
 
913
                                cache, (ulong) cshare->pos_in_file,
909
914
                                cshare->total_threads));
910
915
 
911
916
  cshare->running_threads= cshare->total_threads;
1255
1260
    info->append_read_pos += copy_len;
1256
1261
    Count -= copy_len;
1257
1262
    if (Count)
1258
 
      info->error = save_count - Count;
 
1263
      info->error= (int) (save_count - Count);
1259
1264
 
1260
1265
    /* Fill read buffer with data from write buffer */
1261
1266
    memcpy(info->buffer, info->append_read_pos,
1471
1476
  uchar buff;
1472
1477
  IO_CACHE_CALLBACK pre_read,post_read;
1473
1478
  if ((pre_read = info->pre_read))
1474
 
    (*pre_read)(info);
 
1479
    (*pre_read)(info, NULL, 0, 0);
1475
1480
  if ((*(info)->read_function)(info,&buff,1))
1476
1481
    return my_b_EOF;
1477
1482
  if ((post_read = info->post_read))
1478
 
    (*post_read)(info);
 
1483
    (*post_read)(info, NULL, 0, 0);
1479
1484
  return (int) (uchar) buff;
1480
1485
}
1481
1486
 
 
1487
/* FUNCTIONS TO DO WRITES TO THE CACHE */
 
1488
 
 
1489
#define set_hard_write_error(CACHE)                         \
 
1490
  ((CACHE)->error= (CACHE)->hard_write_error_in_the_past= -1)
 
1491
 
1482
1492
/* 
1483
1493
   Write a byte buffer to IO_CACHE and flush to disk
1484
1494
   if IO_CACHE is full.
1496
1506
  if (info->pos_in_file+info->buffer_length > info->end_of_file)
1497
1507
  {
1498
1508
    my_errno=errno=EFBIG;
1499
 
    return info->error = -1;
 
1509
    return set_hard_write_error(info);
1500
1510
  }
1501
1511
 
1502
1512
  rest_length= (size_t) (info->write_end - info->write_pos);
1520
1530
      */
1521
1531
      if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)))
1522
1532
      {
1523
 
        info->error= -1;
 
1533
        set_hard_write_error(info);
1524
1534
        return (1);
1525
1535
      }
1526
1536
      info->seek_not_done=0;
1527
1537
    }
1528
1538
    if (my_write(info->file, Buffer, length, info->myflags | MY_NABP))
1529
 
      return info->error= -1;
 
1539
      return set_hard_write_error(info);
 
1540
    if (info->post_write)
 
1541
      (*(info->post_write))(info, Buffer, length, info->pos_in_file);
1530
1542
 
1531
1543
#ifdef THREAD
1532
1544
    /*
1571
1583
  */
1572
1584
  DBUG_ASSERT(!info->share);
1573
1585
#endif
1574
 
 
 
1586
  DBUG_ASSERT(info->post_write == NULL); /* unsupported */
1575
1587
  lock_append_buffer(info);
1576
1588
  rest_length= (size_t) (info->write_end - info->write_pos);
1577
1589
  if (Count <= rest_length)
1591
1603
    if (my_write(info->file,Buffer, length, info->myflags | MY_NABP))
1592
1604
    {
1593
1605
      unlock_append_buffer(info);
1594
 
      return info->error= -1;
 
1606
      return set_hard_write_error(info);
1595
1607
    }
1596
1608
    Count-=length;
1597
1609
    Buffer+=length;
1644
1656
  {
1645
1657
    /* Of no overlap, write everything without buffering */
1646
1658
    if (pos + Count <= info->pos_in_file)
1647
 
      return my_pwrite(info->file, Buffer, Count, pos,
1648
 
                       info->myflags | MY_NABP);
 
1659
    {
 
1660
      int ret= my_pwrite(info->file, Buffer, Count, pos,
 
1661
                         info->myflags | MY_NABP);
 
1662
      if (unlikely(ret))
 
1663
        set_hard_write_error(info);
 
1664
      if (info->post_write)
 
1665
        (*(info->post_write))(info, Buffer, Count, pos);
 
1666
      return ret;
 
1667
    }
1649
1668
    /* Write the part of the block that is before buffer */
1650
1669
    length= (uint) (info->pos_in_file - pos);
1651
1670
    if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
1652
 
      info->error= error= -1;
 
1671
      error= set_hard_write_error(info);
 
1672
    if (info->post_write)
 
1673
      (*(info->post_write))(info, Buffer, length, pos);
1653
1674
    Buffer+=length;
1654
1675
    pos+=  length;
1655
1676
    Count-= length;
1701
1722
  my_bool append_cache;
1702
1723
  my_off_t pos_in_file;
1703
1724
  DBUG_ENTER("my_b_flush_io_cache");
 
1725
  DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
1704
1726
 
1705
1727
  if (!(append_cache = (info->type == SEQ_READ_APPEND)))
1706
1728
    need_append_buffer_lock=0;
1710
1732
    if (info->file == -1)
1711
1733
    {
1712
1734
      if (real_open_cached_file(info))
1713
 
        DBUG_RETURN((info->error= -1));
 
1735
        DBUG_RETURN(set_hard_write_error(info));
1714
1736
    }
1715
1737
    LOCK_APPEND_BUFFER;
1716
1738
 
1738
1760
            MY_FILEPOS_ERROR)
1739
1761
        {
1740
1762
          UNLOCK_APPEND_BUFFER;
1741
 
          DBUG_RETURN((info->error= -1));
 
1763
          DBUG_RETURN(set_hard_write_error(info));
1742
1764
        }
1743
1765
        if (!append_cache)
1744
1766
          info->seek_not_done=0;
1745
1767
      }
1746
 
      if (!append_cache)
1747
 
        info->pos_in_file+=length;
1748
1768
      info->write_end= (info->write_buffer+info->buffer_length-
1749
1769
                        ((pos_in_file+length) & (IO_SIZE-1)));
1750
1770
 
1751
1771
      if (my_write(info->file,info->write_buffer,length,
1752
1772
                   info->myflags | MY_NABP))
1753
 
        info->error= -1;
 
1773
        set_hard_write_error(info);
1754
1774
      else
1755
1775
        info->error= 0;
1756
1776
      if (!append_cache)
1757
1777
      {
 
1778
        /*
 
1779
          This post_write is really POST-write; callers depend on this! So
 
1780
          always call it after writing to the file, not before.
 
1781
        */
 
1782
        if (info->post_write)
 
1783
          (*(info->post_write))(info, info->write_buffer,
 
1784
                                length, info->pos_in_file);
 
1785
        /*
 
1786
          The addition below will make the info->pos_in_file be the end of
 
1787
          written block; whereas the value we needed in post_write is the
 
1788
          value before the addition. That's why we called post_write before
 
1789
          this.
 
1790
        */
 
1791
        info->pos_in_file+=length;
1758
1792
        set_if_bigger(info->end_of_file,(pos_in_file+length));
1759
1793
      }
1760
1794
      else
1761
1795
      {
1762
1796
        info->end_of_file+=(info->write_pos-info->append_read_pos);
1763
1797
        DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0)));
 
1798
        DBUG_ASSERT(info->post_write == NULL); /* unsupported */
1764
1799
      }
1765
1800
 
1766
1801
      info->append_read_pos=info->write_pos=info->write_buffer;
1802
1837
  int error=0;
1803
1838
  IO_CACHE_CALLBACK pre_close;
1804
1839
  DBUG_ENTER("end_io_cache");
1805
 
  DBUG_PRINT("enter",("cache: 0x%lx", (ulong) info));
 
1840
  DBUG_PRINT("enter",("cache: %p", info));
1806
1841
 
1807
1842
#ifdef THREAD
1808
1843
  /*
1814
1849
 
1815
1850
  if ((pre_close=info->pre_close))
1816
1851
  {
1817
 
    (*pre_close)(info);
 
1852
    (*pre_close)(info, NULL, 0, 0);
1818
1853
    info->pre_close= 0;
1819
1854
  }
1820
1855
  if (info->alloced_buffer)
1833
1868
    pthread_mutex_destroy(&info->append_buffer_lock);
1834
1869
#endif
1835
1870
  }
 
1871
#ifdef THREAD
 
1872
  info->share= 0;
 
1873
#endif
1836
1874
  DBUG_RETURN(error);
1837
1875
} /* end_io_cache */
1838
1876