cmd_cls = $cmd_cls; $this->ch = $ch; $this->tlimit = time() + $cmd_cls->tout; } function ch_get() { return ($this->ch); } function dbg_get() { // NOTE: cmd_cls must be valid by definition if ($this->cmd_cls->cds == NULL) return -1; return $this->cmd_cls->cds->dbg_get(); } } class CDS_cmd_cls { var $cds; var $name; var $tout; function CDS_cmd_cls($name, $tout) { $this->cds = NULL; $this->name = $name; $this->tout = $tout; } function cds_set($cds) { $this->cds = $cds; } static function pre_create($cds, $url) { if ($cds->dbg_get() > 2) { printf("CURL: curl_init\n"); } if (($ch = curl_init()) == FALSE) return FALSE; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FORBID_REUSE, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: close')); return ($ch); } function create($cds, $ch) { if ($cds->dbg > 2) { printf("CDS_cmd_cls::create - begin\n"); printf("CURL: curl_multi_add_handle\n"); } if (($ret = curl_multi_add_handle($cds->mh, $ch)) != 0) { // INFO: $ret is a CURLM_XXX errors code return (FALSE); } if ($cds->dbg > 2) { printf("CDS_cmd_cls::create - end\n"); } return (TRUE); } function process($cmd, $ret) { fprintf(STDERR, "process MUST BE IMPLEMENTED"); exit(123); } function timeout($cmd) { fprintf(STDERR, "timeout MUST BE IMPLEMENTED"); exit(123); } function dbg_get() { return $this->cds->dbg; } } class Curl_de_sac { var $mh; var $cmd_cls; var $cmd; var $dbg; function Curl_de_sac($dbg=0) { if ($dbg > 2) { printf("CURL: curl_multi_init\n"); } $this->mh = curl_multi_init(); $this->cmd_cls = array(); $this->cmd = array(); $this->dbg = $dbg; } function dbg_set($dbg) { $this->dbg = $dbg; } function dbg_get() { return($this->dbg); } function cmd_cls_register($cmd_cls) { if (get_class($cmd_cls) != 'CDS_cmd_cls' && is_subclass_of($cmd_cls, 'CDS_cmd_cls') == FALSE) return FALSE; if (isset($this->cmd_cls[$cmd_cls->name])) return FALSE; $this->cmd_cls[$cmd_cls->name] = $cmd_cls; $cmd_cls->cds_set($this); return TRUE; } function cmd_cls_deregister($cmd_cls) { if (get_class($cmd_cls) != 'CDS_cmd_cls' && is_subclass_of($cmd_cls, 'CDS_cmd_cls') == FALSE) return FALSE; if (!isset($this->cmd_cls[$cmd_cls->name])) return FALSE; $this->cmd_cls[$cmd_cls->name]->cds_set(NULL); unset($this->cmd_cls[$cmd_cls->name]); return TRUE; } function cmd_cls_deregister_all() { foreach($this->cmd_cls as $cmd_cls) { $cmd_cls->cds_set(NULL); } $this->cmd_cls = array(); } function cleanup($key) { $cmd = $this->cmd[$key]; if ($this->dbg > 2) { printf("cleanup\n"); printf("CURL: curl_multi_remove_handle:\n"); print_r($cmd->ch_get()); printf("\n"); } // return 0 on SUCCESS or CURLM_XXX in other cases if (($ret = curl_multi_remove_handle($this->mh, $cmd->ch_get())) != 0) { fprintf(STDERR, "CURL: curl_multi_remove_handle FAILED (%d)\n", $ret); } if ($this->dbg > 2) { printf("CURL: curl_close\n"); } curl_close($cmd->ch_get()); unset($this->cmd[$key]); } function execute() { $args = func_get_args(); if ($this->dbg > 1) { printf("CDS_cmd_cls::execute ARGS:\n"); print_r($args); } do { if (($name = array_shift($args)) === NULL) break; array_unshift($args, $this); if (!isset($this->cmd_cls[$name])) break; $cmd_cls = $this->cmd_cls[$name]; if (($inst = call_user_func_array(array($cmd_cls, "create"), $args)) == FALSE) break; array_push($this->cmd, $inst); if ($this->dbg > 1) { printf("CDS_cmd_cls::process - execute push cmd\n"); } if (($this->dbg & 1) == 1) { print_r($this); } return TRUE; } while (FALSE); return FALSE; } function process($curtime=0) { if ($curtime == 0) { $curtime = time(); } if ($this->dbg > 1) { printf("CDS_cmd_cls::process - begin\n"); } $running = NULL; if ($this->dbg > 2) { printf("CURL: curl_multi_exec\n"); } $ret = curl_multi_exec($this->mh, $running); $msgs_in_queue = NULL; do { if ($this->dbg > 2) { printf("CURL: curl_multi_info_read\n"); } if ($ret = curl_multi_info_read ($this->mh, $msgs_in_queue)) { if ($this->dbg > 1) { printf("Info_read miq: %d\n", $msgs_in_queue); } if ($this->dbg > 2) { printf("CURL: curl_getinfo\n"); } $info = curl_getinfo($ret['handle']); if ($this->dbg > 1) { printf("Getinfo:\n"); print_r($info); } foreach($this->cmd as $key => $cmd) { if ($cmd->ch == $ret['handle']) { if ($cmd->cmd_cls->process($cmd, $ret) == TRUE) { $this->cleanup($key); } break; } } } } while ($msgs_in_queue > 0); foreach ($this->cmd as $key => $cmd) { if ($this->dbg > 2) { printf("Check tout, curr: %d tlimit %d\n", $curtime, $cmd->tlimit); } if ($curtime > $cmd->tlimit) { if ($this->dbg > 2) { printf("TIMEOUT REACHED!\n"); } $cmd->cmd_cls->timeout($cmd); $this->cleanup($key); } } if ($this->dbg > 1) { printf("CDS_cmd_cls::process - end (queue: %d)\n", $msgs_in_queue); } } }