Exercise 3: Starting a Second Disk Op While the First Is Still Pending — Possible Solution ==================================================================== THE TEST ------------------------------ driver.read_start(101) print(disk.pending) # {'pid': 101, 'remaining': 10} driver.read_start(102) # a SECOND start_op() before the first ever finishes print(disk.pending) RESULT ------------------------------ process 101 starts a real disk operation: pending = {'pid': 101, 'remaining': 10} process 102 starts ANOTHER operation before the first ever finishes: pending = {'pid': 102, 'remaining': 10} The second call completely replaces disk.pending -- process 101's own entry is simply gone. No exception, no warning, nothing returned to indicate anything went wrong. WHY THIS HAPPENS ------------------------------ SimulatedDisk.start_op()'s own implementation is: def start_op(self, pid): self.pending = {'pid': pid, 'remaining': self.latency_ticks} This is a plain, unconditional assignment. There is no check anywhere for "is something already in progress" -- the second call simply overwrites self.pending with a brand-new dict, and Python's own garbage collector quietly reclaims the first dict once nothing references it anymore. Process 101's own operation isn't paused, queued, or rejected -- it's discarded entirely, as if it had never been requested at all. WHY THIS IS A DOCUMENTED LIMITATION, NOT A BUG THIS CHAPTER FIXES ------------------------------ Unlike Finding 4's own timer-handler bug (a real defect that broke a scenario the chapter's own mechanism was SUPPOSED to support correctly), this is a deliberate, honest scope boundary: SimulatedDisk was built to model ONE real device serving ONE operation at a time -- exactly matching a genuinely simple, single-channel disk. Concurrent request handling (a real request queue in front of the device, with operations dispatched one at a time as the device becomes free) is a GENUINELY DIFFERENT feature this simple driver never claimed to provide. Exercise 2's own working test demonstrates the correct usage pattern within these limits: never start a second operation until you've confirmed the first has completed. WHY THIS MATTERS FOR REAL DRIVER DESIGN ------------------------------ Real device drivers do typically maintain their own request queue in front of the underlying hardware precisely because multiple callers routinely want to use the same device concurrently, and hardware often genuinely can only process one operation (or a small, fixed number) at a time. This exercise makes concrete exactly what's missing here -- not a vague "it's simplified," but a specific, demonstrated failure mode (silent data loss of an in-flight operation) that any real queue- based driver would need to prevent. WHY THIS WORKS AS AN ANSWER ------------------------------ Directly inspecting disk.pending before and after the second start_op() call, rather than just observing whichever process happens to wake up later, makes the silent overwrite completely unambiguous -- there's no question of interpretation about what happened to process 101's own operation.