From: Peter Iannucci Date: Thu, 10 Oct 2013 18:03:31 +0000 (-0400) Subject: Removed explicit reference counting in handle.cc X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/commitdiff_plain/ded1e837093f09ec1234be29320525ad6ff200ae Removed explicit reference counting in handle.cc --- diff --git a/handle.cc b/handle.cc index 1cb5cc2..42d038f 100644 --- a/handle.cc +++ b/handle.cc @@ -2,103 +2,64 @@ class hinfo { public: - rpcc *cl = nullptr; - int refcnt = 0; + unique_ptr cl; bool del = false; string m; mutex client_mutex; hinfo(const string & m_) : m(m_) {} }; -class handle_mgr { - private: - mutex mgr_mutex; - map hmap; - void delete_handle(const string & m, lock & handle_mutex_lock); - public: - hinfo *acquire_handle(string m); - void release_handle(hinfo *h); - void delete_handle(const string & m); -}; - -static handle_mgr mgr; - -handle::handle(const string & m) : h(mgr.acquire_handle(m)) {} +static mutex mgr_mutex; +static map> hmap; -rpcc * handle::safebind() { - if (!h) - return nullptr; - lock ml(h->client_mutex); - if (h->del) - return nullptr; - if (h->cl) - return h->cl; - rpcc *cl = new rpcc(h->m); - LOG("trying to bind..." << h->m); - // The test script assumes that the failure can be detected by paxos and - // rsm layer within few seconds. We have to set the timeout with a small - // value to support the assumption. - // - // With RPC_LOSSY=5, tests may fail due to delays and time outs. - int ret = cl->bind(milliseconds(1000)); - if (ret < 0) { - LOG("bind failure! " << h->m << " " << ret); - delete cl; - h->del = true; - } else { - LOG("bind succeeded " << h->m); - h->cl = cl; - } - return h->cl; -} - -handle::~handle() { - if (h) mgr.release_handle(h); +static shared_ptr acquire_handle(string m) { + lock ml(mgr_mutex); + shared_ptr h = hmap[m]; + if (!h || h->del) + return (hmap[m] = make_shared(m)); + return h; } -hinfo * handle_mgr::acquire_handle(string m) { - lock ml(mgr_mutex); - hinfo *h = nullptr; +static void delete_handle(const string & m, lock &) { if (hmap.find(m) == hmap.end()) { - h = new hinfo(m); - hmap[m] = h; - h->refcnt++; - } else if (!hmap[m]->del) { - h = hmap[m]; - h->refcnt++; + LOG_NONMEMBER("cl " << m << " isn't in cl list"); + return; } - return h; -} -void handle_mgr::release_handle(hinfo *h) { - lock ml(mgr_mutex); - if (--h->refcnt == 0 && h->del) - delete_handle(h->m, ml); + hmap[m]->del = true; + LOG_NONMEMBER("cl " << m << " refcnt " << hmap[m].use_count()); + hmap.erase(m); } -void handle_mgr::delete_handle(const string & m) { +void invalidate_handle(const string & m) { lock ml(mgr_mutex); delete_handle(m, ml); } -void handle_mgr::delete_handle(const string & m, lock &) { - if (hmap.find(m) == hmap.end()) { - LOG("cl " << m << " isn't in cl list"); - return; - } - LOG("cl " << m << " refcnt " << hmap[m]->refcnt); - hinfo *h = hmap[m]; - if (h->refcnt == 0) { - if (h->cl) { - h->cl->cancel(); - delete h->cl; - } - hmap.erase(m); - delete h; - } else - h->del = true; -} +handle::handle(const string & m) : h(acquire_handle(m)) {} -void invalidate_handle(const string & m) { - mgr.delete_handle(m); +rpcc * handle::safebind() { + if (!h) + return nullptr; + lock ml(h->client_mutex); + if (h->del) + return nullptr; + if (!h->cl) { + unique_ptr cl(new rpcc(h->m)); + LOG("trying to bind..." << h->m); + // The test script assumes that the failure can be detected by paxos and + // rsm layer within few seconds. We have to set the timeout with a small + // value to support the assumption. + // + // With RPC_LOSSY=5, tests may fail due to delays and time outs. + int ret = cl->bind(milliseconds(1000)); + if (ret < 0) { + LOG("bind failure! " << h->m << " " << ret); + h->del = true; + } else { + LOG("bind succeeded " << h->m); + h->cl = move(cl); + } + } + return h->cl.get(); } diff --git a/handle.h b/handle.h index d4b6223..dc2edb7 100644 --- a/handle.h +++ b/handle.h @@ -30,10 +30,9 @@ class hinfo; class handle { private: - hinfo *h; + shared_ptr h; public: handle(const string & m); - ~handle(); /* safebind will try to bind with the rpc server on the first call. * Since bind may block, the caller probably should not hold a mutex * when calling safebind.