From 865db9bbf3cf97176edabe74e9814b8505343d95 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Tue, 29 Jun 2010 15:18:50 +0000 Subject: [PATCH] ngx_create_file_mapping() --- src/os/unix/ngx_files.c | 52 +++++++++++++++++++++++ src/os/unix/ngx_files.h | 13 ++++++ src/os/win32/ngx_files.c | 92 ++++++++++++++++++++++++++++++++++++++++ src/os/win32/ngx_files.h | 15 +++++++ 4 files changed, 172 insertions(+) diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c index 0ef083824..c11795380 100644 --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -258,6 +258,58 @@ ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s) } +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) { diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h index c40cfe2ea..b7bfff100 100644 --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -17,6 +17,15 @@ typedef struct stat ngx_file_info_t; typedef ino_t ngx_file_uniq_t; +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; @@ -152,6 +161,10 @@ ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s); #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) diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c index 415458bf0..424bd6550 100644 --- 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 fd, time_t s) } +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) { diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h index bd78112e7..fe776057d 100644 --- a/src/os/win32/ngx_files.h +++ b/src/os/win32/ngx_files.h @@ -16,6 +16,17 @@ typedef HANDLE ngx_fd_t; 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, ngx_file_info_t *fi); | (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)