Skip to content

Commit 3904204

Browse files
committed
Provide means for complete cleanup of LibAwsIO default resources
Creates a mutable struct wrapper for each default resource so we can add appropraite finalizers. Also adds a convenience close_ method for each resource that will finalize the current resource and reset it to "null". This machinery is necessary for precompile workloads to appropriately do a total cleanup of all process resources (as discovered in JuliaWeb/HTTP.jl#1213)
1 parent 09b5aa9 commit 3904204

File tree

1 file changed

+98
-21
lines changed

1 file changed

+98
-21
lines changed

src/LibAwsIO.jl

Lines changed: 98 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,92 +45,166 @@ for name in names(@__MODULE__; all=true)
4545
@eval export $name
4646
end
4747

48-
const DEFAULT_AWS_EVENT_LOOP_GROUP = Ref{Ptr{aws_event_loop_group}}(C_NULL)
48+
mutable struct EventLoopGroup
49+
ptr::Ptr{aws_event_loop_group}
50+
EventLoopGroup(ptr::Ptr) =
51+
finalizer(new(Ptr{aws_event_loop_group}(ptr))) do x
52+
if ptr != C_NULL
53+
aws_event_loop_group_release(ptr)
54+
# for i = 1:aws_event_loop_group_get_loop_count(ptr)
55+
# Core.println("stopping event loop $i")
56+
# el = aws_event_loop_group_get_loop_at(ptr, i - 1)
57+
# aws_event_loop_stop(el)
58+
# aws_event_loop_destroy(el)
59+
# end
60+
end
61+
end
62+
end
63+
64+
const DEFAULT_AWS_EVENT_LOOP_GROUP = Ref{EventLoopGroup}(EventLoopGroup(C_NULL))
4965
const DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK = ReentrantLock()
5066

51-
function set_default_aws_event_loop_group!(group)
67+
function set_default_aws_event_loop_group!(group::Ptr{aws_event_loop_group})
5268
@lock DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK begin
53-
DEFAULT_AWS_EVENT_LOOP_GROUP[] = group
69+
DEFAULT_AWS_EVENT_LOOP_GROUP[] = EventLoopGroup(group)
5470
return
5571
end
5672
end
5773

5874
function default_aws_event_loop_group()
5975
@lock DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK begin
60-
if DEFAULT_AWS_EVENT_LOOP_GROUP[] == C_NULL
76+
if DEFAULT_AWS_EVENT_LOOP_GROUP[].ptr == C_NULL
6177
init()
6278
maxthreads = LIB_AWS_IO_MAX_THREADS[]
6379
# populate default event loop group; 0 means one event loop per non-hyperthread core
6480
set_default_aws_event_loop_group!(aws_event_loop_group_new_default(default_aws_allocator(), maxthreads, C_NULL))
6581
end
66-
return DEFAULT_AWS_EVENT_LOOP_GROUP[]
82+
return DEFAULT_AWS_EVENT_LOOP_GROUP[].ptr
83+
end
84+
end
85+
86+
function close_default_aws_event_loop_group!()
87+
@lock DEFAULT_AWS_EVENT_LOOP_GROUP_LOCK begin
88+
if DEFAULT_AWS_EVENT_LOOP_GROUP[].ptr != C_NULL
89+
finalize(DEFAULT_AWS_EVENT_LOOP_GROUP[])
90+
set_default_aws_event_loop_group!(Ptr{aws_event_loop_group}(C_NULL))
91+
end
92+
return
6793
end
6894
end
6995

70-
const DEFAULT_AWS_HOST_RESOLVER = Ref{Ptr{aws_host_resolver}}(C_NULL)
96+
mutable struct HostResolver
97+
ptr::Ptr{aws_host_resolver}
98+
HostResolver(ptr::Ptr) =
99+
finalizer(_ -> aws_host_resolver_release(ptr), new(Ptr{aws_host_resolver}(ptr)))
100+
end
101+
102+
const DEFAULT_AWS_HOST_RESOLVER = Ref{HostResolver}(HostResolver(C_NULL))
71103
const DEFAULT_AWS_HOST_RESOLVER_LOCK = ReentrantLock()
72104

73-
function set_default_aws_host_resolver!(resolver)
105+
function set_default_aws_host_resolver!(resolver::Ptr{aws_host_resolver})
74106
@lock DEFAULT_AWS_HOST_RESOLVER_LOCK begin
75-
DEFAULT_AWS_HOST_RESOLVER[] = resolver
107+
DEFAULT_AWS_HOST_RESOLVER[] = HostResolver(resolver)
76108
return
77109
end
78110
end
79111

80112
function default_aws_host_resolver()
81113
@lock DEFAULT_AWS_HOST_RESOLVER_LOCK begin
82-
if DEFAULT_AWS_HOST_RESOLVER[] == C_NULL
114+
if DEFAULT_AWS_HOST_RESOLVER[].ptr == C_NULL
83115
init()
84116
resolver_options = aws_host_resolver_default_options(8, default_aws_event_loop_group(), C_NULL, C_NULL)
85117
set_default_aws_host_resolver!(aws_host_resolver_new_default(default_aws_allocator(), Ref(resolver_options)))
86118
end
87-
return DEFAULT_AWS_HOST_RESOLVER[]
119+
return DEFAULT_AWS_HOST_RESOLVER[].ptr
120+
end
121+
end
122+
123+
function close_default_aws_host_resolver!()
124+
@lock DEFAULT_AWS_HOST_RESOLVER_LOCK begin
125+
if DEFAULT_AWS_HOST_RESOLVER[].ptr != C_NULL
126+
finalize(DEFAULT_AWS_HOST_RESOLVER[])
127+
set_default_aws_host_resolver!(Ptr{aws_host_resolver}(C_NULL))
128+
end
129+
return
88130
end
89131
end
90132

91133
# aws_client_bootstrap
92-
const DEFAULT_AWS_CLIENT_BOOTSTRAP = Ref{Ptr{aws_client_bootstrap}}(C_NULL)
134+
mutable struct ClientBootstrap
135+
ptr::Ptr{aws_client_bootstrap}
136+
ClientBootstrap(ptr::Ptr) =
137+
finalizer(_ -> aws_client_bootstrap_release(ptr), new(Ptr{aws_client_bootstrap}(ptr)))
138+
end
139+
140+
const DEFAULT_AWS_CLIENT_BOOTSTRAP = Ref{ClientBootstrap}(ClientBootstrap(C_NULL))
93141
const DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK = ReentrantLock()
94142

95-
function set_default_aws_client_bootstrap!(bootstrap)
143+
function set_default_aws_client_bootstrap!(bootstrap::Ptr{aws_client_bootstrap})
96144
@lock DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK begin
97-
DEFAULT_AWS_CLIENT_BOOTSTRAP[] = bootstrap
145+
DEFAULT_AWS_CLIENT_BOOTSTRAP[] = ClientBootstrap(bootstrap)
98146
return
99147
end
100148
end
101149

102150
function default_aws_client_bootstrap()
103151
@lock DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK begin
104-
if DEFAULT_AWS_CLIENT_BOOTSTRAP[] == C_NULL
152+
if DEFAULT_AWS_CLIENT_BOOTSTRAP[].ptr == C_NULL
105153
init()
106154
el_group = default_aws_event_loop_group()
107155
host_resolver = default_aws_host_resolver()
108156
bootstrap_options = aws_client_bootstrap_options(el_group, host_resolver, C_NULL, C_NULL, C_NULL)
109157
set_default_aws_client_bootstrap!(aws_client_bootstrap_new(default_aws_allocator(), Ref(bootstrap_options)))
110158
end
111-
return DEFAULT_AWS_CLIENT_BOOTSTRAP[]
159+
return DEFAULT_AWS_CLIENT_BOOTSTRAP[].ptr
160+
end
161+
end
162+
163+
function close_default_aws_client_bootstrap!()
164+
@lock DEFAULT_AWS_CLIENT_BOOTSTRAP_LOCK begin
165+
if DEFAULT_AWS_CLIENT_BOOTSTRAP[].ptr != C_NULL
166+
finalize(DEFAULT_AWS_CLIENT_BOOTSTRAP[])
167+
set_default_aws_client_bootstrap!(Ptr{aws_client_bootstrap}(C_NULL))
168+
end
169+
return
112170
end
113171
end
114172

115173
# aws_server_bootstrap
116-
const DEFAULT_AWS_SERVER_BOOTSTRAP = Ref{Ptr{aws_server_bootstrap}}(C_NULL)
174+
mutable struct ServerBootstrap
175+
ptr::Ptr{aws_server_bootstrap}
176+
ServerBootstrap(ptr::Ptr) =
177+
finalizer(_ -> aws_server_bootstrap_release(ptr), new(Ptr{aws_server_bootstrap}(ptr)))
178+
end
179+
180+
const DEFAULT_AWS_SERVER_BOOTSTRAP = Ref{ServerBootstrap}(ServerBootstrap(C_NULL))
117181
const DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK = ReentrantLock()
118182

119-
function set_default_aws_server_bootstrap!(bootstrap)
183+
function set_default_aws_server_bootstrap!(bootstrap::Ptr{aws_server_bootstrap})
120184
@lock DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK begin
121-
DEFAULT_AWS_SERVER_BOOTSTRAP[] = bootstrap
185+
DEFAULT_AWS_SERVER_BOOTSTRAP[] = ServerBootstrap(bootstrap)
122186
return
123187
end
124188
end
125189

126190
function default_aws_server_bootstrap()
127191
@lock DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK begin
128-
if DEFAULT_AWS_SERVER_BOOTSTRAP[] == C_NULL
192+
if DEFAULT_AWS_SERVER_BOOTSTRAP[].ptr == C_NULL
129193
init()
130194
el_group = default_aws_event_loop_group()
131195
set_default_aws_server_bootstrap!(aws_server_bootstrap_new(default_aws_allocator(), el_group))
132196
end
133-
return DEFAULT_AWS_SERVER_BOOTSTRAP[]
197+
return DEFAULT_AWS_SERVER_BOOTSTRAP[].ptr
198+
end
199+
end
200+
201+
function close_default_aws_server_bootstrap!()
202+
@lock DEFAULT_AWS_SERVER_BOOTSTRAP_LOCK begin
203+
if DEFAULT_AWS_SERVER_BOOTSTRAP[].ptr != C_NULL
204+
finalize(DEFAULT_AWS_SERVER_BOOTSTRAP[])
205+
set_default_aws_server_bootstrap!(Ptr{aws_server_bootstrap}(C_NULL))
206+
end
207+
return
134208
end
135209
end
136210

@@ -184,7 +258,10 @@ function tlsoptions(host::String;
184258
return tls_options
185259
end
186260

187-
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
261+
export default_aws_event_loop_group, set_default_aws_event_loop_group!, default_aws_host_resolver,
262+
default_aws_client_bootstrap, set_default_aws_client_bootstrap!, default_aws_server_bootstrap,
263+
set_default_aws_server_bootstrap!, tlsoptions, close_default_aws_event_loop_group!,
264+
close_default_aws_host_resolver!, close_default_aws_client_bootstrap!, close_default_aws_server_bootstrap!
188265

189266
const LIB_AWS_IO_MAX_THREADS = Ref{Int}(0)
190267

0 commit comments

Comments
 (0)