shaneharter / PHP-Daemon

Build production-ready Daemons using PHP 5.3+. Build fault-tolerant applications without the boilerplate.
Other
768 stars 166 forks source link

Daemon::__destruct() does not call teardown() on all workers and plugins #56

Open JaredBoone opened 10 years ago

JaredBoone commented 10 years ago

Bug: This foreach loop in Daemon::__destruct() does not behave as expected:

foreach($this->workers + $this->plugins as $object) {
    $this->{$object}->teardown();
    unset($this->{$object});
}

The '+' operator performs an array union using keys, not the values. In this case the array indices may conflict, causing some array values to be excluded. See the note here: http://php.net/manual/en/language.operators.array.php#86379.

Impact: This bug prevents the teardown() function from being called on the complete set of workers and plugins, for example on the Lock_File plugin object. As a result, the lock file may not be unlinked, so restart() fails after the auto_restart_interval with the message "Core_Lock_File::set Failed. Additional Lock Detected."

Solution 1:

foreach($this->workers as $object) {
    $this->{$object}->teardown();
    unset($this->{$object});
}
foreach($this->plugins as $object) {
    $this->{$object}->teardown();
    unset($this->{$object});
}

Solution 2:

foreach(array_unique(array_merge($this->workers,$this->plugins)) as $object){
    $this->{$object}->teardown();
    unset($this->{$object});
}