Skip to content

Commit 8bd5628

Browse files
committed
refactors and comments
1 parent ad677f6 commit 8bd5628

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

src/async_/resolver.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ struct Resolution<'a> {
144144
// Pool used for allocating `Vec<ngx_addr_t>` contents in `Res`. Read by
145145
// the callback handler.
146146
pool: &'a Pool,
147-
// Pointer to the ngx_resolver_ctx_t.
147+
// Owned pointer to the ngx_resolver_ctx_t.
148148
ctx: Option<ResolverCtx>,
149149
}
150150

@@ -184,20 +184,33 @@ impl<'a> Resolution<'a> {
184184
impl<'a> core::future::Future for Resolution<'a> {
185185
type Output = Result<Vec<ngx_addr_t, Pool>, Error>;
186186

187-
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
188-
let mut this = self.as_mut();
189-
187+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
188+
// Resolution is Unpin, so we can use it as just a &mut Resolution
189+
let this: &mut Resolution = self.get_mut();
190+
// First time a Resolution is polled, start resolution.
190191
if this.waker.is_none() && this.complete.is_none() {
191-
let addr = core::ptr::from_mut(unsafe { Pin::into_inner_unchecked(this.as_mut()) });
192-
193-
if let Some(ctx) = &mut this.ctx {
194-
// Start name resolution using the ctx. If the name is in the dns
195-
// cache, the handler may get called from this stack. Otherwise, it
196-
// will be called later by nginx when it gets a dns response or a
197-
// timeout.
198-
ctx.data = addr.cast();
199-
ctx.resolve()?;
200-
}
192+
// Because Resolution is pinned, the *mut pointer from &mut
193+
// Resolution can be safely used to reconstruct a &mut Resolution
194+
// in the handler anytime until the Future is Ready (which is
195+
// always preceeded by use of this addr in the handler) or
196+
// Resolution is dropped, which will drop the ResolverCtx as well,
197+
// cancelling any resolution for which the handler has not yet
198+
// been called.
199+
let addr = core::ptr::from_mut(this);
200+
201+
// Start name resolution using the ctx. If the name is in the dns
202+
// cache, the handler may get called from this stack. Otherwise, it
203+
// will be called later by nginx when it gets a dns response or a
204+
// timeout.
205+
let ctx = this
206+
.ctx
207+
.as_mut()
208+
.expect("ctx is Some between Resolution construction and handler");
209+
ctx.data = addr.cast();
210+
// Does calling the handler inside this call cause UB? We haven't
211+
// told rustc that know we have passed &mut Self to the handler by
212+
// way of the ctx.
213+
ctx.resolve()?;
201214
}
202215

203216
// The handler populates this.complete, and we consume it here:
@@ -206,9 +219,9 @@ impl<'a> core::future::Future for Resolution<'a> {
206219
None => {
207220
// If the handler has not yet fired, populate the waker field,
208221
// which the handler will consume:
209-
match &mut self.waker {
222+
match &mut this.waker {
210223
None => {
211-
self.waker = Some(cx.waker().clone());
224+
this.waker = Some(cx.waker().clone());
212225
}
213226
Some(w) => w.clone_from(cx.waker()),
214227
}
@@ -218,6 +231,7 @@ impl<'a> core::future::Future for Resolution<'a> {
218231
}
219232
}
220233

234+
/// An owned ngx_resolver_ctx_t.
221235
struct ResolverCtx(NonNull<ngx_resolver_ctx_t>);
222236

223237
impl core::ops::Deref for ResolverCtx {
@@ -268,8 +282,8 @@ impl ResolverCtx {
268282
}
269283

270284
/// Take the results in a ctx and make an owned copy as a
271-
/// Result<Vec<ngx_addr_t>, Error>, where the internals of the ngx_addr_t
272-
/// are allocated on the given Pool
285+
/// Result<Vec<ngx_addr_t, Pool>, Error>, where the Vec and the internals
286+
/// of the ngx_addr_t are allocated on the given Pool
273287
pub fn into_result(self, pool: &Pool) -> Result<Vec<ngx_addr_t, Pool>, Error> {
274288
if let Some(e) = NonZero::new(self.state) {
275289
return Err(Error::Resolver(

0 commit comments

Comments
 (0)