Try to send data using writev() to reduce copying and system calls.
This commit is contained in:
parent
be098144db
commit
d183c7b3dc
@ -160,10 +160,46 @@ static void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
|
||||
|
||||
int ioq_send_send(struct ioq_send* q, struct net_connection* con)
|
||||
{
|
||||
int ret;
|
||||
struct adc_message* msg = list_get_first(q->queue);
|
||||
if (!msg) return 0;
|
||||
uhub_assert(msg->cache && *msg->cache);
|
||||
int ret;
|
||||
struct adc_message* msg = list_get_first(q->queue);
|
||||
if (!msg) return 0;
|
||||
uhub_assert(msg->cache && *msg->cache);
|
||||
|
||||
#ifdef HAVE_FUNC_WRITEV
|
||||
#define MAX_IOVEC 32
|
||||
struct iovec vec[MAX_IOVEC];
|
||||
size_t n = 0;
|
||||
vec[0].iov_base = msg->cache + q->offset;
|
||||
vec[0].iov_len = msg->length - q->offset;
|
||||
|
||||
for (struct adc_message* tmp = (struct adc_message*) list_get_next(q->queue), n = 1; tmp && n < MAX_IOVEC; tmp = (struct adc_message*) list_get_next(q->queue), n++)
|
||||
{
|
||||
vec[n].iov_base = msg->cache;
|
||||
vec[n].iov_len = msg->length;
|
||||
}
|
||||
|
||||
ret = net_con_writev(con, &iovec, n);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
while (ret > 0)
|
||||
{
|
||||
if (ret >= (msg->length - q->offset))
|
||||
{
|
||||
ret -= (msg->length - q->offset);
|
||||
q->offset = 0;
|
||||
ioq_send_remove(q, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
q->offset += ret;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
ret = net_con_send(con, msg->cache + q->offset, msg->length - q->offset);
|
||||
|
||||
if (ret > 0)
|
||||
@ -176,8 +212,10 @@ int ioq_send_send(struct ioq_send* q, struct net_connection* con)
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int ioq_send_is_empty(struct ioq_send* q)
|
||||
{
|
||||
return (q->size - q->offset) == 0;
|
||||
|
@ -57,6 +57,48 @@ ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FUNC_WRITEV
|
||||
ssize_t net_con_writev(struct net_connection* con, const struct iovec* iov, size_t iocnt)
|
||||
{
|
||||
int ret;
|
||||
#ifdef SSL_SUPPORT
|
||||
if (!con->ssl)
|
||||
{
|
||||
#endif
|
||||
ret = writev(con->sd, iovec, (int) iocnt);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (is_blocked_or_interrupted())
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
#ifdef SSL_SUPPORT
|
||||
}
|
||||
else
|
||||
{
|
||||
ssize_t total = 0;
|
||||
ret = 0;
|
||||
while (iocnt--)
|
||||
{
|
||||
ret = net_ssl_send(con, buf, len);
|
||||
if (ret >= 0)
|
||||
total += ret;
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (total == 0 && !is_blocked_or_interrupted())
|
||||
return -1;
|
||||
|
||||
return total;
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
@ -92,6 +92,11 @@ extern void net_con_close(struct net_connection* con);
|
||||
*/
|
||||
extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len);
|
||||
|
||||
|
||||
#ifdef HAVE_FUNC_WRITEV
|
||||
extern ssize_t net_con_writev(struct net_connection* con, const struct iovec* iov, size_t iocnt);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Receive data
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user