// lock client interface.
#ifndef lock_client_h
+
#define lock_client_h
#ifdef __cplusplus
#include <string>
#include "lock_protocol.h"
#include "rpc/rpc.h"
-#include <vector>
+#include "lang/verify.h"
+#include "rpc/fifo.h"
+#include "rsm_client.h"
+
+class lock_release_user {
+ public:
+ virtual void dorelease(lock_protocol::lockid_t) = 0;
+ virtual ~lock_release_user() {};
+};
+
+using std::string;
+using std::thread;
+using std::list;
+using std::map;
+
+typedef string callback;
-// Client interface to the lock server
+class lock_state {
+public:
+ lock_state();
+ enum {
+ none = 0,
+ retrying,
+ free,
+ locked,
+ acquiring,
+ releasing
+ } state;
+ std::thread::id held_by;
+ list<std::thread::id> wanted_by;
+ mutex m;
+ map<std::thread::id, std::condition_variable> c;
+ lock_protocol::xid_t xid;
+ void wait();
+ void signal();
+ void signal(std::thread::id who);
+};
+
+typedef map<lock_protocol::lockid_t, lock_state> lock_map;
+
+// Clients that caches locks. The server can revoke locks using
+// lock_revoke_server.
class lock_client {
- protected:
- rpcc *cl;
- public:
- lock_client(std::string d);
- virtual ~lock_client() {};
- virtual lock_protocol::status acquire(lock_protocol::lockid_t);
- virtual lock_protocol::status release(lock_protocol::lockid_t);
- virtual lock_protocol::status stat(lock_protocol::lockid_t);
+ private:
+ rpcc *cl;
+ std::thread releaser_thread;
+ rsm_client *rsmc;
+ class lock_release_user *lu;
+ int rlock_port;
+ string hostname;
+ string id;
+ mutex xid_mutex;
+ lock_protocol::xid_t xid;
+ fifo<lock_protocol::lockid_t> release_fifo;
+ mutex lock_table_lock;
+ lock_map lock_table;
+ lock_state &get_lock_state(lock_protocol::lockid_t lid);
+ public:
+ static int last_port;
+ lock_client(string xdst, class lock_release_user *l = 0);
+ ~lock_client() {};
+ lock_protocol::status acquire(lock_protocol::lockid_t);
+ lock_protocol::status release(lock_protocol::lockid_t);
+ int stat(lock_protocol::lockid_t);
+ void releaser();
+ rlock_protocol::status revoke_handler(int &, lock_protocol::lockid_t, lock_protocol::xid_t);
+ rlock_protocol::status retry_handler(int &, lock_protocol::lockid_t, lock_protocol::xid_t);
};
-#endif
+#endif // C++
extern "C" {