aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanusz Dziemidowicz <rraptorr@nails.eu.org>2011-09-20 21:20:51 +0200
committerBadlop <badlop@process-one.net>2011-09-25 00:56:15 +0200
commit3fd5513549878e0bb586134d64ad82db5f59e1ee (patch)
treeb963e84ce3cb8266639552853758194876191e52
parentFix mod_muc_log crash when first log entry is room being destroyed (EJAB-1499) (diff)
Decrease CPU usage caused by tls:send with large data.
Sending one large chunk of data with tls:send eats lots of CPU power and blocks whole Erlang emulator. This is caused by the fact that encrypted output is read from memory BIO in 1k chunks. Memory BIO, after reading data, shifts the remaining part. If large chunks of data (few MB) is sent and then read in 1k chunks, then a _lot_ of shifting is performed eating CPU. The solution is to simply allocate binary of the needed size (amount of data in memory BIO can be retrieved with BIO_ctrl_pending) and then issue only one read that reads the whole data.
-rw-r--r--src/tls/tls_drv.c16
1 files changed, 3 insertions, 13 deletions
diff --git a/src/tls/tls_drv.c b/src/tls/tls_drv.c
index 36cd8d9b9..bdb5446f2 100644
--- a/src/tls/tls_drv.c
+++ b/src/tls/tls_drv.c
@@ -407,22 +407,12 @@ static int tls_drv_control(ErlDrvData handle,
break;
case GET_ENCRYPTED_OUTPUT:
die_unless(d->ssl, "SSL not initialized");
- size = BUF_SIZE + 1;
- rlen = 1;
+ size = BIO_ctrl_pending(d->bio_write) + 1;
b = driver_alloc_binary(size);
b->orig_bytes[0] = 0;
- while ((res = BIO_read(d->bio_write,
- b->orig_bytes + rlen, BUF_SIZE)) > 0)
- {
- //printf("%d bytes of encrypted data read from state machine\r\n", res);
-
- rlen += res;
- size += BUF_SIZE;
- b = driver_realloc_binary(b, size);
- }
- b = driver_realloc_binary(b, rlen);
+ BIO_read(d->bio_write, b->orig_bytes + 1, size - 1);
*rbuf = (char *)b;
- return rlen;
+ return size;
case GET_DECRYPTED_INPUT:
if (!SSL_is_init_finished(d->ssl))
{