changeset 3651:515d50917016

ngx_create_file_mapping()
author Igor Sysoev <igor@sysoev.ru>
date Tue, 29 Jun 2010 15:18:50 +0000
parents c12b0dd5bd1c
children 1eea82e36053
files src/os/unix/ngx_files.c src/os/unix/ngx_files.h src/os/win32/ngx_files.c src/os/win32/ngx_files.h
diffstat 4 files changed, 172 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -259,6 +259,58 @@ ngx_set_file_time(u_char *name, ngx_fd_t
 
 
 ngx_int_t
+ngx_create_file_mapping(ngx_file_mapping_t *fm)
+{
+    fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
+                           NGX_FILE_DEFAULT_ACCESS);
+    if (fm->fd == NGX_INVALID_FILE) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      ngx_open_file_n " \"%s\" failed", fm->name);
+        return NGX_ERROR;
+    }
+
+    if (ftruncate(fm->fd, fm->size) == -1) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      "ftruncate() \"%s\" failed", fm->name);
+        goto failed;
+    }
+
+    fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
+                    fm->fd, 0);
+    if (fm->addr != MAP_FAILED) {
+        return NGX_OK;
+    }
+
+    ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                  "mmap(%uz) \"%s\" failed", fm->size, fm->name);
+
+failed:
+
+    if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                      ngx_close_file_n " \"%s\" failed", fm->name);
+    }
+
+    return NGX_ERROR;
+}
+
+
+void
+ngx_close_file_mapping(ngx_file_mapping_t *fm)
+{
+    if (munmap(fm->addr, fm->size) == -1) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      "munmap(%uz) \"%s\" failed", fm->size, fm->name);
+    }
+
+    if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                      ngx_close_file_n " \"%s\" failed", fm->name);
+    }
+}
+
+
+ngx_int_t
 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
 {
     dir->dir = opendir((const char *) name->data);
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -18,6 +18,15 @@ typedef ino_t                    ngx_fil
 
 
 typedef struct {
+    u_char                      *name;
+    size_t                       size;
+    void                        *addr;
+    ngx_fd_t                     fd;
+    ngx_log_t                   *log;
+} ngx_file_mapping_t;
+
+
+typedef struct {
     DIR                         *dir;
     struct dirent               *de;
     struct stat                  info;
@@ -152,6 +161,10 @@ ngx_int_t ngx_set_file_time(u_char *name
 #define ngx_file_uniq(sb)        (sb)->st_ino
 
 
+ngx_int_t ngx_create_file_mapping(ngx_file_mapping_t *fm);
+void ngx_close_file_mapping(ngx_file_mapping_t *fm);
+
+
 #if (NGX_HAVE_CASELESS_FILESYSTEM)
 
 #define ngx_filename_cmp(s1, s2, n)  strncasecmp((char *) s1, (char *) s2, n)
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -332,6 +332,98 @@ ngx_set_file_time(u_char *name, ngx_fd_t
 }
 
 
+ngx_int_t
+ngx_create_file_mapping(ngx_file_mapping_t *fm)
+{
+    LARGE_INTEGER  size;
+
+    fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
+                           NGX_FILE_DEFAULT_ACCESS);
+    if (fm->fd == NGX_INVALID_FILE) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      ngx_open_file_n " \"%s\" failed", fm->name);
+        return NGX_ERROR;
+    }
+
+    fm->handle = NULL;
+
+    size.QuadPart = fm->size;
+
+    if (SetFilePointerEx(fm->fd, size, NULL, FILE_BEGIN) == 0) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      "SetFilePointerEx(\"%s\", %uz) failed",
+                      fm->name, fm->size);
+        goto failed;
+    }
+
+    if (SetEndOfFile(fm->fd) == 0) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      "SetEndOfFile() \"%s\" failed", fm->name);
+        goto failed;
+    }
+
+    fm->handle = CreateFileMapping(fm->fd, NULL, PAGE_READWRITE,
+                                   (u_long) ((off_t) fm->size >> 32),
+                                   (u_long) ((off_t) fm->size & 0xffffffff),
+                                   NULL);
+    if (fm->handle == NULL) {
+        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                      "CreateFileMapping(%s, %uz) failed",
+                      fm->name, fm->size);
+        goto failed;
+    }
+
+    fm->addr = MapViewOfFile(fm->handle, FILE_MAP_WRITE, 0, 0, 0);
+
+    if (fm->addr != NULL) {
+        return NGX_OK;
+    }
+
+    ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+                  "MapViewOfFile(%uz) of file mapping \"%s\" failed",
+                  fm->size, fm->name);
+
+failed:
+
+    if (fm->handle) {
+        if (CloseHandle(fm->handle) == 0) {
+            ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                          "CloseHandle() of file mapping \"%s\" failed",
+                          fm->name);
+        }
+    }
+
+    if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                      ngx_close_file_n " \"%s\" failed", fm->name);
+    }
+
+    return NGX_ERROR;
+}
+
+
+void
+ngx_close_file_mapping(ngx_file_mapping_t *fm)
+{
+    if (UnmapViewOfFile(fm->addr) == 0) {
+        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                      "UnmapViewOfFile(%p) of file mapping \"%s\" failed",
+                      fm->addr, &fm->name);
+    }
+
+    if (CloseHandle(fm->handle) == 0) {
+        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                      "CloseHandle() of file mapping \"%s\" failed",
+                      &fm->name);
+    }
+
+    if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+                      ngx_close_file_n " \"%s\" failed", fm->name);
+    }
+}
+
+
 char *
 ngx_realpath(u_char *path, u_char *resolved)
 {
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -16,6 +16,17 @@ typedef HANDLE                      ngx_
 typedef BY_HANDLE_FILE_INFORMATION  ngx_file_info_t;
 typedef uint64_t                    ngx_file_uniq_t;
 
+
+typedef struct {
+    u_char                         *name;
+    size_t                          size;
+    void                           *addr;
+    ngx_fd_t                        fd;
+    HANDLE                          handle;
+    ngx_log_t                      *log;
+} ngx_file_mapping_t;
+
+
 typedef struct {
     HANDLE                          dir;
     WIN32_FIND_DATA                 finddata;
@@ -154,6 +165,10 @@ ngx_int_t ngx_file_info(u_char *filename
                                | (fi)->ftLastWriteTime.dwLowDateTime)        \
                                           - 116444736000000000) / 10000000)
 
+ngx_int_t ngx_create_file_mapping(ngx_file_mapping_t *fm);
+void ngx_close_file_mapping(ngx_file_mapping_t *fm);
+
+
 #define NGX_HAVE_CASELESS_FILESYSTEM  1
 
 #define ngx_filename_cmp(s1, s2, n) _strnicmp((char *) s1, (char *) s2, n)