Variant f_hphpd_client_ctrl(CStrRef name, CStrRef op) { TRACE(5, "in f_hphpd_client_ctrl()\n"); DebuggerClient *client = NULL; std::string nameStr = name->toCPPString(); { DbgCltMap::const_accessor acc; if (!s_dbgCltMap.find(acc, nameStr)) { if (op.equal("getstate")) { return q_DebuggerClient$$STATE_INVALID; } else { raise_warning("client %s does not exist", name.data()); return uninit_null(); } } client = acc->second; } if (op.equal("interrupt")) { if (client->getClientState() < DebuggerClient::StateReadyForCommand) { raise_warning("client is not initialized"); return uninit_null(); } if (client->getClientState() != DebuggerClient::StateBusy) { raise_warning("client is not in a busy state"); return uninit_null(); } client->onSignal(SIGINT); return uninit_null(); } else if (op.equal("getstate")) { return client->getClientState(); } else if (op.equal("reset")) { // To handle the case when client is in a bad state, e.g. the grabbing // request encountered error and did not get chance to destruct or call // sweep. It will remove the client from the map. Here we'd rather take // the risk of leaking the client than the risk of chasing dangling // pointers. // // FIXME: it's unclear why it should be possible that we would not // get a chance to destruct or call sweep. return s_dbgCltMap.erase(nameStr); } raise_warning("unknown op %s", op.data()); return uninit_null(); }
// if the DebuggerClient with the same name is already in use, return null Variant f_hphpd_get_client(CStrRef name /* = null */) { if (name.empty()) { return null; } DebuggerClient *client = NULL; std::string nameStr = name->toCPPString(); { DbgCltMap::accessor acc; if (s_dbgCltMap.insert(acc, nameStr)) { client = new DebuggerClient(nameStr); acc->second = client; } else { client = acc->second; } if (!client->apiGrab()) { // already grabbed by another request return null; } } p_DebuggerClient clt(NEWOBJ(c_DebuggerClient)); clt->m_client = client; return clt; }