Browse Source

r7012@Kushana: nickm | 2006-08-03 19:21:25 -0700
Add an "mmap handle" type to encapsulate bookkeeping elements of mmap issues; add prelim win32 impl


svn:r6980

Nick Mathewson 18 years ago
parent
commit
bf72878cad
5 changed files with 104 additions and 29 deletions
  1. 5 1
      doc/TODO
  2. 83 18
      src/common/compat.c
  3. 6 2
      src/common/compat.h
  4. 1 0
      src/or/or.h
  5. 9 8
      src/or/routerlist.c

+ 5 - 1
doc/TODO

@@ -73,10 +73,14 @@ N   . Improve memory usage on tight-memory machines.
 
     - "bandwidth classes", for incoming vs initiated-here conns.
     o Asynchronous DNS
-      . And test it
+      o And test it
       . Make it work on windows.
         o Implement
+        . Enable
         - Test
+      - Make the Nameservers option documented, and make it work right on
+        reload.
+      - Fail when we have no configured nameservers!
       - Make it the default on platforms where it works
 
   - Security improvements

+ 83 - 18
src/common/compat.c

@@ -24,8 +24,9 @@ const char compat_c_id[] =
 
 #ifdef MS_WINDOWS
 #include <process.h>
-
+#include <windows.h>
 #endif
+
 #ifdef HAVE_UNAME
 #include <sys/utsname.h>
 #endif
@@ -107,16 +108,22 @@ const char compat_c_id[] =
 #define INADDR_NONE ((unsigned long) -1)
 #endif
 
-#ifdef HAVE_SYS_MMAN
-const char *
-tor_mmap_file(const char *filename, size_t *size)
+#ifdef HAVE_SYS_MMAN_H
+struct tor_mmap_t {
+  char *data;
+  size_t size;
+};
+tor_mmap_t *
+tor_mmap_file(const char *filename, const char **data, size_t *size_out)
 {
   int fd; /* router file */
   char *string;
   int page_size;
+  tor_mmap_t *res;
+  size_t size;
 
   tor_assert(filename);
-  tor_assert(size);
+  tor_assert(size_out);
 
   fd = open(filename, O_RDONLY, 0);
   if (fd<0) {
@@ -124,13 +131,13 @@ tor_mmap_file(const char *filename, size_t *size)
     return NULL;
   }
 
-  *size = lseek(fd, 0, SEEK_END);
+  size = lseek(fd, 0, SEEK_END);
   lseek(fd, 0, SEEK_SET);
   /* ensure page alignment */
   page_size = getpagesize();
-  *size += (page_size + (page_size-(*size%page_size)));
+  size += (page_size + (page_size-(size%page_size)));
 
-  string = mmap(0, *size, PROT_READ, MAP_PRIVATE, fd, 0);
+  string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (string == MAP_FAILED) {
     log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
              strerror(errno));
@@ -139,30 +146,88 @@ tor_mmap_file(const char *filename, size_t *size)
 
   close(fd);
 
-  return string;
+  res = tor_malloc_zero(sizeof(tor_mmap_t));
+  *data = res->data = string;
+  *size_out = res->size = size;
+
+  return res;
 }
+void
+tor_munmap_file(tor_mmap_t *handle)
+{
+  munmap(handle->data, handle->size);
+}
+#elif defined(MS_WINDOWS)
+typdef struct tor_mmap_t {
+  char *data;
+  HANDLE file_handle;
+  HANDLE mmap_handle;
+  size_t size;
+} tor_mmap_t;
+tor_mmap_t *
+tor_mmap_file(const char *filename, const char **data, size_t *size)
+{
+  win_mmap_t *res = tor_malloc_zero(res);
+  res->mmap_handle = res->file_handle = INVALID_HANDLE_VALUE;
+  /* What's this about tags? */
+
+  /* Open the file. */
+  res->file_handle = XXXXX;
+  res->size = GetFileSize(res->file_handle, NULL);
+
+  res->mmap_handle = CreateFileMapping(res->file_handle,
+                                       NULL,
+                                       PAGE_READONLY,
+                                       0,
+                                       size,
+                                       tagname);
+  if (res->mmap_handle != INVALID_HANDLE_VALUE)
+    goto err;
+  res->data = (char*) MapViewOfFile(res->mmap_handle,
+                                    access,
+                                    0, 0, 0);
+  if (!res->data)
+    goto err;
+
+  *size = res->size;
+  *data = res->data;
 
+  return res;
+ err:
+  tor_munmap_file(res);
+  return NULL;
+}
 void
-tor_munmap_file(const char *memory, size_t size)
+tor_munmap_file(tor_mmap_t *handle)
 {
-  munmap((char*)memory, size);
+  if (handle->data)
+    UnmapViewOfFile(handle->data);
+  if (res->mmap_handle != INVALID_HANDLE_VALUE)
+    CloseHandle(res->mmap_handle);
+  if (res->file_handle != INVALID_HANDLE_VALUE)
+    CloseHandle(self->file_handle);
+  tor_free(res);
 }
 #else
-const char *
-tor_mmap_file(const char *filename, size_t *size)
+struct tor_mmap_t {
+  char *data;
+};
+tor_mmap_t *
+tor_mmap_file(const char *filename, const char **data, size_t *size)
 {
   char *res = read_file_to_str(filename, 1);
+  tor_mmap_t *handle;
   if (res)
     *size = strlen(res) + 1;
-  return res;
+  handle = tor_malloc_zero(sizeof(tor_mmap_t));
+  *data = handle->data = res;
+  return handle;
 }
 
 void
-tor_munmap_file(const char *memory, size_t size)
+tor_munmap_file(tor_mmap_t *handle)
 {
-  char *mem = (char*) memory;
-  (void)size;
-  tor_free(mem);
+  tor_free(handle->data);
 }
 #endif
 

+ 6 - 2
src/common/compat.h

@@ -114,8 +114,12 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
 #define U64_LITERAL(n) (n ## llu)
 #endif
 
-const char *tor_mmap_file(const char *filename, size_t *size);
-void tor_munmap_file(const char *memory, size_t size);
+/** Opaque bookkeeping type used for mmap accounting. */
+typedef struct tor_mmap_t tor_mmap_t;
+
+tor_mmap_t *tor_mmap_file(const char *filename,
+                          const char **data, size_t *size);
+void tor_munmap_file(tor_mmap_t *handle);
 
 int tor_snprintf(char *str, size_t size, const char *format, ...)
      CHECK_PRINTF(3,4);

+ 1 - 0
src/or/or.h

@@ -1020,6 +1020,7 @@ typedef struct {
   /** DOCDOC */
   const char *mmap_descriptors;
   size_t mmap_descriptors_len;
+  tor_mmap_t *mmap_handle;
 } routerlist_t;
 
 /** Information on router used when extending a circuit.  (We don't need a

+ 9 - 8
src/or/routerlist.c

@@ -276,12 +276,12 @@ router_rebuild_store(int force)
     goto done;
   }
   /* Our mmap is now invalid. */
-  if (routerlist->mmap_descriptors) {
-    tor_munmap_file(routerlist->mmap_descriptors,
-                    routerlist->mmap_descriptors_len);
-    routerlist->mmap_descriptors =
-      tor_mmap_file(fname, &routerlist->mmap_descriptors_len);
-    if (! routerlist->mmap_descriptors)
+  if (routerlist->mmap_handle) {
+    tor_munmap_file(routerlist->mmap_handle);
+    routerlist->mmap_handle = tor_mmap_file(fname,
+                                            &routerlist->mmap_descriptors,
+                                            &routerlist->mmap_descriptors_len);
+    if (! routerlist->mmap_handle)
       log_warn(LD_FS, "Unable to mmap new descriptor file at '%s'.",fname);
   }
 
@@ -340,8 +340,9 @@ router_reload_router_list(void)
   router_journal_len = router_store_len = 0;
 
   tor_snprintf(fname, fname_len, "%s/cached-routers", options->DataDirectory);
-  routerlist->mmap_descriptors =
-    tor_mmap_file(fname, &routerlist->mmap_descriptors_len);
+  routerlist->mmap_handle = tor_mmap_file(fname,
+                                          &routerlist->mmap_descriptors,
+                                          &routerlist->mmap_descriptors_len);
   if (routerlist->mmap_descriptors) {
     router_store_len = routerlist->mmap_descriptors_len;
     router_load_routers_from_string(routerlist->mmap_descriptors,