Merge remote-tracking branch 'origin/patches-2.0'

Conflicts:
	buffer.c
	test/regress_buffer.c
This commit is contained in:
Nick Mathewson 2011-10-06 15:21:55 -04:00
commit 8358877768
5 changed files with 62 additions and 4 deletions

View File

@ -315,6 +315,24 @@ evbuffer_new(void)
return (buffer); return (buffer);
} }
int
evbuffer_set_flags(struct evbuffer *buf, ev_uint64_t flags)
{
EVBUFFER_LOCK(buf);
buf->flags |= (ev_uint32_t)flags;
EVBUFFER_UNLOCK(buf);
return 0;
}
int
evbuffer_clear_flags(struct evbuffer *buf, ev_uint64_t flags)
{
EVBUFFER_LOCK(buf);
buf->flags &= ~(ev_uint32_t)flags;
EVBUFFER_UNLOCK(buf);
return 0;
}
void void
_evbuffer_incref(struct evbuffer *buf) _evbuffer_incref(struct evbuffer *buf)
{ {
@ -2742,7 +2760,6 @@ evbuffer_file_segment_new(
} }
} }
#endif #endif
{ {
ev_off_t start_pos = lseek(fd, 0, SEEK_CUR), pos; ev_off_t start_pos = lseek(fd, 0, SEEK_CUR), pos;
ev_off_t read_so_far = 0; ev_off_t read_so_far = 0;

View File

@ -329,6 +329,7 @@ bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
return NULL; return NULL;
} }
bufev = &bufev_p->bev; bufev = &bufev_p->bev;
evbuffer_set_flags(bufev->output, EVBUFFER_FLAG_DRAINS_TO_FD);
event_assign(&bufev->ev_read, bufev->ev_base, fd, event_assign(&bufev->ev_read, bufev->ev_base, fd,
EV_READ|EV_PERSIST, bufferevent_readcb, bufev); EV_READ|EV_PERSIST, bufferevent_readcb, bufev);

View File

@ -130,6 +130,8 @@ struct evbuffer {
/** True iff this buffer is set up for overlapped IO. */ /** True iff this buffer is set up for overlapped IO. */
unsigned is_overlapped : 1; unsigned is_overlapped : 1;
#endif #endif
/** Zero or more EVBUFFER_FLAG_* bits */
ev_uint32_t flags;
/** Used to implement deferred callbacks. */ /** Used to implement deferred callbacks. */
struct deferred_cb_queue *cb_queue; struct deferred_cb_queue *cb_queue;

View File

@ -152,7 +152,6 @@ struct evbuffer_iovec {
occurred occurred
*/ */
struct evbuffer *evbuffer_new(void); struct evbuffer *evbuffer_new(void);
/** /**
Deallocate storage for an evbuffer. Deallocate storage for an evbuffer.
@ -186,6 +185,41 @@ void evbuffer_lock(struct evbuffer *buf);
*/ */
void evbuffer_unlock(struct evbuffer *buf); void evbuffer_unlock(struct evbuffer *buf);
/** If this flag is set, then we will not use evbuffer_peek(),
* evbuffer_remove(), evbuffer_remove_buffer(), and so on to read bytes
* from this buffer: we'll only take bytes out of this buffer by
* writing them to the network (as with evbuffer_write_atmost), by
* removing them without observing them (as with evbuffer_drain),
* or by copying them all out at once (as with evbuffer_add_buffer).
*
* Using this option allows the implementation to use sendfile-based
* operations for evbuffer_add_file(); see that function for more
* information.
*
* This flag is on by default for bufferevents that can take advantage
* of it; you should never actually need to set it on a bufferevent's
* output buffer.
*/
#define EVBUFFER_FLAG_DRAINS_TO_FD 1
/** Change the flags that are set for an evbuffer by adding more.
*
* @param buffer the evbuffer that the callback is watching.
* @param cb the callback whose status we want to change.
* @param flags One or more EVBUFFER_FLAG_* options
* @return 0 on success, -1 on failure.
*/
int evbuffer_set_flags(struct evbuffer *buf, ev_uint64_t flags);
/** Change the flags that are set for an evbuffer by removing some.
*
* @param buffer the evbuffer that the callback is watching.
* @param cb the callback whose status we want to change.
* @param flags One or more EVBUFFER_FLAG_* options
* @return 0 on success, -1 on failure.
*/
int evbuffer_clear_flags(struct evbuffer *buf, ev_uint64_t flags);
/** /**
Returns the total number of bytes stored in the evbuffer Returns the total number of bytes stored in the evbuffer
@ -419,8 +453,9 @@ int evbuffer_add_reference(struct evbuffer *outbuf,
Copy data from a file into the evbuffer for writing to a socket. Copy data from a file into the evbuffer for writing to a socket.
This function avoids unnecessary data copies between userland and This function avoids unnecessary data copies between userland and
kernel. Where available, it uses sendfile or splice; failing those, kernel. If sendfile is available and the EVBUFFER_FLAG_DRAINS_TO_FD
it tries to use mmap. flag is set, it uses those functions. Otherwise, it tries to use
mmap (or CreateFileMapping on Windows).
The function owns the resulting file descriptor and will close it The function owns the resulting file descriptor and will close it
when finished transferring data. when finished transferring data.

View File

@ -751,6 +751,9 @@ test_evbuffer_add_file(void *ptr)
tt_skip(); tt_skip();
} }
/* Say that it drains to a fd so that we can use sendfile. */
evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
#if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__) #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
/* We need to use a pair of AF_INET sockets, since Solaris /* We need to use a pair of AF_INET sockets, since Solaris
doesn't support sendfile() over AF_UNIX. */ doesn't support sendfile() over AF_UNIX. */