X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/dfe8486473094c0769fd1922329c3f0dfd8f43c0..6b5e09540e9392a7015fae1ad3b01b0973600ff2:/handle.cc diff --git a/handle.cc b/handle.cc index ff38a56..79b3b4c 100644 --- a/handle.cc +++ b/handle.cc @@ -1,110 +1,70 @@ #include "handle.h" -#include -#include "tprintf.h" -#include "lock.h" -handle_mgr mgr; +class hinfo { +public: + unique_ptr client; + bool valid = true; + string destination; + mutex client_mutex; + hinfo(const string & destination_) : destination(destination_) {} +}; -handle::handle(std::string m) -{ - h = mgr.get_handle(m); +static mutex mgr_mutex; +static map> hmap; + +handle::handle(const string & destination) { + lock ml(mgr_mutex); + h = hmap[destination]; + if (!h || !h->valid) + h = (hmap[destination] = make_shared(destination)); } -rpcc * -handle::safebind() -{ +rpcc * handle::safebind() { if (!h) - return NULL; - lock ml(h->cl_mutex); - if (h->del) - return NULL; - 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; - // 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. - ret = cl->bind(rpcc::to(1000)); - if (ret < 0) { - tprintf("handle_mgr::get_handle bind failure! %s %d\n", h->m.c_str(), ret); - delete cl; - h->del = true; - } else { - tprintf("handle_mgr::get_handle bind succeeded %s\n", h->m.c_str()); - h->cl = cl; + return nullptr; + lock cl(h->client_mutex); + if (!h->valid) + return nullptr; + if (!h->client) { + unique_ptr client(new rpcc(h->destination)); + LOG("trying to bind..." << h->destination); + // 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 = client->bind(milliseconds(1000)); + if (ret < 0) { + LOG("bind failure! " << h->destination << " " << ret); + h->valid = false; + } else { + LOG("bind succeeded " << h->destination); + h->client = move(client); + } } - return h->cl; + return h->client.get(); } -handle::~handle() -{ - if (h) mgr.done_handle(h); -} +void handle::invalidate() { + { + lock cl(h->client_mutex); + h->valid = false; -handle_mgr::handle_mgr() -{ -} - -struct hinfo * -handle_mgr::get_handle(std::string m) -{ - lock ml(handle_mutex); - struct hinfo *h = 0; - if (hmap.find(m) == hmap.end()) { - h = new hinfo; - h->cl = NULL; - h->del = false; - h->refcnt = 1; - h->m = m; - hmap[m] = h; - } else if (!hmap[m]->del) { - h = hmap[m]; - h->refcnt ++; + LOG_NONMEMBER("cl " << h->destination << " refcnt " << h.use_count()); } - return h; + lock ml(mgr_mutex); + hmap.erase(h->destination); + h = nullptr; } -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::delete_handle(std::string m) -{ - lock ml(handle_mutex); - delete_handle_wo(m); -} - -// Must be called with handle_mutex locked. -void -handle_mgr::delete_handle_wo(std::string m) -{ +void invalidate_handle(const string & m) { + lock ml(mgr_mutex); 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_NONMEMBER("cl " << m << " isn't in cl list"); + return; } + + hmap[m]->valid = false; + LOG_NONMEMBER("cl " << m << " refcnt " << hmap[m].use_count()); + hmap.erase(m); }