Bug 857830: Part 2 - Adds readahead to read-only fopen calls in Hunspell. r=ehsan
authorAaron Klotz <aklotz@mozilla.com>
Tue, 07 May 2013 00:14:15 -0600
changeset 131100 abaf789d8030afc528c0e7f636b8689fba0aa981
parent 131099 e1f30dbb81086b17a8a3ff4d97d80b8c0f9b7636
child 131101 93f778d033644ff6565ae5580598009a376c93ff
push id24649
push userryanvm@gmail.com
push dateWed, 08 May 2013 02:10:32 +0000
treeherdermozilla-central@b980d32c366f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs857830
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 857830: Part 2 - Adds readahead to read-only fopen calls in Hunspell. r=ehsan
extensions/spellcheck/hunspell/src/hunspell_fopen_hooks.h
mozilla-config.h.in
new file mode 100644
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hunspell_fopen_hooks.h
@@ -0,0 +1,79 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef fopen_hooks_h__
+#define fopen_hooks_h__
+
+/**
+ * This file is force-included in hunspell code. Its purpose is to add 
+ * readahead to fopen() calls in hunspell without modifying its code, in order 
+ * to ease future upgrades.
+ *
+ * This file is force-included through mozilla-config.h which is generated
+ * during the configure step.
+ */
+
+#include "mozilla/FileUtils.h"
+#include <stdio.h>
+#include <string.h>
+
+#if defined(XP_WIN)
+#include "nsString.h"
+
+#include <fcntl.h>
+#include <windows.h>
+// Hunspell defines a function named near. Windef.h #defines near.
+#undef near
+// mozHunspell defines a function named RemoveDirectory.
+#undef RemoveDirectory
+#endif /* defined(XP_WIN) */
+
+inline FILE*
+hunspell_fopen_readahead(const char* filename, const char* mode)
+{
+  if (!filename || !mode) {
+    return nullptr;
+  }
+  // Fall back to libc's fopen for modes not supported by ReadAheadFile
+  if (!strchr(mode, 'r') || strchr(mode, '+')) {
+    return fopen(filename, mode);
+  }
+  int fd = -1;
+#if defined(XP_WIN)
+  HANDLE handle = INVALID_HANDLE_VALUE;
+  mozilla::ReadAheadFile(NS_ConvertUTF8toUTF16(filename).get(), 0, SIZE_MAX,
+                         &handle);
+  if (handle == INVALID_HANDLE_VALUE) {
+    return nullptr;
+  }
+  int flags = _O_RDONLY;
+  // MSVC CRT's _open_osfhandle only supports adding _O_TEXT, not _O_BINARY
+  if (strchr(mode, 't')) {
+    // Force translated mode
+    flags |= _O_TEXT;
+  }
+  // Import the Win32 fd into the CRT
+  fd = _open_osfhandle((intptr_t)handle, flags);
+  if (fd < 0) {
+    CloseHandle(handle);
+    return nullptr;
+  }
+#else
+  mozilla::ReadAheadFile(filename, 0, SIZE_MAX, &fd);
+  if (fd < 0) {
+    return nullptr;
+  }
+#endif /* defined(XP_WIN) */
+
+  FILE* file = fdopen(fd, mode);
+  if (!file) {
+    close(fd);
+  }
+  return file;
+}
+
+#define fopen(filename, mode) hunspell_fopen_readahead(filename, mode)
+
+#endif /* fopen_hooks_h__ */
+
--- a/mozilla-config.h.in
+++ b/mozilla-config.h.in
@@ -8,20 +8,21 @@
 
 @ALLDEFINES@
 
 /* The c99 defining the limit macros (UINT32_MAX for example), says:
  * C++ implementations should define these macros only when __STDC_LIMIT_MACROS
  * is defined before <stdint.h> is included. */
 #define __STDC_LIMIT_MACROS
 
-/* Force-include hunspell_alloc_hooks.h for hunspell, so that we don't need to
- * modify it directly.
+/* Force-include hunspell_alloc_hooks.h and hunspell_fopen_hooks.h for hunspell,
+ * so that we don't need to modify it directly.
  *
  * HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in,
  * unless --enable-system-hunspell is defined.
  */
 #if defined(HUNSPELL_STATIC)
 #include "hunspell_alloc_hooks.h"
+#include "hunspell_fopen_hooks.h"
 #endif
 
 #endif /* _MOZILLA_CONFIG_H_ */