Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide means for complete cleanup of LibAwsIO default resources #9

Merged
merged 1 commit into from
Feb 4, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 98 additions & 21 deletions src/LibAwsIO.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,92 +45,166 @@ for name in names(@__MODULE__; all=true)
@eval export $name
end

const DEFAULT_AWS_EVENT_LOOP_GROUP = Ref{Ptr{aws_event_loop_group}}(C_NULL)
mutable struct EventLoopGroup
ptr::Ptr{aws_event_loop_group}
EventLoopGroup(ptr::Ptr) =
finalizer(new(Ptr{aws_event_loop_group}(ptr))) do x
if ptr != C_NULL
aws_event_loop_group_release(ptr)
# for i = 1:aws_event_loop_group_get_loop_count(ptr)
# Core.println("stopping event loop $i")
# el = aws_event_loop_group_get_loop_at(ptr, i - 1)
# aws_event_loop_stop(el)
# aws_event_loop_destroy(el)
# end
end
end
end

const DEFAULT_AWS_EVENT_LOOP_GROUP = Ref{EventLoopGroup}(EventLoopGroup(C_NULL))
const DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK = ReentrantLock()

function set_default_aws_event_loop_group!(group)
function set_default_aws_event_loop_group!(group::Ptr{aws_event_loop_group})
@lock DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK begin
DEFAULT_AWS_EVENT_LOOP_GROUP[] = group
DEFAULT_AWS_EVENT_LOOP_GROUP[] = EventLoopGroup(group)
return
end
end

function default_aws_event_loop_group()
@lock DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK begin
if DEFAULT_AWS_EVENT_LOOP_GROUP[] == C_NULL
if DEFAULT_AWS_EVENT_LOOP_GROUP[].ptr == C_NULL
init()
maxthreads = LIB_AWS_IO_MAX_THREADS[]
# populate default event loop group; 0 means one event loop per non-hyperthread core
set_default_aws_event_loop_group!(aws_event_loop_group_new_default(default_aws_allocator(), maxthreads, C_NULL))
end
return DEFAULT_AWS_EVENT_LOOP_GROUP[]
return DEFAULT_AWS_EVENT_LOOP_GROUP[].ptr
end
end

function close_default_aws_event_loop_group!()
@lock DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK begin
if DEFAULT_AWS_EVENT_LOOP_GROUP[].ptr != C_NULL
finalize(DEFAULT_AWS_EVENT_LOOP_GROUP[])
set_default_aws_event_loop_group!(Ptr{aws_event_loop_group}(C_NULL))
end
return
end
end

const DEFAULT_AWS_HOST_RESOLVER = Ref{Ptr{aws_host_resolver}}(C_NULL)
mutable struct HostResolver
ptr::Ptr{aws_host_resolver}
HostResolver(ptr::Ptr) =
finalizer(_ -> aws_host_resolver_release(ptr), new(Ptr{aws_host_resolver}(ptr)))
end

const DEFAULT_AWS_HOST_RESOLVER = Ref{HostResolver}(HostResolver(C_NULL))
const DEFAULT_AWS_HOST_RESOLVER_LOCK = ReentrantLock()

function set_default_aws_host_resolver!(resolver)
function set_default_aws_host_resolver!(resolver::Ptr{aws_host_resolver})
@lock DEFAULT_AWS_HOST_RESOLVER_LOCK begin
DEFAULT_AWS_HOST_RESOLVER[] = resolver
DEFAULT_AWS_HOST_RESOLVER[] = HostResolver(resolver)
return
end
end

function default_aws_host_resolver()
@lock DEFAULT_AWS_HOST_RESOLVER_LOCK begin
if DEFAULT_AWS_HOST_RESOLVER[] == C_NULL
if DEFAULT_AWS_HOST_RESOLVER[].ptr == C_NULL
init()
resolver_options = aws_host_resolver_default_options(8, default_aws_event_loop_group(), C_NULL, C_NULL)
set_default_aws_host_resolver!(aws_host_resolver_new_default(default_aws_allocator(), Ref(resolver_options)))
end
return DEFAULT_AWS_HOST_RESOLVER[]
return DEFAULT_AWS_HOST_RESOLVER[].ptr
end
end

function close_default_aws_host_resolver!()
@lock DEFAULT_AWS_HOST_RESOLVER_LOCK begin
if DEFAULT_AWS_HOST_RESOLVER[].ptr != C_NULL
finalize(DEFAULT_AWS_HOST_RESOLVER[])
set_default_aws_host_resolver!(Ptr{aws_host_resolver}(C_NULL))
end
return
end
end

# aws_client_bootstrap
const DEFAULT_AWS_CLIENT_BOOTSTRAP = Ref{Ptr{aws_client_bootstrap}}(C_NULL)
mutable struct ClientBootstrap
ptr::Ptr{aws_client_bootstrap}
ClientBootstrap(ptr::Ptr) =
finalizer(_ -> aws_client_bootstrap_release(ptr), new(Ptr{aws_client_bootstrap}(ptr)))
end

const DEFAULT_AWS_CLIENT_BOOTSTRAP = Ref{ClientBootstrap}(ClientBootstrap(C_NULL))
const DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK = ReentrantLock()

function set_default_aws_client_bootstrap!(bootstrap)
function set_default_aws_client_bootstrap!(bootstrap::Ptr{aws_client_bootstrap})
@lock DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK begin
DEFAULT_AWS_CLIENT_BOOTSTRAP[] = bootstrap
DEFAULT_AWS_CLIENT_BOOTSTRAP[] = ClientBootstrap(bootstrap)
return
end
end

function default_aws_client_bootstrap()
@lock DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK begin
if DEFAULT_AWS_CLIENT_BOOTSTRAP[] == C_NULL
if DEFAULT_AWS_CLIENT_BOOTSTRAP[].ptr == C_NULL
init()
el_group = default_aws_event_loop_group()
host_resolver = default_aws_host_resolver()
bootstrap_options = aws_client_bootstrap_options(el_group, host_resolver, C_NULL, C_NULL, C_NULL)
set_default_aws_client_bootstrap!(aws_client_bootstrap_new(default_aws_allocator(), Ref(bootstrap_options)))
end
return DEFAULT_AWS_CLIENT_BOOTSTRAP[]
return DEFAULT_AWS_CLIENT_BOOTSTRAP[].ptr
end
end

function close_default_aws_client_bootstrap!()
@lock DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK begin
if DEFAULT_AWS_CLIENT_BOOTSTRAP[].ptr != C_NULL
finalize(DEFAULT_AWS_CLIENT_BOOTSTRAP[])
set_default_aws_client_bootstrap!(Ptr{aws_client_bootstrap}(C_NULL))
end
return
end
end

# aws_server_bootstrap
const DEFAULT_AWS_SERVER_BOOTSTRAP = Ref{Ptr{aws_server_bootstrap}}(C_NULL)
mutable struct ServerBootstrap
ptr::Ptr{aws_server_bootstrap}
ServerBootstrap(ptr::Ptr) =
finalizer(_ -> aws_server_bootstrap_release(ptr), new(Ptr{aws_server_bootstrap}(ptr)))
end

const DEFAULT_AWS_SERVER_BOOTSTRAP = Ref{ServerBootstrap}(ServerBootstrap(C_NULL))
const DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK = ReentrantLock()

function set_default_aws_server_bootstrap!(bootstrap)
function set_default_aws_server_bootstrap!(bootstrap::Ptr{aws_server_bootstrap})
@lock DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK begin
DEFAULT_AWS_SERVER_BOOTSTRAP[] = bootstrap
DEFAULT_AWS_SERVER_BOOTSTRAP[] = ServerBootstrap(bootstrap)
return
end
end

function default_aws_server_bootstrap()
@lock DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK begin
if DEFAULT_AWS_SERVER_BOOTSTRAP[] == C_NULL
if DEFAULT_AWS_SERVER_BOOTSTRAP[].ptr == C_NULL
init()
el_group = default_aws_event_loop_group()
set_default_aws_server_bootstrap!(aws_server_bootstrap_new(default_aws_allocator(), el_group))
end
return DEFAULT_AWS_SERVER_BOOTSTRAP[]
return DEFAULT_AWS_SERVER_BOOTSTRAP[].ptr
end
end

function close_default_aws_server_bootstrap!()
@lock DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK begin
if DEFAULT_AWS_SERVER_BOOTSTRAP[].ptr != C_NULL
finalize(DEFAULT_AWS_SERVER_BOOTSTRAP[])
set_default_aws_server_bootstrap!(Ptr{aws_server_bootstrap}(C_NULL))
end
return
end
end

Expand Down Expand Up @@ -184,7 +258,10 @@ function tlsoptions(host::String;
return tls_options
end

export default_aws_event_loop_group, set_default_aws_event_loop_group!, default_aws_host_resolver, default_aws_client_bootstrap, set_default_aws_client_bootstrap!, default_aws_server_bootstrap, set_default_aws_server_bootstrap!, tlsoptions
export default_aws_event_loop_group, set_default_aws_event_loop_group!, default_aws_host_resolver,
default_aws_client_bootstrap, set_default_aws_client_bootstrap!, default_aws_server_bootstrap,
set_default_aws_server_bootstrap!, tlsoptions, close_default_aws_event_loop_group!,
close_default_aws_host_resolver!, close_default_aws_client_bootstrap!, close_default_aws_server_bootstrap!

const LIB_AWS_IO_MAX_THREADS = Ref{Int}(0)

Expand Down
Loading