Closed jmazanec15 closed 6 years ago
@jmazanec15 this appears to be along the lines of what we discussed.
Since it involves a change deep to the internals of process
,
let's all stop and think carefully about the impact of this,
and any potential corner cases.
What happens to the child if the parent isn't waiting? (And who should find out about it?) What happens to the parent in the child doesn't finish? (And who should find out about it?) What happens if two children finish at the same time?
Take a walk through the code line by line, and look for opportunities where an unexpected result -- like a null pointer -- could cause havoc in either the parent or the child.
In the case where the parent isn't waiting for the child, the child, on exit, would attempt to wakeup the parent off the grave_wait_list even though the parent is not there. This would lead to an Error message that the parent couldn't be found, but would still run because I did not put an exit statement there. I think if the child can't find it's parent on the grave_wait_list, it should just continue and assume the parent isn't waiting.
In the case where the child never returns, is that a program error? Because, if a child exits, and the parent called process_wait_child, then the exit function will wakeup the parent on the grave_wait_list before finishing.
I was trying to think of what would happen in the case when a parent has multiple children and I think there is a major problem here. Say a parent forks a couple child processes and calls wait on one of them. I believe a parent can only wait on 1 process at a time because when it does this, it will be set to blocking. In the code written in this PR, whatever child finishes first will wakeup the parent. This would lead to errors if the child process that finishes first is not the one the parent is waiting on. One solution to this could be to add both the parent process and the pid of the child process to the grave_wait_list and then when waking up the parent check that the pid child being waited on and the child exiting matchup as well.
I like that idea. I will try that.
I added a field called waiting_for_child_pid in the process struct. Then, when a process exits, it calls process_wakeup_parent to check if it needs to wakeup its parent. In process_wakeup_parent, it loops through the gave_watcher_list and if the current process's ppid is equal to a process in the grave_watcher_list and either waiting_for_child_pid is 0 or is equal to current's pid, it wakes up that process.
In response to #167, I modified process_wait_child to put the parent on a list called grave_watcher_list. Then, when a process exits, it calls process_wakeup_parent that loops through the grave_watcher_list and wakes up the correct parent.
I tested the program on the snake game and it works on the other branch.