X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/a4175b2e216a20b86cc872dea8a08005c60617a5..2546a41ad36fdc9ef6471cb35a1d56930ae1b527:/handle.cc?ds=sidebyside diff --git a/handle.cc b/handle.cc index e998b3c..d048ead 100644 --- a/handle.cc +++ b/handle.cc @@ -1,112 +1,108 @@ #include "handle.h" -#include -#include "tprintf.h" +#include "threaded_log.h" #include "lock.h" +#include -handle_mgr mgr; +using std::map; -handle::handle(std::string m) -{ - h = mgr.get_handle(m); -} +class hinfo { +public: + rpcc *cl = nullptr; + int refcnt = 0; + 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; -rpcc * -handle::safebind() -{ +handle::handle(const string & m) : h(mgr.acquire_handle(m)) {} + +rpcc * handle::safebind() { if (!h) - return NULL; - lock ml(h->cl_mutex); + return nullptr; + lock ml(h->client_mutex); if (h->del) - return NULL; + return nullptr; if (h->cl) return h->cl; - sockaddr_in dstsock; - make_sockaddr(h->m.c_str(), &dstsock); - rpcc *cl = new rpcc(dstsock); - tprintf("handler_mgr::get_handle trying to bind...%s\n", h->m.c_str()); - int ret; - // Starting with lab 6, our 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. + rpcc *cl = new rpcc(h->m); + LOG("handler_mgr::acquire_handle 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. // - // Note: with RPC_LOSSY=5, your lab would failed to pass the tests of - // lab 6 and lab 7 because the rpc layer may delay your RPC request, - // and cause a time out failure. Please make sure RPC_LOSSY is set to 0. - ret = cl->bind(rpcc::to(1000)); + // With RPC_LOSSY=5, tests may fail due to delays and time outs. + int ret = cl->bind(rpcc::to(1000)); if (ret < 0) { - tprintf("handle_mgr::get_handle bind failure! %s %d\n", h->m.c_str(), ret); + LOG("handle_mgr::acquire_handle bind failure! " << h->m << " " << ret); delete cl; h->del = true; } else { - tprintf("handle_mgr::get_handle bind succeeded %s\n", h->m.c_str()); + LOG("handle_mgr::acquire_handle bind succeeded " << h->m); h->cl = cl; } return h->cl; } -handle::~handle() -{ - if (h) mgr.done_handle(h); -} - -handle_mgr::handle_mgr() -{ +handle::~handle() { + if (h) mgr.release_handle(h); } -struct hinfo * -handle_mgr::get_handle(std::string m) -{ - lock ml(handle_mutex); - struct hinfo *h = 0; +hinfo * handle_mgr::acquire_handle(string m) { + lock ml(mgr_mutex); + hinfo *h = nullptr; if (hmap.find(m) == hmap.end()) { - h = new hinfo; - h->cl = NULL; - h->del = false; - h->refcnt = 1; - h->m = m; + h = new hinfo(m); hmap[m] = h; } else if (!hmap[m]->del) { h = hmap[m]; - h->refcnt ++; } + h->refcnt++; return h; } -void -handle_mgr::done_handle(struct hinfo *h) -{ - lock ml(handle_mutex); - h->refcnt--; - if (h->refcnt == 0 && h->del) - delete_handle_wo(h->m); +void handle_mgr::release_handle(hinfo *h) { + lock ml(mgr_mutex); + if (--h->refcnt == 0 && h->del) + delete_handle(h->m, ml); } -void -handle_mgr::delete_handle(std::string m) -{ - lock ml(handle_mutex); - delete_handle_wo(m); +void handle_mgr::delete_handle(const string & m) { + lock ml(mgr_mutex); + delete_handle(m, ml); } -// Must be called with handle_mutex locked. -void -handle_mgr::delete_handle_wo(std::string m) -{ +void handle_mgr::delete_handle(const string & m, lock &) { if (hmap.find(m) == hmap.end()) { - tprintf("handle_mgr::delete_handle_wo: cl %s isn't in cl list\n", m.c_str()); - } else { - tprintf("handle_mgr::delete_handle_wo: cl %s refcnt %d\n", m.c_str(), - hmap[m]->refcnt); - struct 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; - } + LOG("handle_mgr::delete_handle: cl " << m << " isn't in cl list"); + return; } + LOG("handle_mgr::delete_handle: 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; +} + +void invalidate_handle(const string & m) { + mgr.delete_handle(m); }