Skip to content

Commit d4389b4

Browse files
committed
Fix performance regression in do_write(s)
This causes significant performance issues when using large (>10meg) writes Fix by adjusting the buffer write function to clear the buffer once, rather than piece by piece, avoiding a case where a large write (in our case, around 70mbytes) will consume 100% of CPU. This takes a webrick GET request via SSL from around 200kbyts/sec and consuming 100% of a core, to line speed on gigabit ethernet and 6% cpu utlization.
1 parent ccc1594 commit d4389b4

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

lib/openssl/buffering.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,18 @@ def do_write(s)
348348
@wbuffer << s
349349
@wbuffer.force_encoding(Encoding::BINARY)
350350
@sync ||= false
351-
if @sync or @wbuffer.size > BLOCK_SIZE
352-
until @wbuffer.empty?
353-
begin
354-
nwrote = syswrite(@wbuffer)
355-
rescue Errno::EAGAIN
356-
retry
351+
buffer_size = @wbuffer.size
352+
if @sync or buffer_size > BLOCK_SIZE
353+
nwrote = 0
354+
begin
355+
while nwrote < buffer_size do
356+
begin
357+
nwrote += syswrite(@wbuffer[nwrote, buffer_size - nwrote])
358+
rescue Errno::EAGAIN
359+
retry
360+
end
357361
end
362+
ensure
358363
@wbuffer[0, nwrote] = ""
359364
end
360365
end

0 commit comments

Comments
 (0)