| 1 | |
| 2 |
|
| 3 | |
| 4 |
|
| 5 | use kernel::{list::ListArc, prelude::*, seq_file::SeqFile, seq_print, sync::UniqueArc};
|
| 6 |
|
| 7 | use crate::{node::Node, thread::Thread, BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead};
|
| 8 |
|
| 9 | use core::mem::MaybeUninit;
|
| 10 |
|
| 11 | pub(crate) struct CritIncrWrapper {
|
| 12 | inner: UniqueArc<MaybeUninit<DTRWrap<NodeWrapper>>>,
|
| 13 | }
|
| 14 |
|
| 15 | impl CritIncrWrapper {
|
| 16 | pub(crate) fn new() -> Result<Self> {
|
| 17 | Ok(CritIncrWrapper {
|
| 18 | inner: UniqueArc::new_uninit(GFP_KERNEL)?,
|
| 19 | })
|
| 20 | }
|
| 21 |
|
| 22 | pub(super) fn init(self, node: DArc<Node>) -> DLArc<dyn DeliverToRead> {
|
| 23 | match self.inner.pin_init_with(DTRWrap::new(NodeWrapper { node })) {
|
| 24 | Ok(initialized) => ListArc::from(initialized) as DLArc<dyn DeliverToRead>,
|
| 25 | Err(err) => match err {},
|
| 26 | }
|
| 27 | }
|
| 28 | }
|
| 29 |
|
| 30 | struct NodeWrapper {
|
| 31 | node: DArc<Node>,
|
| 32 | }
|
| 33 |
|
| 34 | kernel::list::impl_list_arc_safe! {
|
| 35 | impl ListArcSafe<0> for NodeWrapper {
|
| 36 | untracked;
|
| 37 | }
|
| 38 | }
|
| 39 |
|
| 40 | impl DeliverToRead for NodeWrapper {
|
| 41 | fn do_work(
|
| 42 | self: DArc<Self>,
|
| 43 | _thread: &Thread,
|
| 44 | writer: &mut BinderReturnWriter<'_>,
|
| 45 | ) -> Result<bool> {
|
| 46 | let node = &self.node;
|
| 47 | let mut owner_inner = node.owner.inner.lock();
|
| 48 | let inner = node.inner.access_mut(&mut owner_inner);
|
| 49 |
|
| 50 | let ds = &mut inner.delivery_state;
|
| 51 |
|
| 52 | assert!(ds.has_pushed_wrapper);
|
| 53 | assert!(ds.has_strong_zero2one);
|
| 54 | ds.has_pushed_wrapper = false;
|
| 55 | ds.has_strong_zero2one = false;
|
| 56 |
|
| 57 | node.do_work_locked(writer, owner_inner)
|
| 58 | }
|
| 59 |
|
| 60 | fn cancel(self: DArc<Self>) {
|
| 61 | let _drop_outside_lock;
|
| 62 | let node = &self.node;
|
| 63 | let mut owner_inner = node.owner.inner.lock();
|
| 64 |
|
| 65 | |
| 66 | if owner_inner.is_dead {
|
| 67 | return;
|
| 68 | }
|
| 69 |
|
| 70 | |
| 71 | |
| 72 | let inner = node.inner.access_mut(&mut owner_inner);
|
| 73 |
|
| 74 | let ds = &mut inner.delivery_state;
|
| 75 | assert!(ds.has_pushed_wrapper);
|
| 76 | assert!(ds.has_strong_zero2one);
|
| 77 | ds.has_pushed_wrapper = false;
|
| 78 |
|
| 79 | |
| 80 | |
| 81 | ds.has_weak_zero2one = false;
|
| 82 |
|
| 83 | if !ds.has_pushed_node {
|
| 84 | if let Some(node2) = ListArc::try_from_arc_borrow(node.as_arc_borrow()) {
|
| 85 | ds.has_pushed_node = true;
|
| 86 | _drop_outside_lock = owner_inner.push_work(&node.owner, node2);
|
| 87 | } else {
|
| 88 | |
| 89 | ds.has_strong_zero2one = false;
|
| 90 | }
|
| 91 | }
|
| 92 | }
|
| 93 |
|
| 94 | fn should_sync_wakeup(&self) -> bool {
|
| 95 | false
|
| 96 | }
|
| 97 |
|
| 98 | #[inline(never)]
|
| 99 | fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
|
| 100 | seq_print!(
|
| 101 | m,
|
| 102 | "{}node work {}: u{:016x} c{:016x}\n",
|
| 103 | prefix,
|
| 104 | self.node.debug_id,
|
| 105 | self.node.ptr,
|
| 106 | self.node.cookie,
|
| 107 | );
|
| 108 | Ok(())
|
| 109 | }
|
| 110 | }
|