summaryrefslogtreecommitdiff
path: root/mysys/my_seek.c
diff options
context:
space:
mode:
authorunknown <svoj@mysql.com/april.(none)>2007-05-16 23:42:32 +0500
committerunknown <svoj@mysql.com/april.(none)>2007-05-16 23:42:32 +0500
commite1e83a8b66dc59b1e46cd78db6a20b8ba2ea44ba (patch)
tree9c9698a00650c9b14df2751df3ccce8e811752b6 /mysys/my_seek.c
parent0eaf97393dbe4e8e13bbe85c18c71b41e473b086 (diff)
downloadmariadb-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.c15
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;