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 131105 abaf789d8030afc528c0e7f636b8689fba0aa981
parent 131104 e1f30dbb81086b17a8a3ff4d97d80b8c0f9b7636
child 131106 93f778d033644ff6565ae5580598009a376c93ff
push id1590
push userphilringnalda@gmail.com
push dateWed, 08 May 2013 02:55:52 +0000
treeherderfx-team@b3a6bee35493 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs857830
milestone23.0a1
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_ */