mMaxClient = $max_clients; $this->mUsingClients = []; $this->mFreeClients = []; $this->mSuspendCIDS = []; $this->mStop = false; } public function get($cid) { if(array_key_exists($cid,$this->mUsingClients)) { $this->mUsingClients[$cid]['ref_count'] += 1; return $this->mUsingClients[$cid]['client']; } if(!empty($this->mFreeClients)) { $client = $this->mFreeClients[0]; unset($this->mFreeClients[0]); $this->mFreeClients = array_values($this->mFreeClients); $this->mUsingClients[$cid] = ['client' => $client, 'ref_count' => 1,'ifTransacting' => false]; } elseif(count($this->mUsingClients) < $this->mMaxClient) { $client = $this->create_client(); $this->mUsingClients[$cid] = ['client' => $client, 'ref_count' => 1,'ifTransacting' => false]; } else { $this->mSuspendCIDS[] = Co::getCid(); Co::suspend(); $client = $this->mFreeClients[0]; unset($this->mFreeClients[0]); $this->mFreeClients = array_values($this->mFreeClients); $this->mUsingClients[$cid] = ['client' => $client, 'ref_count' => 1,'ifTransacting' => false]; } $count = count($this->mUsingClients); Log::record("get mUsingCount={$count}",Log::DEBUG); return $client; } public function find($cid) { if(array_key_exists($cid,$this->mUsingClients)) { return $this->mUsingClients[$cid]['client']; } else { Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG); throw new Exception("cannot find mysqli cid={$cid} client"); } } public function reset($cid,$client) { if(array_key_exists($cid,$this->mUsingClients)) { return $this->mUsingClients[$cid]['client'] = $client; } else { Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG); throw new Exception("cannot find mysqli cid={$cid} client"); } } public function transaction($cid) { if(array_key_exists($cid,$this->mUsingClients)) { return $this->mUsingClients[$cid]['ifTransacting']; } else { Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG); throw new Exception("cannot find mysqli cid={$cid} client"); } } public function commit($cid) { if(array_key_exists($cid,$this->mUsingClients)) { return $this->mUsingClients[$cid]['ifTransacting'] = false; } else { Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG); throw new Exception("cannot find mysqli cid={$cid} client"); } } public function rollback($cid) { if(array_key_exists($cid,$this->mUsingClients)) { return $this->mUsingClients[$cid]['ifTransacting'] = false; } else { Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG); throw new Exception("cannot find mysqli cid={$cid} client"); } } public function put($cid) { Log::record("CoRefPool put cid={$cid}",Log::DEBUG); if(array_key_exists($cid,$this->mUsingClients)) { $this->mUsingClients[$cid]['ref_count'] -= 1; $refcount = $this->mUsingClients[$cid]['ref_count']; if($refcount == 0) { $client = $this->mUsingClients[$cid]['client']; unset($this->mUsingClients[$cid]); $this->mFreeClients[] = $client; $suspend_cid = $this->getSuspend(); if($suspend_cid > 0) { Co::resume($suspend_cid); } Log::record("CoRefPool put cid={$cid} suspend_cid={$suspend_cid} refcount={$refcount}",Log::DEBUG); } else { Log::record("CoRefPool put cid={$cid} refcount={$refcount}",Log::DEBUG); } } else { Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG); throw new Exception("cannot find mysqli cid={$cid} client"); } } private function getSuspend() { if (empty($this->mSuspendCIDS)) { return 0; } else { $cid = $this->mSuspendCIDS[0]; unset($this->mSuspendCIDS[0]); $this->mSuspendCIDS = array_values($this->mSuspendCIDS); return $cid; } } public function stoped() { return $this->mStop; } public function stop() { $this->mStop = true; } abstract public function create_client(); }