mirror of
https://gitea.invidious.io/iv-org/lsquic.cr
synced 2024-08-15 00:43:31 +00:00
Implement engine_process_connections timer
The previous code did not have an implementation to set timers for processing connections. This leads to an occasional deadlock where process_connections must be called to continue. This change implements this timer modelled after the lsquic reference implementation. Reference: https://github.com/litespeedtech/lsquic/blob/master/bin/prog.c#L535
This commit is contained in:
parent
cd6ec66292
commit
c965e0a380
1 changed files with 20 additions and 2 deletions
|
@ -145,6 +145,7 @@ module QUIC
|
|||
@read_timeout : Float64?
|
||||
@socket : UDPSocket?
|
||||
@stream_ctx : StreamCtx?
|
||||
@process_fiber : Fiber
|
||||
|
||||
def initialize(@host : String, port = nil, tls : Bool | OpenSSL::SSL::Context::Client = false)
|
||||
check_host_only(@host)
|
||||
|
@ -162,6 +163,7 @@ module QUIC
|
|||
@stream_channel = Channel(StreamCtx?).new(20)
|
||||
@stream_ctx = nil
|
||||
@engine_open = false
|
||||
@process_fiber = Fiber.new { puts "process_fiber started before run_engine" }
|
||||
end
|
||||
|
||||
def run_engine
|
||||
|
@ -209,7 +211,7 @@ module QUIC
|
|||
while stream_ctx = @stream_channel.receive
|
||||
LibLsquic.conn_set_ctx(conn, Box.box(stream_ctx))
|
||||
LibLsquic.conn_make_stream(conn)
|
||||
LibLsquic.engine_process_conns(engine)
|
||||
client_process_conns(engine)
|
||||
end
|
||||
@engine_open = false
|
||||
LibLsquic.engine_destroy(engine)
|
||||
|
@ -217,13 +219,25 @@ module QUIC
|
|||
@socket = nil
|
||||
end
|
||||
|
||||
@process_fiber = spawn do
|
||||
loop do
|
||||
sleep
|
||||
LibLsquic.engine_process_conns(engine)
|
||||
diff = 0
|
||||
# check advisory time
|
||||
if LibLsquic.engine_earliest_adv_tick(engine, pointerof(diff)) != 0
|
||||
Thread.current.scheduler.@current.resume_event.add(diff.microseconds)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
buffer = Bytes.new(0x600)
|
||||
loop do
|
||||
bytes_read = socket.read buffer
|
||||
break if !@engine_open
|
||||
LibLsquic.engine_packet_in(engine, buffer[0, bytes_read], bytes_read, socket.local_address, socket.remote_address, Box.box(socket), 0) if bytes_read != 0
|
||||
LibLsquic.engine_process_conns(engine)
|
||||
client_process_conns(engine)
|
||||
end
|
||||
@socket.try &.close
|
||||
@socket = nil
|
||||
|
@ -232,6 +246,10 @@ module QUIC
|
|||
end
|
||||
end
|
||||
|
||||
def client_process_conns(engine)
|
||||
Crystal::Scheduler.yield @process_fiber
|
||||
end
|
||||
|
||||
def socket : UDPSocket
|
||||
socket = @socket
|
||||
return socket.not_nil! if @socket
|
||||
|
|
Loading…
Reference in a new issue