mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Make evbuffer_add_file() work on windows
Right now only the add_file() mode is supported, when it would be nicer to have mmap support. Perhaps for Libevent 2.1.x.
This commit is contained in:
parent
b4f12a17aa
commit
dcdae6b743
59
buffer.c
59
buffer.c
@ -141,6 +141,13 @@ static int evbuffer_ptr_memcmp(const struct evbuffer *buf,
|
|||||||
static struct evbuffer_chain *evbuffer_expand_singlechain(struct evbuffer *buf,
|
static struct evbuffer_chain *evbuffer_expand_singlechain(struct evbuffer *buf,
|
||||||
size_t datlen);
|
size_t datlen);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
static int evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd,
|
||||||
|
int howmuch);
|
||||||
|
#else
|
||||||
|
#define evbuffer_readfile evbuffer_read
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct evbuffer_chain *
|
static struct evbuffer_chain *
|
||||||
evbuffer_chain_new(size_t size)
|
evbuffer_chain_new(size_t size)
|
||||||
{
|
{
|
||||||
@ -1998,6 +2005,56 @@ done:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
static int
|
||||||
|
evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int nchains, n;
|
||||||
|
struct evbuffer_iovec v[2];
|
||||||
|
|
||||||
|
EVBUFFER_LOCK(buf);
|
||||||
|
|
||||||
|
if (buf->freeze_end) {
|
||||||
|
result = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (howmuch < 0)
|
||||||
|
howmuch = 16384;
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX we _will_ waste some space here if there is any space left
|
||||||
|
* over on buf->last. */
|
||||||
|
nchains = evbuffer_reserve_space(buf, howmuch, v, 2);
|
||||||
|
if (nchains < 1 || nchains > 2) {
|
||||||
|
result = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
n = read(fd, v[0].iov_base, v[0].iov_len);
|
||||||
|
if (n <= 0) {
|
||||||
|
result = n;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
v[0].iov_len = n;
|
||||||
|
if (nchains > 1) {
|
||||||
|
n = read(fd, v[1].iov_base, v[1].iov_len);
|
||||||
|
if (n <= 0) {
|
||||||
|
result = v[0].iov_len;
|
||||||
|
evbuffer_commit_space(buf, v, 1);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
v[1].iov_len = n;
|
||||||
|
}
|
||||||
|
evbuffer_commit_space(buf, v, nchains);
|
||||||
|
|
||||||
|
result = n;
|
||||||
|
done:
|
||||||
|
EVBUFFER_UNLOCK(buf);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_IOVEC_IMPL
|
#ifdef USE_IOVEC_IMPL
|
||||||
static inline int
|
static inline int
|
||||||
evbuffer_write_iovec(struct evbuffer *buffer, evutil_socket_t fd,
|
evbuffer_write_iovec(struct evbuffer *buffer, evutil_socket_t fd,
|
||||||
@ -2592,7 +2649,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd,
|
|||||||
* can abort without side effects if the read fails.
|
* can abort without side effects if the read fails.
|
||||||
*/
|
*/
|
||||||
while (length) {
|
while (length) {
|
||||||
read = evbuffer_read(tmp, fd, length);
|
read = evbuffer_readfile(tmp, fd, length);
|
||||||
if (read == -1) {
|
if (read == -1) {
|
||||||
evbuffer_free(tmp);
|
evbuffer_free(tmp);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -596,6 +596,8 @@ test_evbuffer_add_file(void *ptr)
|
|||||||
const char *compare;
|
const char *compare;
|
||||||
evutil_socket_t fd, pair[2];
|
evutil_socket_t fd, pair[2];
|
||||||
|
|
||||||
|
/* Add a test for a big file. XXXX */
|
||||||
|
|
||||||
tt_assert(impl);
|
tt_assert(impl);
|
||||||
if (!strcmp(impl, "sendfile")) {
|
if (!strcmp(impl, "sendfile")) {
|
||||||
if (!_evbuffer_testing_use_sendfile())
|
if (!_evbuffer_testing_use_sendfile())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user