Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- impl<'a> LockSet<'a> {
- // ANCHOR: lock_set
- /// Проверяет, что процесс `src` имеет право модифицировать целевой процесс,
- /// заданный своим идентификатором `dst_pid`.
- /// Целевой процесс может совпадать с `src`.
- ///
- /// Модифицировать можно:
- /// - Либо самого себя, задавая [`Pid::Current`] или явно собственный идентификатор [`Pid::Id`].
- /// - Либо свой непосредственно дочерний процесс, задавая его идентификатор.
- ///
- /// Возвращает:
- /// - Исходную блокировку на `src`, если `dst_pid` задаёт тот же процесс.
- /// - Блокировку на процесс `dst`, если `process_set == ProcessSet::Dst`.
- /// - Блокировки на процессы `src` и `dst`, если это разные процессы.
- ///
- /// Захватывает блокировки в правильном порядке для избежания
- /// [взаимоблокировки](https://en.wikipedia.org/wiki/Deadlock).
- fn new(
- src: SpinlockGuard<Process>,
- dst_pid: usize,
- process_set: ProcessSet,
- ) -> Result<LockSet<'_>> {
- let dst = Pid::from_usize(dst_pid)?;
- match process_set {
- ProcessSet::Dst => {
- if src.pid().into_usize() == dst_pid {
- return Ok(LockSet::Dst { dst: src });
- }
- if dst == Pid::Current {
- return Ok(LockSet::Dst { dst: src });
- }
- let dst_process = Table::get(dst)?;
- if dst_process.parent() != Some(src.pid()) && dst != src.pid() && dst != Pid::Current {
- return Err(PermissionDenied);
- }
- return Ok(LockSet::Dst { dst: dst_process });
- },
- ProcessSet::SrcDst => {
- if src.pid().into_usize() == dst_pid {
- return Ok(LockSet::Same { src_dst: src });
- }
- if dst == Pid::Current {
- return Ok(LockSet::Same { src_dst: src });
- }
- let dst_process = Table::get(dst)?;
- if dst_process.parent() != Some(src.pid()) && dst != src.pid() && dst != Pid::Current {
- return Err(PermissionDenied);
- }
- return Ok(LockSet::Different { dst: dst_process, src: src });
- },
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment