List:Commits« Previous MessageNext Message »
From:vvaintroub Date:January 27 2008 9:39pm
Subject: bk commit into 6.0 tree (vvaintroub:1.2781)
View as plain text  
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)vvaintroub27 Jan 2008