mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
Add CreateFileMapping file_segment implementation for win32
This commit is contained in:
parent
c2d9884a6a
commit
3f405d2d4b
57
buffer.c
57
buffer.c
@ -192,9 +192,14 @@ evbuffer_chain_free(struct evbuffer_chain *chain)
|
|||||||
EVBUFFER_CHAIN_EXTRA(
|
EVBUFFER_CHAIN_EXTRA(
|
||||||
struct evbuffer_chain_file_segment,
|
struct evbuffer_chain_file_segment,
|
||||||
chain);
|
chain);
|
||||||
if (info->segment)
|
if (info->segment) {
|
||||||
|
#ifdef WIN32
|
||||||
|
if (info->segment->type == EVBUF_FS_MMAP)
|
||||||
|
UnmapViewOfFile(chain->buffer);
|
||||||
|
#endif
|
||||||
evbuffer_file_segment_free(info->segment);
|
evbuffer_file_segment_free(info->segment);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mm_free(chain);
|
mm_free(chain);
|
||||||
}
|
}
|
||||||
@ -2615,7 +2620,6 @@ evbuffer_file_segment_new(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(_EVENT_HAVE_MMAP)
|
#if defined(_EVENT_HAVE_MMAP)
|
||||||
/* TODO: Implement an mmap-alike for windows. */
|
|
||||||
if (!(flags & EVBUF_FS_DISABLE_MMAP)) {
|
if (!(flags & EVBUF_FS_DISABLE_MMAP)) {
|
||||||
off_t offset_rounded = 0, offset_leftover = 0;
|
off_t offset_rounded = 0, offset_leftover = 0;
|
||||||
void *mapped;
|
void *mapped;
|
||||||
@ -2656,6 +2660,24 @@ evbuffer_file_segment_new(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
if (!(flags & EVBUF_FS_DISABLE_MMAP)) {
|
||||||
|
long h = (long)_get_osfhandle(fd);
|
||||||
|
HANDLE m;
|
||||||
|
ev_uint64_t total_size = length+offset;
|
||||||
|
if (h == (long)INVALID_HANDLE_VALUE)
|
||||||
|
return NULL;
|
||||||
|
m = CreateFileMapping((HANDLE)h, NULL, PAGE_READONLY,
|
||||||
|
(total_size >> 32), total_size & 0xfffffffful,
|
||||||
|
NULL);
|
||||||
|
if (m != INVALID_HANDLE_VALUE) { /* Does h leak? */
|
||||||
|
seg->mapping_handle = m;
|
||||||
|
seg->offset = offset;
|
||||||
|
seg->type = EVBUF_FS_MMAP;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
ev_off_t start_pos = lseek(fd, 0, SEEK_CUR), pos;
|
ev_off_t start_pos = lseek(fd, 0, SEEK_CUR), pos;
|
||||||
@ -2719,8 +2741,12 @@ evbuffer_file_segment_free(struct evbuffer_file_segment *seg)
|
|||||||
if (seg->type == EVBUF_FS_SENDFILE) {
|
if (seg->type == EVBUF_FS_SENDFILE) {
|
||||||
;
|
;
|
||||||
} else if (seg->type == EVBUF_FS_MMAP) {
|
} else if (seg->type == EVBUF_FS_MMAP) {
|
||||||
|
#ifdef WIN32
|
||||||
|
CloseHandle(seg->mapping_handle);
|
||||||
|
#elif defined (_EVENT_HAVE_MMAP)
|
||||||
if (munmap(seg->mapping, seg->length) == -1)
|
if (munmap(seg->mapping, seg->length) == -1)
|
||||||
event_warn("%s: munmap failed", __func__);
|
event_warn("%s: munmap failed", __func__);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
EVUTIL_ASSERT(seg->type == EVBUF_FS_IO);
|
EVUTIL_ASSERT(seg->type == EVBUF_FS_IO);
|
||||||
mm_free(seg->contents);
|
mm_free(seg->contents);
|
||||||
@ -2772,9 +2798,36 @@ evbuffer_add_file_segment(struct evbuffer *buf,
|
|||||||
chain->off = length;
|
chain->off = length;
|
||||||
chain->buffer_len = chain->misalign + length;
|
chain->buffer_len = chain->misalign + length;
|
||||||
} else if (seg->type == EVBUF_FS_MMAP) {
|
} else if (seg->type == EVBUF_FS_MMAP) {
|
||||||
|
#ifdef WIN32
|
||||||
|
ev_uint64_t total_offset = seg->offset+offset;
|
||||||
|
ev_uint64_t offset_rounded=0, offset_remaining=0;
|
||||||
|
LPVOID data;
|
||||||
|
if (total_offset) {
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
memset(&si, 0, sizeof(si)); /* cargo cult */
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
offset_remaining = total_offset % si.dwAllocationGranularity;
|
||||||
|
offset_rounded = total_offset - offset_remaining;
|
||||||
|
}
|
||||||
|
data = MapViewOfFile(
|
||||||
|
seg->mapping_handle,
|
||||||
|
FILE_MAP_READ,
|
||||||
|
offset_rounded >> 32,
|
||||||
|
offset_rounded & 0xfffffffful,
|
||||||
|
length);
|
||||||
|
if (data == NULL) {
|
||||||
|
mm_free(chain);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
chain->buffer = (unsigned char*) data;
|
||||||
|
chain->buffer_len = length+offset_remaining;
|
||||||
|
chain->misalign = offset_remaining;
|
||||||
|
chain->off = length;
|
||||||
|
#else
|
||||||
chain->buffer = (unsigned char*)(seg->contents + offset);
|
chain->buffer = (unsigned char*)(seg->contents + offset);
|
||||||
chain->buffer_len = length;
|
chain->buffer_len = length;
|
||||||
chain->off = length;
|
chain->off = length;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
EVUTIL_ASSERT(seg->type == EVBUF_FS_IO);
|
EVUTIL_ASSERT(seg->type == EVBUF_FS_IO);
|
||||||
chain->buffer = (unsigned char*)(seg->contents + offset);
|
chain->buffer = (unsigned char*)(seg->contents + offset);
|
||||||
|
@ -204,6 +204,10 @@ struct evbuffer_chain_reference {
|
|||||||
* evbuffer_chain with the EVBUFFER_FILESEGMENT flag set. */
|
* evbuffer_chain with the EVBUFFER_FILESEGMENT flag set. */
|
||||||
struct evbuffer_chain_file_segment {
|
struct evbuffer_chain_file_segment {
|
||||||
struct evbuffer_file_segment *segment;
|
struct evbuffer_file_segment *segment;
|
||||||
|
#ifdef WIN32
|
||||||
|
/** If we're using CreateFileMapping, this is the handle to the view. */
|
||||||
|
HANDLE view_handle;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Declared in event2/buffer.h; defined here. */
|
/* Declared in event2/buffer.h; defined here. */
|
||||||
@ -219,6 +223,10 @@ struct evbuffer_file_segment {
|
|||||||
int fd;
|
int fd;
|
||||||
/** If we're using mmap, this is the raw mapped memory. */
|
/** If we're using mmap, this is the raw mapped memory. */
|
||||||
void *mapping;
|
void *mapping;
|
||||||
|
#ifdef WIN32
|
||||||
|
/** If we're using CreateFileMapping, this is the mapping */
|
||||||
|
HANDLE mapping_handle;
|
||||||
|
#endif
|
||||||
/** If we're using mmap or IO, this is the content of the file
|
/** If we're using mmap or IO, this is the content of the file
|
||||||
* segment. */
|
* segment. */
|
||||||
char *contents;
|
char *contents;
|
||||||
@ -226,9 +234,9 @@ struct evbuffer_file_segment {
|
|||||||
* this data segment begins. If we're using sendfile, this is the
|
* this data segment begins. If we're using sendfile, this is the
|
||||||
* offset within the file where this data begins. If we're using IO,
|
* offset within the file where this data begins. If we're using IO,
|
||||||
* this is 0. */
|
* this is 0. */
|
||||||
off_t offset;
|
ev_off_t offset;
|
||||||
/** The length of this segment. */
|
/** The length of this segment. */
|
||||||
off_t length;
|
ev_off_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EVBUFFER_CHAIN_SIZE sizeof(struct evbuffer_chain)
|
#define EVBUFFER_CHAIN_SIZE sizeof(struct evbuffer_chain)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user