summaryrefslogtreecommitdiff
path: root/mysys/mf_iocache.c
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2006-02-16 19:51:09 +0100
committerunknown <ingo@mysql.com>2006-02-16 19:51:09 +0100
commit5001e0a3f73b89b3f0af4139d4aa6a83d08d4c4f (patch)
treed7549f4b986ce5dc20245b9dfbc88bc78dbcf4f9 /mysys/mf_iocache.c
parent3554d87f84464426b5eb6dfa14ffbbfb1c3b22a0 (diff)
parentd46fc0e8072ef960114d4cd0dbd386566d86eb8f (diff)
downloadmariadb-git-5001e0a3f73b89b3f0af4139d4aa6a83d08d4c4f.tar.gz
Merge mysql.com:/home/mydev/mysql-4.1-bug11527
into mysql.com:/home/mydev/mysql-5.0-bug11527 mysys/mf_iocache.c: Auto merged
Diffstat (limited to 'mysys/mf_iocache.c')
-rw-r--r--mysys/mf_iocache.c103
1 files changed, 75 insertions, 28 deletions
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 63f5dc964da..cd2a140182e 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -399,11 +399,31 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
/*
- Read buffered. Returns 1 if can't read requested characters
- This function is only called from the my_b_read() macro
- when there isn't enough characters in the buffer to
- satisfy the request.
- Returns 0 we succeeded in reading all data
+ Read buffered.
+
+ SYNOPSIS
+ _my_b_read()
+ info IO_CACHE pointer
+ Buffer Buffer to retrieve count bytes from file
+ Count Number of bytes to read into Buffer
+
+ NOTE
+ This function is only called from the my_b_read() macro when there
+ isn't enough characters in the buffer to satisfy the request.
+
+ WARNING
+
+ When changing this function, be careful with handling file offsets
+ (end-of_file, pos_in_file). Do not cast them to possibly smaller
+ types than my_off_t unless you can be sure that their value fits.
+ Same applies to differences of file offsets.
+
+ When changing this function, check _my_b_read_r(). It might need the
+ same change.
+
+ RETURN
+ 0 we succeeded in reading all data
+ 1 Error: can't read requested characters
*/
int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
@@ -431,7 +451,7 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
{ /* Fill first intern buffer */
uint read_length;
- if (info->end_of_file == pos_in_file)
+ if (info->end_of_file <= pos_in_file)
{ /* End of file */
info->error=(int) left_length;
DBUG_RETURN(1);
@@ -546,43 +566,70 @@ static void unlock_io_cache(IO_CACHE *info)
/*
Read from IO_CACHE when it is shared between several threads.
- It works as follows: when a thread tries to read from a file
- (that is, after using all the data from the (shared) buffer),
- it just hangs on lock_io_cache(), wating for other threads.
- When the very last thread attempts a read, lock_io_cache()
- returns 1, the thread does actual IO and unlock_io_cache(),
- which signals all the waiting threads that data is in the buffer.
+
+ SYNOPSIS
+ _my_b_read_r()
+ info IO_CACHE pointer
+ Buffer Buffer to retrieve count bytes from file
+ Count Number of bytes to read into Buffer
+
+ NOTE
+ This function is only called from the my_b_read() macro when there
+ isn't enough characters in the buffer to satisfy the request.
+
+ IMPLEMENTATION
+
+ It works as follows: when a thread tries to read from a file (that
+ is, after using all the data from the (shared) buffer), it just
+ hangs on lock_io_cache(), wating for other threads. When the very
+ last thread attempts a read, lock_io_cache() returns 1, the thread
+ does actual IO and unlock_io_cache(), which signals all the waiting
+ threads that data is in the buffer.
+
+ WARNING
+
+ When changing this function, be careful with handling file offsets
+ (end-of_file, pos_in_file). Do not cast them to possibly smaller
+ types than my_off_t unless you can be sure that their value fits.
+ Same applies to differences of file offsets. (Bug #11527)
+
+ When changing this function, check _my_b_read(). It might need the
+ same change.
+
+ RETURN
+ 0 we succeeded in reading all data
+ 1 Error: can't read requested characters
*/
int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
{
my_off_t pos_in_file;
- uint length,diff_length,read_len;
+ uint length, diff_length, left_length;
DBUG_ENTER("_my_b_read_r");
- if ((read_len=(uint) (info->read_end-info->read_pos)))
+ if ((left_length= (uint) (info->read_end - info->read_pos)))
{
- DBUG_ASSERT(Count >= read_len); /* User is not using my_b_read() */
- memcpy(Buffer,info->read_pos, (size_t) (read_len));
- Buffer+=read_len;
- Count-=read_len;
+ DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
+ memcpy(Buffer, info->read_pos, (size_t) (left_length));
+ Buffer+= left_length;
+ Count-= left_length;
}
while (Count)
{
int cnt, len;
- pos_in_file= info->pos_in_file + (uint)(info->read_end - info->buffer);
+ pos_in_file= info->pos_in_file + (info->read_end - info->buffer);
diff_length= (uint) (pos_in_file & (IO_SIZE-1));
length=IO_ROUND_UP(Count+diff_length)-diff_length;
length=(length <= info->read_length) ?
length + IO_ROUND_DN(info->read_length - length) :
length - IO_ROUND_UP(length - info->read_length) ;
if (info->type != READ_FIFO &&
- (length > (uint) (info->end_of_file - pos_in_file)))
+ (length > (info->end_of_file - pos_in_file)))
length= (uint) (info->end_of_file - pos_in_file);
if (length == 0)
{
- info->error=(int) read_len;
+ info->error= (int) left_length;
DBUG_RETURN(1);
}
if (lock_io_cache(info, pos_in_file))
@@ -607,15 +654,15 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
info->seek_not_done=0;
if (len <= 0)
{
- info->error=(int) read_len;
+ info->error= (int) left_length;
DBUG_RETURN(1);
}
- cnt=((uint) len > Count) ? (int) Count : len;
- memcpy(Buffer,info->read_pos, (size_t)cnt);
- Count -=cnt;
- Buffer+=cnt;
- read_len+=cnt;
- info->read_pos+=cnt;
+ cnt= ((uint) len > Count) ? (int) Count : len;
+ memcpy(Buffer, info->read_pos, (size_t) cnt);
+ Count -= cnt;
+ Buffer+= cnt;
+ left_length+= cnt;
+ info->read_pos+= cnt;
}
DBUG_RETURN(0);
}