walkor vor 3 Jahren
Ursprung
Commit
cddfe86ec2
1 geänderte Dateien mit 22 neuen und 5 gelöschten Zeilen
  1. 22 5
      src/Events/Select.php

+ 22 - 5
src/Events/Select.php

@@ -14,6 +14,9 @@
 
 namespace Workerman\Events;
 
+use Throwable;
+use Workerman\Worker;
+
 /**
  * select eventloop
  */
@@ -259,6 +262,7 @@ class Select implements EventInterface
      */
     protected function tick()
     {
+        $tasks_to_insert = [];
         while (!$this->_scheduler->isEmpty()) {
             $scheduler_data = $this->_scheduler->top();
             $timer_id = $scheduler_data['data'];
@@ -276,13 +280,27 @@ class Select implements EventInterface
                 $task_data = $this->_eventTimer[$timer_id];
                 if (isset($task_data[2])) {
                     $next_run_time = $time_now + $task_data[2];
-                    $this->_scheduler->insert($timer_id, -$next_run_time);
+                    $tasks_to_insert[] = [$timer_id, -$next_run_time];
                 } else {
                     unset($this->_eventTimer[$timer_id]);
                 }
-                $task_data[0]($task_data[1]);
-                continue;
+                try {
+                    $task_data[0]($task_data[1]);
+                } catch (Throwable $e) {
+                    Worker::stopAll(250, $e);
+                }
+            } else {
+                break;
             }
+        }
+        foreach ($tasks_to_insert as $item) {
+            $this->_scheduler->insert($item[0], $item[1]);
+        }
+        if (!$this->_scheduler->isEmpty()) {
+            $scheduler_data = $this->_scheduler->top();
+            $next_run_time = -$scheduler_data['priority'];
+            $time_now = \microtime(true);
+            $this->_selectTimeout = \max((int)(($next_run_time - $time_now) * 1000000), 0);
             return;
         }
         $this->_selectTimeout = 100000000;
@@ -317,12 +335,11 @@ class Select implements EventInterface
                 // Waiting read/write/signal/timeout events.
                 try {
                     @stream_select($read, $write, $except, 0, $this->_selectTimeout);
-                } catch (\Throwable $e) {
+                } catch (Throwable $e) {
                 }
 
             } else {
                 $this->_selectTimeout >= 1 && usleep($this->_selectTimeout);
-                $ret = false;
             }
 
             if (!$this->_scheduler->isEmpty()) {