Rozwiązanie poprawne korzystające z metody Przekazywania (Dziedziczenia) Sekcji Krytycznej

Problem obecny w niepoprawnym rozwiązaniu, może być naprawiony także w inny sposób. Można do tego wykorzystać technikę nazywaną Przekazywanie (Dziedziczenie) Sekcji Krytycznej. W tym przypadku będzie to polegało na zagwarantowaniu, że po procesie budzącym będzie się wykonywał proces budzony (typ samym zapewniamy że przed procesem budzonym nie będzie się wykonywał żeaden proces zwalniający szerokość pasma).

var
  szerokosc_niezarezerwowana: integer := N;
  szerokosc_potrzebna: integer := -1;
  rozpatrywanie_rezerwacji_pojedynczo: binary semaphore := 1;
  czekajacy_uzytkownik: binary semaphore := 0;
  ochrona: binary semaphore := 1;

procedure rezerwacja_pasma(szerokosc_dla_uzytkownika: integer)
begin
  P(rozpatrywanie_rezerwacji_pojedynczo);
  P(ochrona);
  if (szerokosc_dla_uzytkownika<szerokosc_niezarezerwowana) then
    begin
      szerokosc_potrzebna := szerokosc_dla_uzytkownika;
      V(ochrona);
      P(czekajacy_uzytkownik);
      {korzystanie z przekazanej ochrona}
      szerokosc_potrzebna:=-1;
    end;
  szerokosc_niezarezerwowana := szerokosc_niezarezerwowana - szerokosc_dla_uzytkownika;
  V(ochrona);
  V(rozpatrywanie_rezerwacji_pojedynczo); 
end;

procedure zwalnianie_pasma(szerokosc_dla_uzytkownika: integer)
begin
  P(ochrona);
  szerokosc_niezarezerwowana := szerokosc_niezarezerwowana + szerokosc_dla_uzytkownika;
  if (szerokosc_potrzebna<>-1 and szerokosc_niezarezerwowana>=szerokosc_potrzebna) then
    V(czekajacy_uzytkownik); {przekazywanie ochrony}
  else
    V(ochrona); 
end;