From 697dd7ca17adc62c9c1580d948577b710913937c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attilio=20Don=C3=A0?= Date: Mon, 16 Dec 2024 11:36:58 +0100 Subject: [PATCH 1/3] Optimize writeframe mem allocations --- Project.toml | 2 ++ src/WebSockets.jl | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index b96e06d1..e022c028 100644 --- a/Project.toml +++ b/Project.toml @@ -18,6 +18,7 @@ PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SimpleBufferStream = "777ac1f9-54b0-4bf8-805c-2214025038e7" Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" +TaskLocalValues = "ed4db957-447d-4319-bfb6-7fa9ae7ecf34" URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" @@ -30,6 +31,7 @@ MbedTLS = "0.6.8, 0.7, 1" OpenSSL = "1.3" PrecompileTools = "1.2.1" SimpleBufferStream = "1.1" +TaskLocalValues = "0.1.2" URIs = "1.3" julia = "1.6" diff --git a/src/WebSockets.jl b/src/WebSockets.jl index 1afb5f76..0f00b133 100644 --- a/src/WebSockets.jl +++ b/src/WebSockets.jl @@ -2,6 +2,7 @@ module WebSockets using Base64, UUIDs, Sockets, Random using MbedTLS: digest, MD_SHA1, SSLContext +using TaskLocalValues using ..IOExtras, ..Streams, ..Connections, ..Messages, ..Conditions, ..Servers using ..Exceptions: current_exceptions_to_string import ..open @@ -180,9 +181,14 @@ function readframe(io::IO, ::Type{Frame}, buffer::Vector{UInt8}=UInt8[], first_f return Frame(flags, extlen, mask, payload) end +const frameio = TaskLocalValue{IOBuffer}(() -> IOBuffer()) + # writing a single frame function writeframe(io::IO, x::Frame) - buff = IOBuffer() + buff = frameio[] + buff.ptr = 1 + buff.size = 0 + buff.offset = 0 n = write(buff, hton(uint16(x.flags))) if x.extendedlen !== nothing n += write(buff, hton(x.extendedlen)) @@ -199,7 +205,8 @@ function writeframe(io::IO, x::Frame) else n += write(buff, pl) end - write(io.io, take!(buff)) + seekstart(buff) + write(io.io, buff) return n end From 009ea133c3b3c7ccb37758a799db0df742c5d16b Mon Sep 17 00:00:00 2001 From: attdona Date: Fri, 16 May 2025 11:00:09 +0200 Subject: [PATCH 2/3] lock on write --- src/WebSockets.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/WebSockets.jl b/src/WebSockets.jl index 0f00b133..a99dfa71 100644 --- a/src/WebSockets.jl +++ b/src/WebSockets.jl @@ -10,6 +10,8 @@ import ..HTTP # for doc references export WebSocket, send, receive, ping, pong +write_lock = ReentrantLock() + # 1st 2 bytes of a frame primitive type FrameFlags 16 end uint16(x::FrameFlags) = Base.bitcast(UInt16, x) @@ -206,7 +208,9 @@ function writeframe(io::IO, x::Frame) n += write(buff, pl) end seekstart(buff) - write(io.io, buff) + lock(write_lock) do + write(io.io, buff) + end return n end From 4fe18a77ea73433bb380212bfa6a88901c7e6810 Mon Sep 17 00:00:00 2001 From: attdona Date: Fri, 16 May 2025 12:11:53 +0200 Subject: [PATCH 3/3] Remove thread local storage for julia 1.10.x compat --- src/WebSockets.jl | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/WebSockets.jl b/src/WebSockets.jl index a99dfa71..91612289 100644 --- a/src/WebSockets.jl +++ b/src/WebSockets.jl @@ -183,14 +183,8 @@ function readframe(io::IO, ::Type{Frame}, buffer::Vector{UInt8}=UInt8[], first_f return Frame(flags, extlen, mask, payload) end -const frameio = TaskLocalValue{IOBuffer}(() -> IOBuffer()) - -# writing a single frame function writeframe(io::IO, x::Frame) - buff = frameio[] - buff.ptr = 1 - buff.size = 0 - buff.offset = 0 + buff = IOBuffer() n = write(buff, hton(uint16(x.flags))) if x.extendedlen !== nothing n += write(buff, hton(x.extendedlen)) @@ -207,9 +201,8 @@ function writeframe(io::IO, x::Frame) else n += write(buff, pl) end - seekstart(buff) lock(write_lock) do - write(io.io, buff) + write(io.io, take!(buff)) end return n end