Below is the list of changes that have just been committed into a local
6.0 repository of vvaintroub. When vvaintroub does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-01-27 21:04:23+01:00, vvaintroub@wva. +7 -0
Windows: Remove mutex synchronization from my_pread()/my_pwrite().
- implement pread()/pwrite() with native Windows ReadFile/WriteFile
- implement my_lock() with LockFileEx/UnlockFileEx
- Get rid of file-seek mutex also in Innodb and Falcon
include/my_sys.h@stripped, 2008-01-27 21:04:18+01:00, vvaintroub@wva. +1 -1
Get rid of Windows-specific file-seek mutex
mysys/my_lock.c@stripped, 2008-01-27 21:04:19+01:00, vvaintroub@wva. +39 -20
Implement my_lock() with native Win32 functions LockFileEx and UnlockFile
to remove mutex from my_file_info.
mysys/my_open.c@stripped, 2008-01-27 21:04:19+01:00, vvaintroub@wva. +2 -2
Get rid of "seek"-mutex
mysys/my_pread.c@stripped, 2008-01-27 21:04:19+01:00, vvaintroub@wva. +75 -3
Implement pread() and pwrite() with native Windows functions, remove
thread serialization via mutex in pread/pwrite.
mysys/my_seek.c@stripped, 2008-01-27 21:04:20+01:00, vvaintroub@wva. +1 -1
Get rid of file-seek mutex.
storage/falcon/SerialLogFile.cpp@stripped, 2008-01-27 21:04:20+01:00, vvaintroub@wva. +11
-18
implement positional read/write on Windows without file-seek mutex.
storage/innobase/os/os0file.c@stripped, 2008-01-27 21:04:21+01:00, vvaintroub@wva. +15
-102
implement positional read/write on Windows without file-seek mutex.
diff -Nrup a/include/my_sys.h b/include/my_sys.h
--- a/include/my_sys.h 2007-12-06 01:16:53 +01:00
+++ b/include/my_sys.h 2008-01-27 21:04:18 +01:00
@@ -303,7 +303,7 @@ struct st_my_file_info
{
char * name;
enum file_type type;
-#if defined(THREAD) && !defined(HAVE_PREAD)
+#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(__WIN__)
pthread_mutex_t mutex;
#endif
};
diff -Nrup a/mysys/my_lock.c b/mysys/my_lock.c
--- a/mysys/my_lock.c 2006-12-23 20:19:46 +01:00
+++ b/mysys/my_lock.c 2008-01-27 21:04:19 +01:00
@@ -48,6 +48,10 @@ int my_lock(File fd, int locktype, my_of
#ifdef __NETWARE__
int nxErrno;
#endif
+#ifdef __WIN__
+ DWORD lastError;
+#endif
+
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(long) start,(long) length,MyFlags));
@@ -97,29 +101,42 @@ int my_lock(File fd, int locktype, my_of
DBUG_RETURN(0);
}
}
-#elif defined(HAVE_LOCKING)
- /* Windows */
+#elif defined(__WIN__)
{
- my_bool error= FALSE;
- pthread_mutex_lock(&my_file_info[fd].mutex);
- if (MyFlags & MY_SEEK_NOT_DONE)
+
+ LARGE_INTEGER liOffset,liLength;
+ DWORD dwFlags;
+ OVERLAPPED ov= {0};
+ HANDLE hFile= (HANDLE)_get_osfhandle(fd);
+
+ lastError= 0;
+
+ liOffset.QuadPart= start;
+ liLength.QuadPart= length;
+
+ ov.Offset= liOffset.LowPart;
+ ov.OffsetHigh= liOffset.HighPart;
+
+ if (locktype == F_UNLCK)
{
- if( my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))
- == MY_FILEPOS_ERROR )
- {
- /*
- If my_seek fails my_errno will already contain an error code;
- just unlock and return error code.
- */
- DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- DBUG_RETURN(-1);
- }
+ /* The lock flags are currently ignored by Windows */
+ if(UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+ else
+ lastError= GetLastError();
}
- error= locking(fd,locktype,(ulong) length) && errno != EINVAL;
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- if (!error)
- DBUG_RETURN(0);
+ else if (locktype == F_RDLCK)
+ /* read lock is mapped to a shared lock. */
+ dwFlags= 0;
+ else
+ /* write lock is mapped to an exclusive lock. */
+ dwFlags= LOCKFILE_EXCLUSIVE_LOCK;
+
+ if (MyFlags & MY_DONT_WAIT)
+ dwFlags|= LOCKFILE_FAIL_IMMEDIATELY;
+
+ if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
}
#else
#if defined(HAVE_FCNTL)
@@ -171,6 +188,8 @@ int my_lock(File fd, int locktype, my_of
#ifdef __NETWARE__
my_errno = nxErrno;
+#elif defined(__WIN__)
+ my_errno = (lastError == ERROR_IO_PENDING)? EAGAIN:lastError?lastError : -1;
#else
/* We got an error. We don't want EACCES errors */
my_errno=(errno == EACCES) ? EAGAIN : errno ? errno : -1;
diff -Nrup a/mysys/my_open.c b/mysys/my_open.c
--- a/mysys/my_open.c 2007-08-13 15:11:10 +02:00
+++ b/mysys/my_open.c 2008-01-27 21:04:19 +01:00
@@ -108,7 +108,7 @@ int my_close(File fd, myf MyFlags)
if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
{
my_free(my_file_info[fd].name, MYF(0));
-#if defined(THREAD) && !defined(HAVE_PREAD)
+#if defined(THREAD) && !defined(HAVE_PREAD) && !defined (__WIN__)
pthread_mutex_destroy(&my_file_info[fd].mutex);
#endif
my_file_info[fd].type = UNOPEN;
@@ -153,7 +153,7 @@ File my_register_filename(File fd, const
my_file_opened++;
my_file_total_opened++;
my_file_info[fd].type = type_of_file;
-#if defined(THREAD) && !defined(HAVE_PREAD)
+#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(__WIN__)
pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
#endif
pthread_mutex_unlock(&THR_LOCK_open);
diff -Nrup a/mysys/my_pread.c b/mysys/my_pread.c
--- a/mysys/my_pread.c 2007-05-31 16:45:16 +02:00
+++ b/mysys/my_pread.c 2008-01-27 21:04:19 +01:00
@@ -16,10 +16,82 @@
#include "mysys_priv.h"
#include "mysys_err.h"
#include <errno.h>
-#ifdef HAVE_PREAD
+#if defined (HAVE_PREAD) && !defined(__WIN__)
#include <unistd.h>
#endif
+#ifdef __WIN__
+extern void _dosmaperr(DWORD);
+
+/*
+ Positional read and write on Windows.
+
+ NOTE:
+ - this functions require NT-based kernel.
+ - they can read/write at most 4GB at once.
+ - unlike Posix pread/pwrite, they change file pointer position.
+*/
+static size_t pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset)
+{
+ DWORD nBytesRead;
+ HANDLE hFile;
+ OVERLAPPED ov={0};
+ LARGE_INTEGER li;
+
+ if(!Count)
+ return 0;
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count = UINT_MAX;
+#endif
+
+ hFile= (HANDLE)_get_osfhandle(Filedes);
+ li.QuadPart= offset;
+ ov.Offset= li.LowPart;
+ ov.OffsetHigh= li.HighPart;
+
+ if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, &ov))
+ {
+ DWORD lastError = GetLastError();
+ if(lastError == ERROR_HANDLE_EOF)
+ return 0; /*return 0 at EOF*/
+ _dosmaperr(lastError);
+ return -1;
+ }
+ else
+ return nBytesRead;
+}
+
+static size_t pwrite(File Filedes, const uchar *Buffer, size_t Count, my_off_t offset)
+{
+ DWORD nBytesWritten;
+ HANDLE hFile;
+ OVERLAPPED ov={0};
+ LARGE_INTEGER li;
+
+ if(!Count)
+ return 0;
+
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count = UINT_MAX;
+#endif
+
+ hFile= (HANDLE)_get_osfhandle(Filedes);
+ li.QuadPart= offset;
+ ov.Offset= li.LowPart;
+ ov.OffsetHigh= li.HighPart;
+
+ if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov))
+ {
+ _dosmaperr(GetLastError());
+ return -1;
+ }
+ else
+ return nBytesWritten;
+}
+#endif
+
/*
Read a chunk of bytes from a file from a given position
@@ -55,7 +127,7 @@ size_t my_pread(File Filedes, uchar *Buf
#ifndef __WIN__
errno=0; /* Linux doesn't reset this */
#endif
-#ifndef HAVE_PREAD
+#if !defined (HAVE_PREAD) && !defined (__WIN__)
pthread_mutex_lock(&my_file_info[Filedes].mutex);
readbytes= (uint) -1;
error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
@@ -131,7 +203,7 @@ size_t my_pwrite(int Filedes, const ucha
for (;;)
{
-#ifndef HAVE_PREAD
+#if !defined (HAVE_PREAD) && !defined (__WIN__)
int error;
writenbytes= (size_t) -1;
pthread_mutex_lock(&my_file_info[Filedes].mutex);
diff -Nrup a/mysys/my_seek.c b/mysys/my_seek.c
--- a/mysys/my_seek.c 2007-06-05 00:43:02 +02:00
+++ b/mysys/my_seek.c 2008-01-27 21:04:20 +01:00
@@ -56,7 +56,7 @@ my_off_t my_seek(File fd, my_off_t pos,
Make sure we are using a valid file descriptor!
*/
DBUG_ASSERT(fd != -1);
-#if defined(THREAD) && !defined(HAVE_PREAD)
+#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(__WIN__)
if (MyFlags & MY_THREADSAFE)
{
pthread_mutex_lock(&my_file_info[fd].mutex);
diff -Nrup a/storage/falcon/SerialLogFile.cpp b/storage/falcon/SerialLogFile.cpp
--- a/storage/falcon/SerialLogFile.cpp 2007-11-28 18:20:53 +01:00
+++ b/storage/falcon/SerialLogFile.cpp 2008-01-27 21:04:20 +01:00
@@ -175,22 +175,16 @@ void SerialLogFile::write(int64 position
priority.schedule(PRIORITY_HIGH);
#ifdef _WIN32
-
- Sync sync(&syncObject, "SerialLogFile::write");
- sync.lock(Exclusive);
-
- if (position != offset)
- {
- LARGE_INTEGER pos;
- pos.QuadPart = position;
+ LARGE_INTEGER pos;
+ pos.QuadPart = offset;
- if (!SetFilePointerEx(handle, pos, NULL, FILE_BEGIN))
- throw SQLError(IO_ERROR, "serial log SetFilePointerEx failed with %d",
GetLastError());
- }
+ OVERLAPPED ov = {0};
+ ov.Offset = pos.LowPart;
+ ov.OffsetHigh = pos.HighPart;
DWORD ret;
- if (!WriteFile(handle, data, effectiveLength, &ret, NULL))
+ if (!WriteFile(handle, data, effectiveLength, &ret, &ov))
{
int lastError = GetLastError();
@@ -252,18 +246,17 @@ uint32 SerialLogFile::read(int64 positio
priority.schedule(PRIORITY_HIGH);
#ifdef _WIN32
- Sync sync(&syncObject, "SerialLogFile::read");
- sync.lock(Exclusive);
ASSERT(position < writePoint || writePoint == 0);
LARGE_INTEGER pos;
pos.QuadPart = position;
-
- if (!SetFilePointerEx(handle, pos, NULL, FILE_BEGIN))
- throw SQLError(IO_ERROR, "serial log SetFilePointer failed with %d", GetLastError());
+
+ OVERLAPPED ov = {0};
+ ov.Offset = pos.LowPart;
+ ov.OffsetHigh = pos.HighPart;
DWORD ret;
- if (!ReadFile(handle, data, effectiveLength, &ret, NULL))
+ if (!ReadFile(handle, data, effectiveLength, &ret, &ov))
throw SQLError(IO_ERROR, "serial log ReadFile failed with %d", GetLastError());
offset = position + effectiveLength;
diff -Nrup a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
--- a/storage/innobase/os/os0file.c 2007-08-16 01:44:21 +02:00
+++ b/storage/innobase/os/os0file.c 2008-01-27 21:04:21 +01:00
@@ -2133,11 +2133,8 @@ os_file_read(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ibool retry;
- ulint i;
+ OVERLAPPED ov;
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2149,34 +2146,15 @@ try_again:
ut_ad(buf);
ut_ad(n > 0);
- low = (DWORD) offset;
- high = (DWORD) offset_high;
+ memset(&ov, 0, sizeof(ov));
+ ov.Offset = (DWORD) offset;
+ ov.OffsetHigh = (DWORD) offset_high;
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
- os_mutex_exit(os_file_seek_mutexes[i]);
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
- goto error_handling;
- }
-
- ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
-
- os_mutex_exit(os_file_seek_mutexes[i]);
+ ret = ReadFile(file, buf, (DWORD) n, &len, &ov);
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2205,9 +2183,6 @@ try_again:
(ulong)n, (ulong)offset_high,
(ulong)offset, (long)ret);
#endif
-#ifdef __WIN__
-error_handling:
-#endif
retry = os_file_handle_error(NULL, "read");
if (retry) {
@@ -2250,11 +2225,8 @@ os_file_read_no_error_handling(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
+ OVERLAPPED ov;
ibool retry;
- ulint i;
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2266,34 +2238,15 @@ try_again:
ut_ad(buf);
ut_ad(n > 0);
- low = (DWORD) offset;
- high = (DWORD) offset_high;
+ memset(&ov, 0, sizeof(ov));
+ ov.Offset = (DWORD) offset;
+ ov.OffsetHigh = (DWORD) offset_high;
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
- os_mutex_exit(os_file_seek_mutexes[i]);
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
- goto error_handling;
- }
-
- ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
-
- os_mutex_exit(os_file_seek_mutexes[i]);
+ ret = ReadFile(file, buf, (DWORD) n, &len, &ov);
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2316,9 +2269,6 @@ try_again:
return(TRUE);
}
#endif
-#ifdef __WIN__
-error_handling:
-#endif
retry = os_file_handle_error_no_exit(NULL, "read");
if (retry) {
@@ -2372,10 +2322,7 @@ os_file_write(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
- ulint i;
+ OVERLAPPED ov;
ulint n_retries = 0;
ulint err;
@@ -2387,47 +2334,15 @@ os_file_write(
ut_ad(buf);
ut_ad(n > 0);
retry:
- low = (DWORD) offset;
- high = (DWORD) offset_high;
+ memset(&ov, 0, sizeof(ov));
+ ov.Offset = (DWORD) offset;
+ ov.OffsetHigh = (DWORD) offset_high;
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
- /* Protect the seek / write operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
- os_mutex_exit(os_file_seek_mutexes[i]);
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
- " InnoDB: Error: File pointer positioning to"
- " file %s failed at\n"
- "InnoDB: offset %lu %lu. Operating system"
- " error number %lu.\n"
- "InnoDB: Some operating system error numbers"
- " are described at\n"
- "InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n",
- name, (ulong) offset_high, (ulong) offset,
- (ulong) GetLastError());
-
- return(FALSE);
- }
-
- ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
+ ret = WriteFile(file, buf, (DWORD) n, &len, &ov);
/* Always do fsync to reduce the probability that when the OS crashes,
a database page is only partially physically written to disk. */
@@ -2437,8 +2352,6 @@ retry:
ut_a(TRUE == os_file_flush(file));
}
# endif /* UNIV_DO_FLUSH */
-
- os_mutex_exit(os_file_seek_mutexes[i]);
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
| Thread |
|---|
| • bk commit into 6.0 tree (vvaintroub:1.2781) | vvaintroub | 27 Jan 2008 |