diff options
author | unknown <svoj@mysql.com/april.(none)> | 2007-05-16 23:42:32 +0500 |
---|---|---|
committer | unknown <svoj@mysql.com/april.(none)> | 2007-05-16 23:42:32 +0500 |
commit | e1e83a8b66dc59b1e46cd78db6a20b8ba2ea44ba (patch) | |
tree | 9c9698a00650c9b14df2751df3ccce8e811752b6 /mysys/my_seek.c | |
parent | 0eaf97393dbe4e8e13bbe85c18c71b41e473b086 (diff) | |
download | mariadb-git-e1e83a8b66dc59b1e46cd78db6a20b8ba2ea44ba.tar.gz |
BUG#25712 - insert delayed and check table run together report crashed
tables
In case system doesn't have native pread/pwrite calls (e.g. Windows)
and there is CHECK TABLE runs concurrently with another statement that
reads from a table, the table may be reported as crashed.
This is fixed by locking file descriptor when my_seek is executed on
MyISAM index file and emulated pread/pwrite may be executed concurrently.
Affects MyISAM tables on platforms that do not have native
pread/pwrite calls (e.g. Windows).
No deterministic test case for this bug.
myisam/mi_check.c:
Key file descriptor is shared among threads and mixed set of
my_pread/my_pwrite and my_seek calls is possible. This is not
a problem on systems that have native pread/pwrite calls.
In case system doesn't have native pread/pwrite calls (e.g. Windows)
we must ensure that my_pread/my_pwrite are not executed at the same
time with my_seek. This is done by passing MY_THREADSAFE flag to
my_seek.
mysys/my_seek.c:
On platforms that do not have native pread/pwrite calls (e.g. Windows)
these calls are emulated as follow: lock fd, lseek, read, unlock fd.
In case file descriptor is shared among threads, where one thread
executes my_pread and another thread executes my_seek, we may read
from a wrong position. This may happen because my_seek doesn't lock
fd and thus may be executed by another thread after emulated pread
has done lseek and before it has done read.
To fix problem mentioned above we introduce new flag MY_THREADSAFE to
my_seek, which is meaningful only in case pread/pwrite calls are
emulated. If this flag is set, lseek operation is performed as follow:
lock fd, seek, unlock fd.
Diffstat (limited to 'mysys/my_seek.c')
-rw-r--r-- | mysys/my_seek.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/mysys/my_seek.c b/mysys/my_seek.c index a9ae68cd5f0..cb0fe75d7e5 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -24,7 +24,9 @@ my_off_t pos The expected position (absolute or relative) int whence A direction parameter and one of {SEEK_SET, SEEK_CUR, SEEK_END} - myf MyFlags Not used. + myf MyFlags MY_THREADSAFE must be set in case my_seek may be mixed + with my_pread/my_pwrite calls and fd is shared among + threads. DESCRIPTION The my_seek function is a wrapper around the system call lseek and @@ -51,7 +53,16 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, whence, MyFlags)); DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ - newpos=lseek(fd, pos, whence); +#if defined(THREAD) && !defined(HAVE_PREAD) + if (MyFlags & MY_THREADSAFE) + { + pthread_mutex_lock(&my_file_info[fd].mutex); + newpos= lseek(fd, pos, whence); + pthread_mutex_lock(&my_file_info[fd].mutex); + } + else +#endif + newpos= lseek(fd, pos, whence); if (newpos == (os_off_t) -1) { my_errno=errno; |