1 use core::fmt;
2 use core::marker::PhantomData;
3 
4 use {Poll, Future, Stream, Sink, StartSend};
5 
6 mod atomic_task;
7 pub use self::atomic_task::AtomicTask;
8 
9 mod core;
10 
11 #[cfg(feature = "use_std")]
12 mod std;
13 #[cfg(feature = "use_std")]
14 pub use self::std::*;
15 #[cfg(not(feature = "use_std"))]
16 pub use self::core::*;
17 
18 pub struct BorrowedTask<'a> {
19     id: usize,
20     unpark: BorrowedUnpark<'a>,
21     events: BorrowedEvents<'a>,
22     // Task-local storage
23     map: &'a LocalMap,
24 }
25 
fresh_task_id() -> usize26 fn fresh_task_id() -> usize {
27     use core::sync::atomic::{AtomicUsize, Ordering};
28     #[allow(deprecated)]
29     use core::sync::atomic::ATOMIC_USIZE_INIT;
30 
31     // TODO: this assert is a real bummer, need to figure out how to reuse
32     //       old IDs that are no longer in use.
33     //
34     // Note, though, that it is intended that these ids go away entirely
35     // eventually, see the comment on `is_current` below.
36     #[allow(deprecated)]
37     static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
38     let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
39     assert!(id < usize::max_value() / 2,
40             "too many previous tasks have been allocated");
41     id
42 }
43 
with<F: FnOnce(&BorrowedTask) -> R, R>(f: F) -> R44 fn with<F: FnOnce(&BorrowedTask) -> R, R>(f: F) -> R {
45     unsafe {
46         let task = get_ptr().expect("no Task is currently running");
47         assert!(!task.is_null(), "no Task is currently running");
48         f(&*(task as *const BorrowedTask))
49     }
50 }
51 
52 /// A handle to a "task", which represents a single lightweight "thread" of
53 /// execution driving a future to completion.
54 ///
55 /// In general, futures are composed into large units of work, which are then
56 /// spawned as tasks onto an *executor*. The executor is responsible for polling
57 /// the future as notifications arrive, until the future terminates.
58 ///
59 /// This is obtained by the `task::current` function.
60 ///
61 /// # FAQ
62 ///
63 /// ### Why does `Task` not implement `Eq` and `Hash`?
64 ///
65 /// A valid use case for `Task` to implement these two traits has not been
66 /// encountered.
67 ///
68 /// Usually, this question is asked by someone who wants to store a `Task`
69 /// instance in a `HashSet`. This seems like an obvious way to implement a
70 /// future aware, multi-handle structure; e.g. a multi-producer channel.
71 ///
72 /// In this case, the idea is that whenever a `start_send` is called on one of
73 /// the channel's send handles, if the channel is at capacity, the current task
74 /// is stored in a set. Then, when capacity is available, a task is removed from
75 /// the set and notified.
76 ///
77 /// The problem with this strategy is that multiple `Sender` handles can be used
78 /// on the same task. In this case, when the second handle is used and the task
79 /// is stored in a set, there already is an entry. Then, when the first
80 /// handle is dropped, this entry is cleared, resulting in a dead lock.
81 ///
82 /// See [here](https://github.com/rust-lang-nursery/futures-rs/issues/670) for
83 /// more discussion.
84 ///
85 #[derive(Clone)]
86 pub struct Task {
87     id: usize,
88     unpark: TaskUnpark,
89     events: UnparkEvents,
90 }
91 
92 trait AssertSend: Send {}
93 impl AssertSend for Task {}
94 
95 /// Returns a handle to the current task to call `notify` at a later date.
96 ///
97 /// The returned handle implements the `Send` and `'static` bounds and may also
98 /// be cheaply cloned. This is useful for squirreling away the handle into a
99 /// location which is then later signaled that a future can make progress.
100 ///
101 /// Implementations of the `Future` trait typically use this function if they
102 /// would otherwise perform a blocking operation. When something isn't ready
103 /// yet, this `current` function is called to acquire a handle to the current
104 /// task, and then the future arranges it such that when the blocking operation
105 /// otherwise finishes (perhaps in the background) it will `notify` the
106 /// returned handle.
107 ///
108 /// It's sometimes necessary to pass extra information to the task when
109 /// unparking it, so that the task knows something about *why* it was woken.
110 /// See the `FutureQueue` documentation for details on how to do this.
111 ///
112 /// # Panics
113 ///
114 /// This function will panic if a task is not currently being executed. That
115 /// is, this method can be dangerous to call outside of an implementation of
116 /// `poll`.
current() -> Task117 pub fn current() -> Task {
118     with(|borrowed| {
119         let unpark = borrowed.unpark.to_owned();
120         let events = borrowed.events.to_owned();
121 
122         Task {
123             id: borrowed.id,
124             unpark: unpark,
125             events: events,
126         }
127     })
128 }
129 
130 #[doc(hidden)]
131 #[deprecated(note = "renamed to `current`")]
park() -> Task132 pub fn park() -> Task {
133     current()
134 }
135 
136 impl Task {
137     /// Indicate that the task should attempt to poll its future in a timely
138     /// fashion.
139     ///
140     /// It's typically guaranteed that, after calling `notify`, `poll` will
141     /// be called at least once subsequently (unless the future has terminated).
142     /// If the task is currently polling its future when `notify` is called, it
143     /// must poll the future *again* afterwards, ensuring that all relevant
144     /// events are eventually observed by the future.
notify(&self)145     pub fn notify(&self) {
146         self.events.notify();
147         self.unpark.notify();
148     }
149 
150     #[doc(hidden)]
151     #[deprecated(note = "renamed to `notify`")]
unpark(&self)152     pub fn unpark(&self) {
153         self.notify()
154     }
155 
156     /// Returns `true` when called from within the context of the task.
157     ///
158     /// In other words, the task is currently running on the thread calling the
159     /// function. Note that this is currently, and has historically, been
160     /// implemented by tracking an `id` on every instance of `Spawn` created.
161     /// When a `Spawn` is being polled it stores in thread-local-storage the id
162     /// of the instance, and then `task::current` will return a `Task` that also
163     /// stores this id.
164     ///
165     /// The intention of this function was to answer questions like "if I
166     /// `notify` this task, is it equivalent to `task::current().notify()`?"
167     /// The answer "yes" may be able to avoid some extra work to block the
168     /// current task, such as sending a task along a channel or updating a
169     /// stored `Task` somewhere. An answer of "no" typically results in doing
170     /// the work anyway.
171     ///
172     /// Unfortunately this function has been somewhat buggy in the past and is
173     /// not intended to be supported in the future. By simply matching `id` the
174     /// intended question above isn't accurately taking into account, for
175     /// example, unpark events (now deprecated, but still a feature). Thus many
176     /// old users of this API weren't fully accounting for the question it was
177     /// intended they were asking.
178     ///
179     /// This API continues to be implemented but will in the future, e.g. in the
180     /// 0.1.x series of this crate, eventually return `false` unconditionally.
181     /// It is intended that this function will be removed in the next breaking
182     /// change of this crate. If you'd like to continue to be able to answer the
183     /// example question above, it's recommended you use the
184     /// `will_notify_current` method.
185     ///
186     /// If you've got questions about this though please let us know! We'd like
187     /// to learn about other use cases here that we did not consider.
188     ///
189     /// # Panics
190     ///
191     /// This function will panic if no current future is being polled.
192     #[deprecated(note = "intended to be removed, see docs for details")]
is_current(&self) -> bool193     pub fn is_current(&self) -> bool {
194         with(|current| current.id == self.id)
195     }
196 
197     /// This function is intended as a performance optimization for structures
198     /// which store a `Task` internally.
199     ///
200     /// The purpose of this function is to answer the question "if I `notify`
201     /// this task is it equivalent to `task::current().notify()`". An answer
202     /// "yes" may mean that you don't actually need to call `task::current()`
203     /// and store it, but rather you can simply leave a stored task in place. An
204     /// answer of "no" typically means that you need to call `task::current()`
205     /// and store it somewhere.
206     ///
207     /// As this is purely a performance optimization a valid implementation for
208     /// this function is to always return `false`. A best effort is done to
209     /// return `true` where possible, but false negatives may happen. Note that
210     /// this function will not return a false positive, however.
211     ///
212     /// # Panics
213     ///
214     /// This function will panic if no current future is being polled.
215     #[allow(deprecated)]
will_notify_current(&self) -> bool216     pub fn will_notify_current(&self) -> bool {
217         with(|current| {
218             self.unpark.will_notify(&current.unpark) &&
219                 self.events.will_notify(&current.events)
220         })
221     }
222 }
223 
224 impl fmt::Debug for Task {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result225     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226         f.debug_struct("Task")
227          .finish()
228     }
229 }
230 
231 /// Representation of a spawned future/stream.
232 ///
233 /// This object is returned by the `spawn` function in this module. This
234 /// represents a "fused task and future", storing all necessary pieces of a task
235 /// and owning the top-level future that's being driven as well.
236 ///
237 /// A `Spawn` can be poll'd for completion or execution of the current thread
238 /// can be blocked indefinitely until a notification arrives. This can be used
239 /// with either futures or streams, with different methods being available on
240 /// `Spawn` depending which is used.
241 pub struct Spawn<T: ?Sized> {
242     id: usize,
243     data: LocalMap,
244     obj: T,
245 }
246 
247 /// Spawns a future or stream, returning it and the new task responsible for
248 /// running it to completion.
249 ///
250 /// This function is the termination endpoint for running futures. This method
251 /// will conceptually allocate a new task to run the given object, which is
252 /// normally either a `Future` or `Stream`.
253 ///
254 /// This function is similar to the `thread::spawn` function but does not
255 /// attempt to run code in the background. The future will not make progress
256 /// until the methods on `Spawn` are called in turn.
spawn<T>(obj: T) -> Spawn<T>257 pub fn spawn<T>(obj: T) -> Spawn<T> {
258     Spawn {
259         id: fresh_task_id(),
260         obj: obj,
261         data: local_map(),
262     }
263 }
264 
265 impl<T: ?Sized> Spawn<T> {
266     /// Get a shared reference to the object the Spawn is wrapping.
get_ref(&self) -> &T267     pub fn get_ref(&self) -> &T {
268         &self.obj
269     }
270 
271     /// Get a mutable reference to the object the Spawn is wrapping.
get_mut(&mut self) -> &mut T272     pub fn get_mut(&mut self) -> &mut T {
273         &mut self.obj
274     }
275 
276     /// Consume the Spawn, returning its inner object
into_inner(self) -> T where T: Sized277     pub fn into_inner(self) -> T where T: Sized {
278         self.obj
279     }
280 
281     /// Calls the provided closure, scheduling notifications to be sent to the
282     /// `notify` argument.
poll_fn_notify<N, F, R>(&mut self, notify: &N, id: usize, f: F) -> R where F: FnOnce(&mut T) -> R, N: Clone + Into<NotifyHandle>,283     pub fn poll_fn_notify<N, F, R>(&mut self,
284                              notify: &N,
285                              id: usize,
286                              f: F) -> R
287         where F: FnOnce(&mut T) -> R,
288               N: Clone + Into<NotifyHandle>,
289     {
290         let mk = || notify.clone().into();
291         self.enter(BorrowedUnpark::new(&mk, id), f)
292     }
293 
294     /// Polls the internal future, scheduling notifications to be sent to the
295     /// `notify` argument.
296     ///
297     /// This method will poll the internal future, testing if it's completed
298     /// yet. The `notify` argument is used as a sink for notifications sent to
299     /// this future. That is, while the future is being polled, any call to
300     /// `task::current()` will return a handle that contains the `notify`
301     /// specified.
302     ///
303     /// If this function returns `NotReady`, then the `notify` should have been
304     /// scheduled to receive a notification when poll can be called again.
305     /// Otherwise if `Ready` or `Err` is returned, the `Spawn` task can be
306     /// safely destroyed.
307     ///
308     /// Note that `notify` itself is passed as a shared reference, and is itself
309     /// not required to be a `NotifyHandle`. The `Clone` and `Into` trait bounds
310     /// will be used to convert this `notify` to a `NotifyHandle` if necessary.
311     /// This construction can avoid an unnecessary atomic reference count bump
312     /// in some situations.
313     ///
314     /// ## Unsafety and `id`
315     ///
316     /// This function and all other `*_notify` functions on this type will treat
317     /// the `id` specified very carefully, explicitly calling functions like the
318     /// `notify` argument's `clone_id` and `drop_id` functions. It should be
319     /// safe to encode a pointer itself into the `id` specified, such as an
320     /// `Arc<N>` or a `Box<N>`. The `clone_id` and `drop_id` functions are then
321     /// intended to be sufficient for the memory management related to that
322     /// pointer.
poll_future_notify<N>(&mut self, notify: &N, id: usize) -> Poll<T::Item, T::Error> where N: Clone + Into<NotifyHandle>, T: Future,323     pub fn poll_future_notify<N>(&mut self,
324                                  notify: &N,
325                                  id: usize) -> Poll<T::Item, T::Error>
326         where N: Clone + Into<NotifyHandle>,
327               T: Future,
328     {
329         self.poll_fn_notify(notify, id, |f| f.poll())
330     }
331 
332     /// Like `poll_future_notify`, except polls the underlying stream.
poll_stream_notify<N>(&mut self, notify: &N, id: usize) -> Poll<Option<T::Item>, T::Error> where N: Clone + Into<NotifyHandle>, T: Stream,333     pub fn poll_stream_notify<N>(&mut self,
334                                  notify: &N,
335                                  id: usize)
336                                  -> Poll<Option<T::Item>, T::Error>
337         where N: Clone + Into<NotifyHandle>,
338               T: Stream,
339     {
340         self.poll_fn_notify(notify, id, |s| s.poll())
341     }
342 
343     /// Invokes the underlying `start_send` method with this task in place.
344     ///
345     /// If the underlying operation returns `NotReady` then the `notify` value
346     /// passed in will receive a notification when the operation is ready to be
347     /// attempted again.
start_send_notify<N>(&mut self, value: T::SinkItem, notify: &N, id: usize) -> StartSend<T::SinkItem, T::SinkError> where N: Clone + Into<NotifyHandle>, T: Sink,348     pub fn start_send_notify<N>(&mut self,
349                                 value: T::SinkItem,
350                                 notify: &N,
351                                 id: usize)
352                                -> StartSend<T::SinkItem, T::SinkError>
353         where N: Clone + Into<NotifyHandle>,
354               T: Sink,
355     {
356         self.poll_fn_notify(notify, id, |s| s.start_send(value))
357     }
358 
359     /// Invokes the underlying `poll_complete` method with this task in place.
360     ///
361     /// If the underlying operation returns `NotReady` then the `notify` value
362     /// passed in will receive a notification when the operation is ready to be
363     /// attempted again.
poll_flush_notify<N>(&mut self, notify: &N, id: usize) -> Poll<(), T::SinkError> where N: Clone + Into<NotifyHandle>, T: Sink,364     pub fn poll_flush_notify<N>(&mut self,
365                                 notify: &N,
366                                 id: usize)
367                                 -> Poll<(), T::SinkError>
368         where N: Clone + Into<NotifyHandle>,
369               T: Sink,
370     {
371         self.poll_fn_notify(notify, id, |s| s.poll_complete())
372     }
373 
374     /// Invokes the underlying `close` method with this task in place.
375     ///
376     /// If the underlying operation returns `NotReady` then the `notify` value
377     /// passed in will receive a notification when the operation is ready to be
378     /// attempted again.
close_notify<N>(&mut self, notify: &N, id: usize) -> Poll<(), T::SinkError> where N: Clone + Into<NotifyHandle>, T: Sink,379     pub fn close_notify<N>(&mut self,
380                            notify: &N,
381                            id: usize)
382                            -> Poll<(), T::SinkError>
383         where N: Clone + Into<NotifyHandle>,
384               T: Sink,
385     {
386         self.poll_fn_notify(notify, id, |s| s.close())
387     }
388 
enter<F, R>(&mut self, unpark: BorrowedUnpark, f: F) -> R where F: FnOnce(&mut T) -> R389     fn enter<F, R>(&mut self, unpark: BorrowedUnpark, f: F) -> R
390         where F: FnOnce(&mut T) -> R
391     {
392         let borrowed = BorrowedTask {
393             id: self.id,
394             unpark: unpark,
395             events: BorrowedEvents::new(),
396             map: &self.data,
397         };
398         let obj = &mut self.obj;
399         set(&borrowed, || f(obj))
400     }
401 }
402 
403 impl<T: fmt::Debug + ?Sized> fmt::Debug for Spawn<T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result404     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405         f.debug_struct("Spawn")
406          .field("obj", &&self.obj)
407          .finish()
408     }
409 }
410 
411 /// A trait which represents a sink of notifications that a future is ready to
412 /// make progress.
413 ///
414 /// This trait is provided as an argument to the `Spawn::*_notify` family of
415 /// functions. It's transitively used as part of the `Task::notify` method to
416 /// internally deliver notifications of readiness of a future to move forward.
417 ///
418 /// An instance of `Notify` has one primary method, `notify`, which is given a
419 /// contextual argument as to what's being notified. This contextual argument is
420 /// *also* provided to the `Spawn::*_notify` family of functions and can be used
421 /// to reuse an instance of `Notify` across many futures.
422 ///
423 /// Instances of `Notify` must be safe to share across threads, and the methods
424 /// be invoked concurrently. They must also live for the `'static` lifetime,
425 /// not containing any stack references.
426 pub trait Notify: Send + Sync {
427     /// Indicates that an associated future and/or task are ready to make
428     /// progress.
429     ///
430     /// Typically this means that the receiver of the notification should
431     /// arrange for the future to get poll'd in a prompt fashion.
432     ///
433     /// This method takes an `id` as an argument which was transitively passed
434     /// in from the original call to `Spawn::*_notify`. This id can be used to
435     /// disambiguate which precise future became ready for polling.
436     ///
437     /// # Panics
438     ///
439     /// Since `unpark` may be invoked from arbitrary contexts, it should
440     /// endeavor not to panic and to do as little work as possible. However, it
441     /// is not guaranteed not to panic, and callers should be wary. If a panic
442     /// occurs, that panic may or may not be propagated to the end-user of the
443     /// future that you'd otherwise wake up.
notify(&self, id: usize)444     fn notify(&self, id: usize);
445 
446     /// This function is called whenever a new copy of `id` is needed.
447     ///
448     /// This is called in one of two situations:
449     ///
450     /// * A `Task` is being created through `task::current` while a future is
451     ///   being polled. In that case the instance of `Notify` passed in to one
452     ///   of the `poll_*` functions is called with the `id` passed into the same
453     ///   `poll_*` function.
454     /// * A `Task` is itself being cloned. Each `Task` contains its own id and a
455     ///   handle to the `Notify` behind it, and the task's `Notify` is used to
456     ///   clone the internal `id` to assign to the new task.
457     ///
458     /// The `id` returned here will be stored in the `Task`-to-be and used later
459     /// to pass to `notify` when the `Task::notify` function is called on that
460     /// `Task`.
461     ///
462     /// Note that typically this is just the identity function, passing through
463     /// the identifier. For more unsafe situations, however, if `id` is itself a
464     /// pointer of some kind this can be used as a hook to "clone" the pointer,
465     /// depending on what that means for the specified pointer.
clone_id(&self, id: usize) -> usize466     fn clone_id(&self, id: usize) -> usize {
467         id
468     }
469 
470     /// All instances of `Task` store an `id` that they're going to internally
471     /// notify with, and this function is called when the `Task` is dropped.
472     ///
473     /// This function provides a hook for schemes which encode pointers in this
474     /// `id` argument to deallocate resources associated with the pointer. It's
475     /// guaranteed that after this function is called the `Task` containing this
476     /// `id` will no longer use the `id`.
drop_id(&self, id: usize)477     fn drop_id(&self, id: usize) {
478         drop(id);
479     }
480 }
481 
482 /// Sets the `NotifyHandle` of the current task for the duration of the provided
483 /// closure.
484 ///
485 /// This function takes a type that can be converted into a notify handle,
486 /// `notify` and `id`, and a closure `f`. The closure `f` will be executed such
487 /// that calls to `task::current()` will store a reference to the notify handle
488 /// provided, not the one previously in the environment.
489 ///
490 /// Note that calls to `task::current()` in the closure provided *will not* be
491 /// equivalent to `task::current()` before this method is called. The two tasks
492 /// returned will notify different handles, and the task handles pulled out
493 /// during the duration of this closure will not notify the previous task. It's
494 /// recommended that you call `task::current()` in some capacity before calling
495 /// this function to ensure that calls to `task::current()` inside of this
496 /// closure can transitively wake up the outer task.
497 ///
498 /// # Panics
499 ///
500 /// This function will panic if it is called outside the context of a future's
501 /// task. This is only valid to call once you've already entered a future via
502 /// `Spawn::poll_*` functions.
with_notify<F, T, R>(notify: &T, id: usize, f: F) -> R where F: FnOnce() -> R, T: Clone + Into<NotifyHandle>,503 pub fn with_notify<F, T, R>(notify: &T, id: usize, f: F) -> R
504     where F: FnOnce() -> R,
505           T: Clone + Into<NotifyHandle>,
506 {
507     with(|task| {
508         let mk = || notify.clone().into();
509         let new_task = BorrowedTask {
510             id: task.id,
511             unpark: BorrowedUnpark::new(&mk, id),
512             events: task.events,
513             map: task.map,
514         };
515 
516         set(&new_task, f)
517     })
518 }
519 
520 /// An unsafe trait for implementing custom forms of memory management behind a
521 /// `Task`.
522 ///
523 /// The `futures` critically relies on "notification handles" to extract for
524 /// futures to contain and then later inform that they're ready to make
525 /// progress. These handles, however, must be cheap to create and cheap
526 /// to clone to ensure that this operation is efficient throughout the
527 /// execution of a program.
528 ///
529 /// Typically this sort of memory management is done in the standard library
530 /// with the `Arc` type. An `Arc` is relatively cheap to allocate an is
531 /// quite cheap to clone and pass around. Plus, it's 100% safe!
532 ///
533 /// When working outside the standard library, however, you don't always have
534 /// and `Arc` type available to you. This trait, `UnsafeNotify`, is intended
535 /// to be the "unsafe version" of the `Notify` trait. This trait encodes the
536 /// memory management operations of a `Task`'s notification handle, allowing
537 /// custom implementations for the memory management of a notification handle.
538 ///
539 /// Put another way, the core notification type in this library,
540 /// `NotifyHandle`, simply internally contains an instance of
541 /// `*mut UnsafeNotify`. This "unsafe trait object" is then used exclusively
542 /// to operate with, dynamically dispatching calls to clone, drop, and notify.
543 /// Critically though as a raw pointer it doesn't require a particular form
544 /// of memory management, allowing external implementations.
545 ///
546 /// A default implementation of the `UnsafeNotify` trait is provided for the
547 /// `Arc` type in the standard library. If the `use_std` feature of this crate
548 /// is not available however, you'll be required to implement your own
549 /// instance of this trait to pass it into `NotifyHandle::new`.
550 ///
551 /// # Unsafety
552 ///
553 /// This trait is manually encoding the memory management of the underlying
554 /// handle, and as a result is quite unsafe to implement! Implementors of
555 /// this trait must guarantee:
556 ///
557 /// * Calls to `clone_raw` produce uniquely owned handles. It should be safe
558 ///   to drop the current handle and have the returned handle still be valid.
559 /// * Calls to `drop_raw` work with `self` as a raw pointer, deallocating
560 ///   resources associated with it. This is a pretty unsafe operation as it's
561 ///   invalidating the `self` pointer, so extreme care needs to be taken.
562 ///
563 /// In general it's recommended to review the trait documentation as well as
564 /// the implementation for `Arc` in this crate. When in doubt ping the
565 /// `futures` authors to clarify an unsafety question here.
566 pub unsafe trait UnsafeNotify: Notify {
567     /// Creates a new `NotifyHandle` from this instance of `UnsafeNotify`.
568     ///
569     /// This function will create a new uniquely owned handle that under the
570     /// hood references the same notification instance. In other words calls
571     /// to `notify` on the returned handle should be equivalent to calls to
572     /// `notify` on this handle.
573     ///
574     /// # Unsafety
575     ///
576     /// This trait is unsafe to implement, as are all these methods. This
577     /// method is also unsafe to call as it's asserting the `UnsafeNotify`
578     /// value is in a consistent state. In general it's recommended to
579     /// review the trait documentation as well as the implementation for `Arc`
580     /// in this crate. When in doubt ping the `futures` authors to clarify
581     /// an unsafety question here.
clone_raw(&self) -> NotifyHandle582     unsafe fn clone_raw(&self) -> NotifyHandle;
583 
584     /// Drops this instance of `UnsafeNotify`, deallocating resources
585     /// associated with it.
586     ///
587     /// This method is intended to have a signature such as:
588     ///
589     /// ```ignore
590     /// fn drop_raw(self: *mut Self);
591     /// ```
592     ///
593     /// Unfortunately in Rust today that signature is not object safe.
594     /// Nevertheless it's recommended to implement this function *as if* that
595     /// were its signature. As such it is not safe to call on an invalid
596     /// pointer, nor is the validity of the pointer guaranteed after this
597     /// function returns.
598     ///
599     /// # Unsafety
600     ///
601     /// This trait is unsafe to implement, as are all these methods. This
602     /// method is also unsafe to call as it's asserting the `UnsafeNotify`
603     /// value is in a consistent state. In general it's recommended to
604     /// review the trait documentation as well as the implementation for `Arc`
605     /// in this crate. When in doubt ping the `futures` authors to clarify
606     /// an unsafety question here.
drop_raw(&self)607     unsafe fn drop_raw(&self);
608 }
609 
610 /// A `NotifyHandle` is the core value through which notifications are routed
611 /// in the `futures` crate.
612 ///
613 /// All instances of `Task` will contain a `NotifyHandle` handle internally.
614 /// This handle itself contains a trait object pointing to an instance of the
615 /// `Notify` trait, allowing notifications to get routed through it.
616 ///
617 /// The `NotifyHandle` type internally does not codify any particular memory
618 /// management strategy. Internally it contains an instance of `*mut
619 /// UnsafeNotify`, and more details about that trait can be found on its own
620 /// documentation. Consequently, though, the one constructor of this type,
621 /// `NotifyHandle::new`, is `unsafe` to call. It is not recommended to call
622 /// this constructor directly.
623 ///
624 /// If you're working with the standard library then it's recommended to
625 /// work with the `Arc` type. If you have a struct, `T`, which implements the
626 /// `Notify` trait, then you can construct this with
627 /// `NotifyHandle::from(t: Arc<T>)`. The coercion to `UnsafeNotify` will
628 /// happen automatically and safely for you.
629 ///
630 /// When working externally from the standard library it's recommended to
631 /// provide a similar safe constructor for your custom type as opposed to
632 /// recommending an invocation of `NotifyHandle::new` directly.
633 pub struct NotifyHandle {
634     inner: *mut UnsafeNotify,
635 }
636 
637 unsafe impl Send for NotifyHandle {}
638 unsafe impl Sync for NotifyHandle {}
639 
640 impl NotifyHandle {
641     /// Constructs a new `NotifyHandle` directly.
642     ///
643     /// Note that most code will not need to call this. Implementers of the
644     /// `UnsafeNotify` trait will typically provide a wrapper that calls this
645     /// but you otherwise shouldn't call it directly.
646     ///
647     /// If you're working with the standard library then it's recommended to
648     /// use the `NotifyHandle::from` function instead which works with the safe
649     /// `Arc` type and the safe `Notify` trait.
650     #[inline]
new(inner: *mut UnsafeNotify) -> NotifyHandle651     pub unsafe fn new(inner: *mut UnsafeNotify) -> NotifyHandle {
652         NotifyHandle { inner: inner }
653     }
654 
655     /// Invokes the underlying instance of `Notify` with the provided `id`.
notify(&self, id: usize)656     pub fn notify(&self, id: usize) {
657         unsafe { (*self.inner).notify(id) }
658     }
659 
clone_id(&self, id: usize) -> usize660     fn clone_id(&self, id: usize) -> usize {
661         unsafe { (*self.inner).clone_id(id) }
662     }
663 
drop_id(&self, id: usize)664     fn drop_id(&self, id: usize) {
665         unsafe { (*self.inner).drop_id(id) }
666     }
667 }
668 
669 impl Clone for NotifyHandle {
670     #[inline]
clone(&self) -> Self671     fn clone(&self) -> Self {
672         unsafe {
673             (*self.inner).clone_raw()
674         }
675     }
676 }
677 
678 impl fmt::Debug for NotifyHandle {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result679     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
680         f.debug_struct("NotifyHandle")
681          .finish()
682     }
683 }
684 
685 impl Drop for NotifyHandle {
drop(&mut self)686     fn drop(&mut self) {
687         unsafe {
688             (*self.inner).drop_raw()
689         }
690     }
691 }
692 
693 /// Marker for a `T` that is behind &'static.
694 struct StaticRef<T>(PhantomData<T>);
695 
696 impl<T: Notify> Notify for StaticRef<T> {
notify(&self, id: usize)697     fn notify(&self, id: usize) {
698         let me = unsafe { &*(self as *const _ as *const T) };
699         me.notify(id);
700     }
701 
clone_id(&self, id: usize) -> usize702     fn clone_id(&self, id: usize) -> usize {
703         let me = unsafe { &*(self as *const _ as *const T) };
704         me.clone_id(id)
705     }
706 
drop_id(&self, id: usize)707     fn drop_id(&self, id: usize) {
708         let me = unsafe { &*(self as *const _ as *const T) };
709         me.drop_id(id);
710     }
711 }
712 
713 unsafe impl<T: Notify + 'static> UnsafeNotify for StaticRef<T> {
clone_raw(&self) -> NotifyHandle714     unsafe fn clone_raw(&self) -> NotifyHandle {
715         NotifyHandle::new(self as *const _ as *mut StaticRef<T>)
716     }
717 
drop_raw(&self)718     unsafe fn drop_raw(&self) {}
719 }
720 
721 impl<T: Notify> From<&'static T> for NotifyHandle {
from(src : &'static T) -> NotifyHandle722     fn from(src : &'static T) -> NotifyHandle {
723         unsafe { NotifyHandle::new(src as *const _ as *mut StaticRef<T>) }
724     }
725 }
726 
727 #[cfg(feature = "nightly")]
728 mod nightly {
729     use super::NotifyHandle;
730     use core::marker::Unpin;
731 
732     impl Unpin for NotifyHandle {}
733 }
734