-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
zhf
committed
Nov 22, 2012
1 parent
b01acd8
commit 9188d86
Showing
14 changed files
with
382 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
LAB=3 | ||
LAB=4 | ||
SOL=0 | ||
RPC=./rpc | ||
LAB2GE=$(shell expr $(LAB) \>\= 2) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "handle.h" | ||
#include <stdio.h> | ||
#include "tprintf.h" | ||
|
||
handle_mgr mgr; | ||
|
||
handle::handle(std::string m) | ||
{ | ||
h = mgr.get_handle(m); | ||
} | ||
|
||
rpcc * | ||
handle::safebind() | ||
{ | ||
if (!h) | ||
return NULL; | ||
ScopedLock 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; | ||
// handle class has to tolerate lossy network, since we may test | ||
// students' lab with RPC_LOSSY=5 from lab 1 to lab 5 | ||
ret = cl->bind(); | ||
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 h->cl; | ||
} | ||
|
||
handle::~handle() | ||
{ | ||
if (h) mgr.done_handle(h); | ||
} | ||
|
||
handle_mgr::handle_mgr() | ||
{ | ||
VERIFY (pthread_mutex_init(&handle_mutex, NULL) == 0); | ||
} | ||
|
||
struct hinfo * | ||
handle_mgr::get_handle(std::string m) | ||
{ | ||
ScopedLock 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; | ||
pthread_mutex_init(&h->cl_mutex, NULL); | ||
hmap[m] = h; | ||
} else if (!hmap[m]->del) { | ||
h = hmap[m]; | ||
h->refcnt ++; | ||
} | ||
return h; | ||
} | ||
|
||
void | ||
handle_mgr::done_handle(struct hinfo *h) | ||
{ | ||
ScopedLock ml(&handle_mutex); | ||
h->refcnt--; | ||
if (h->refcnt == 0 && h->del) | ||
delete_handle_wo(h->m); | ||
} | ||
|
||
void | ||
handle_mgr::delete_handle(std::string m) | ||
{ | ||
ScopedLock ml(&handle_mutex); | ||
delete_handle_wo(m); | ||
} | ||
|
||
// Must be called with handle_mutex locked. | ||
void | ||
handle_mgr::delete_handle_wo(std::string m) | ||
{ | ||
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; | ||
} | ||
pthread_mutex_destroy(&h->cl_mutex); | ||
hmap.erase(m); | ||
delete h; | ||
} else { | ||
h->del = true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// manage a cache of RPC connections. | ||
// assuming cid is a std::string holding the | ||
// host:port of the RPC server you want | ||
// to talk to: | ||
// | ||
// handle h(cid); | ||
// rpcc *cl = h.safebind(); | ||
// if(cl){ | ||
// ret = cl->call(...); | ||
// } else { | ||
// bind() failed | ||
// } | ||
// | ||
// if the calling program has not contacted | ||
// cid before, safebind() will create a new | ||
// connection, call bind(), and return | ||
// an rpcc*, or 0 if bind() failed. if the | ||
// program has previously contacted cid, | ||
// safebind() just returns the previously | ||
// created rpcc*. best not to hold any | ||
// mutexes while calling safebind(). | ||
|
||
#ifndef handle_h | ||
#define handle_h | ||
|
||
#include <string> | ||
#include <vector> | ||
#include "rpc.h" | ||
|
||
struct hinfo { | ||
rpcc *cl; | ||
int refcnt; | ||
bool del; | ||
std::string m; | ||
pthread_mutex_t cl_mutex; | ||
}; | ||
|
||
class handle { | ||
private: | ||
struct hinfo *h; | ||
public: | ||
handle(std::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. | ||
* | ||
* return: | ||
* if the first safebind succeeded, all later calls would return | ||
* a rpcc object; otherwise, all later calls would return NULL. | ||
* | ||
* Example: | ||
* handle h(dst); | ||
* XXX_protocol::status ret; | ||
* if (h.safebind()) { | ||
* ret = h.safebind()->call(...); | ||
* } | ||
* if (!h.safebind() || ret != XXX_protocol::OK) { | ||
* // handle failure | ||
* } | ||
*/ | ||
rpcc *safebind(); | ||
}; | ||
|
||
class handle_mgr { | ||
private: | ||
pthread_mutex_t handle_mutex; | ||
std::map<std::string, struct hinfo *> hmap; | ||
public: | ||
handle_mgr(); | ||
struct hinfo *get_handle(std::string m); | ||
void done_handle(struct hinfo *h); | ||
void delete_handle(std::string m); | ||
void delete_handle_wo(std::string m); | ||
}; | ||
|
||
extern class handle_mgr mgr; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// RPC stubs for clients to talk to lock_server, and cache the locks | ||
// see lock_client.cache.h for protocol details. | ||
|
||
#include "lock_client_cache.h" | ||
#include "rpc.h" | ||
#include <sstream> | ||
#include <iostream> | ||
#include <stdio.h> | ||
#include "tprintf.h" | ||
|
||
|
||
lock_client_cache::lock_client_cache(std::string xdst, | ||
class lock_release_user *_lu) | ||
: lock_client(xdst), lu(_lu) | ||
{ | ||
rpcs *rlsrpc = new rpcs(0); | ||
rlsrpc->reg(rlock_protocol::revoke, this, &lock_client_cache::revoke_handler); | ||
rlsrpc->reg(rlock_protocol::retry, this, &lock_client_cache::retry_handler); | ||
|
||
const char *hname; | ||
hname = "127.0.0.1"; | ||
std::ostringstream host; | ||
host << hname << ":" << rlsrpc->port(); | ||
id = host.str(); | ||
} | ||
|
||
lock_protocol::status | ||
lock_client_cache::acquire(lock_protocol::lockid_t lid) | ||
{ | ||
int ret = lock_protocol::OK; | ||
return lock_protocol::OK; | ||
} | ||
|
||
lock_protocol::status | ||
lock_client_cache::release(lock_protocol::lockid_t lid) | ||
{ | ||
return lock_protocol::OK; | ||
|
||
} | ||
|
||
rlock_protocol::status | ||
lock_client_cache::revoke_handler(lock_protocol::lockid_t lid, | ||
int &) | ||
{ | ||
int ret = rlock_protocol::OK; | ||
return ret; | ||
} | ||
|
||
rlock_protocol::status | ||
lock_client_cache::retry_handler(lock_protocol::lockid_t lid, | ||
int &) | ||
{ | ||
int ret = rlock_protocol::OK; | ||
return ret; | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// lock client interface. | ||
|
||
#ifndef lock_client_cache_h | ||
|
||
#define lock_client_cache_h | ||
|
||
#include <string> | ||
#include "lock_protocol.h" | ||
#include "rpc.h" | ||
#include "lock_client.h" | ||
#include "lang/verify.h" | ||
|
||
// Classes that inherit lock_release_user can override dorelease so that | ||
// that they will be called when lock_client releases a lock. | ||
// You will not need to do anything with this class until Lab 5. | ||
class lock_release_user { | ||
public: | ||
virtual void dorelease(lock_protocol::lockid_t) = 0; | ||
virtual ~lock_release_user() {}; | ||
}; | ||
|
||
class lock_client_cache : public lock_client { | ||
private: | ||
class lock_release_user *lu; | ||
int rlock_port; | ||
std::string hostname; | ||
std::string id; | ||
public: | ||
lock_client_cache(std::string xdst, class lock_release_user *l = 0); | ||
virtual ~lock_client_cache() {}; | ||
lock_protocol::status acquire(lock_protocol::lockid_t); | ||
lock_protocol::status release(lock_protocol::lockid_t); | ||
rlock_protocol::status revoke_handler(lock_protocol::lockid_t, | ||
int &); | ||
rlock_protocol::status retry_handler(lock_protocol::lockid_t, | ||
int &); | ||
}; | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// the caching lock server implementation | ||
|
||
#include "lock_server_cache.h" | ||
#include <sstream> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <arpa/inet.h> | ||
#include "lang/verify.h" | ||
#include "handle.h" | ||
#include "tprintf.h" | ||
|
||
|
||
lock_server_cache::lock_server_cache() | ||
{ | ||
} | ||
|
||
|
||
int lock_server_cache::acquire(lock_protocol::lockid_t lid, std::string id, | ||
int &) | ||
{ | ||
lock_protocol::status ret = lock_protocol::OK; | ||
return ret; | ||
} | ||
|
||
int | ||
lock_server_cache::release(lock_protocol::lockid_t lid, std::string id, | ||
int &r) | ||
{ | ||
lock_protocol::status ret = lock_protocol::OK; | ||
return ret; | ||
} | ||
|
||
lock_protocol::status | ||
lock_server_cache::stat(lock_protocol::lockid_t lid, int &r) | ||
{ | ||
tprintf("stat request\n"); | ||
r = nacquire; | ||
return lock_protocol::OK; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#ifndef lock_server_cache_h | ||
#define lock_server_cache_h | ||
|
||
#include <string> | ||
|
||
#include <map> | ||
#include "lock_protocol.h" | ||
#include "rpc.h" | ||
#include "lock_server.h" | ||
|
||
|
||
class lock_server_cache { | ||
private: | ||
int nacquire; | ||
public: | ||
lock_server_cache(); | ||
lock_protocol::status stat(lock_protocol::lockid_t, int &); | ||
int acquire(lock_protocol::lockid_t, std::string id, int &); | ||
int release(lock_protocol::lockid_t, std::string id, int &); | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.