public function multiCurlPoll()
 {
     $curl_mh = $this->curl_mh;
     do {
         $mrc = curl_multi_exec($curl_mh, $still_running);
         if ($mrc == CURLM_OK) {
             $info = curl_multi_info_read($curl_mh);
             if ($info && isset($this->curl_cb[(int) $info['handle']])) {
                 $as = $this->curl_cb[(int) $info['handle']];
                 $curl = $info['handle'];
                 unset($this->curl_cb[(int) $curl]);
                 $as->_futoin_response = curl_multi_getcontent($curl);
                 $as->success($curl, $info);
                 curl_multi_remove_handle($this->curl_mh, $curl);
             }
         }
     } while ($mrc === CURLM_CALL_MULTI_PERFORM);
     if ($this->curl_event !== null) {
         \FutoIn\RI\AsyncTool::cancelCall($this->curl_event);
         $this->curl_event = null;
     }
     if ($this->curl_cb) {
         $this->curl_event = \FutoIn\RI\AsyncTool::callLater([$this, "multiCurlSelect"]);
     }
 }
 public function setTimeout($timeout_ms)
 {
     if ($this->_limit_event) {
         \FutoIn\RI\AsyncTool::cancelCall($this->_limit_event);
     }
     $this->_limit_event = \FutoIn\RI\AsyncTool::callLater(function () {
         \FutoIn\RI\AsyncTool::cancelCall($this->_limit_event);
         $this->_limit_event = null;
         // Skip own sanity checks for top-of-stack
         $this->root->_handle_error(\FutoIn\Error::Timeout);
     }, $timeout_ms);
 }