summaryrefslogtreecommitdiff
path: root/main/streams/plain_wrapper.c
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-02-28 01:47:28 +0000
committerWez Furlong <wez@php.net>2003-02-28 01:47:28 +0000
commitcd98ed7b0aa91f7427251aa3168e7c8523e7df75 (patch)
tree7a73e0b666965862a3f8c1706250bb9c4f3e4206 /main/streams/plain_wrapper.c
parent7be8179520a89609527a2d8c8defd53b222f10f8 (diff)
downloadphp-git-cd98ed7b0aa91f7427251aa3168e7c8523e7df75.tar.gz
Implement memory mapping for win32.
Could do with some rigorous testing; simple readfile() tests here appear to work.
Diffstat (limited to 'main/streams/plain_wrapper.c')
-rw-r--r--main/streams/plain_wrapper.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index f121b8ce15..ce2a7a553d 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -149,6 +149,10 @@ typedef struct {
char *last_mapped_addr;
size_t last_mapped_len;
#endif
+#ifdef PHP_WIN32
+ char *last_mapped_addr;
+ HANDLE file_mapping;
+#endif
} php_stdio_stream_data;
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC)
@@ -362,6 +366,15 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC)
munmap(data->last_mapped_addr, data->last_mapped_len);
data->last_mapped_addr = NULL;
}
+#elif defined(PHP_WIN32)
+ if (data->last_mapped_addr) {
+ UnmapViewOfFile(data->last_mapped_addr);
+ data->last_mapped_addr = NULL;
+ }
+ if (data->file_mapping) {
+ CloseHandle(data->file_mapping);
+ data->file_mapping = NULL;
+ }
#endif
if (close_handle) {
@@ -643,6 +656,88 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
return PHP_STREAM_OPTION_RETURN_ERR;
}
}
+#elif defined(PHP_WIN32)
+ {
+ php_stream_mmap_range *range = (php_stream_mmap_range*)ptrparam;
+ HANDLE hfile = (HANDLE)_get_osfhandle(fd);
+ DWORD prot, acc, loffs = 0, delta = 0;
+
+ switch (value) {
+ case PHP_STREAM_MMAP_SUPPORTED:
+ return hfile == INVALID_HANDLE_VALUE ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK;
+
+ case PHP_STREAM_MMAP_MAP_RANGE:
+ switch (range->mode) {
+ case PHP_STREAM_MAP_MODE_READONLY:
+ prot = PAGE_READONLY;
+ acc = FILE_MAP_READ;
+ break;
+ case PHP_STREAM_MAP_MODE_READWRITE:
+ prot = PAGE_READWRITE;
+ acc = FILE_MAP_READ | FILE_MAP_WRITE;
+ break;
+ case PHP_STREAM_MAP_MODE_SHARED_READONLY:
+ prot = PAGE_READONLY;
+ acc = FILE_MAP_READ;
+ /* TODO: we should assign a name for the mapping */
+ break;
+ case PHP_STREAM_MAP_MODE_SHARED_READWRITE:
+ prot = PAGE_READWRITE;
+ acc = FILE_MAP_READ | FILE_MAP_WRITE;
+ /* TODO: we should assign a name for the mapping */
+ break;
+ }
+
+ /* create a mapping capable of viewing the whole file (this costs no real resources) */
+ data->file_mapping = CreateFileMapping(hfile, NULL, prot, 0, 0, NULL);
+
+ if (data->file_mapping == NULL) {
+ return PHP_STREAM_OPTION_RETURN_ERR;
+ }
+
+ if (range->length == 0) {
+ range->length = GetFileSize(hfile, NULL) - range->offset;
+ }
+
+ /* figure out how big a chunk to map to be able to view the part that we need */
+ if (range->offset != 0) {
+ SYSTEM_INFO info;
+ DWORD gran;
+
+ GetSystemInfo(&info);
+ gran = info.dwAllocationGranularity;
+ loffs = (range->offset / gran) * gran;
+ delta = range->offset - loffs;
+ }
+
+ data->last_mapped_addr = MapViewOfFile(data->file_mapping, acc, 0, loffs, range->length);
+
+ if (data->last_mapped_addr) {
+ /* give them back the address of the start offset they requested */
+ range->mapped = data->last_mapped_addr + delta;
+ return PHP_STREAM_OPTION_RETURN_OK;
+ }
+
+ CloseHandle(data->file_mapping);
+ data->file_mapping = NULL;
+
+ return PHP_STREAM_OPTION_RETURN_ERR;
+
+ case PHP_STREAM_MMAP_UNMAP:
+ if (data->last_mapped_addr) {
+ UnmapViewOfFile(data->last_mapped_addr);
+ data->last_mapped_addr = NULL;
+ CloseHandle(data->file_mapping);
+ data->file_mapping = NULL;
+ return PHP_STREAM_OPTION_RETURN_OK;
+ }
+ return PHP_STREAM_OPTION_RETURN_ERR;
+
+ default:
+ return PHP_STREAM_OPTION_RETURN_ERR;
+ }
+ }
+
#endif
return PHP_STREAM_OPTION_RETURN_NOTIMPL;