|
@@ -11,9 +11,6 @@
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
-struct synchronization_tool exitSync, readySync;
|
|
|
-mutex updateMtx;
|
|
|
-
|
|
|
atomic<size_t> epochNum(0);
|
|
|
|
|
|
// Initialize the classes we use
|
|
@@ -238,7 +235,7 @@ Twistpoint get_generator(
|
|
|
pi.push_back(currProof);
|
|
|
|
|
|
remove(genFilename);
|
|
|
- delete genFilename;
|
|
|
+ delete [] genFilename;
|
|
|
}
|
|
|
|
|
|
return retval;
|
|
@@ -390,7 +387,7 @@ Twistpoint initiate_epoch_updates(
|
|
|
generatorProofHolder.push_back(generatorProof);
|
|
|
|
|
|
remove(epochFilename);
|
|
|
- delete epochFilename;
|
|
|
+ delete [] epochFilename;
|
|
|
|
|
|
return retval;
|
|
|
}
|
|
@@ -772,6 +769,8 @@ void distribute_tallied_scores(
|
|
|
}
|
|
|
|
|
|
void epoch(
|
|
|
+ mutex *updateMtx,
|
|
|
+ atomic<size_t> *epochNum,
|
|
|
PrsonaServer *prsonaServer,
|
|
|
default_random_engine& rng,
|
|
|
const vector<string>& serverIPs,
|
|
@@ -783,7 +782,7 @@ void epoch(
|
|
|
|
|
|
struct synchronization_tool updateSync;
|
|
|
|
|
|
- unique_lock<mutex> lck(updateMtx, defer_lock);
|
|
|
+ unique_lock<mutex> lck(*updateMtx, defer_lock);
|
|
|
obtain_update_locks(
|
|
|
lck,
|
|
|
serverIPs,
|
|
@@ -835,7 +834,7 @@ void epoch(
|
|
|
generatorProof,
|
|
|
nextGenerator);
|
|
|
|
|
|
- epochNum.fetch_add(1);
|
|
|
+ epochNum->fetch_add(1);
|
|
|
|
|
|
release_update_locks(
|
|
|
lck,
|
|
@@ -849,15 +848,16 @@ void epoch(
|
|
|
class EpochReadyHandler : public CivetHandler
|
|
|
{
|
|
|
public:
|
|
|
- EpochReadyHandler(size_t numServers)
|
|
|
- : numServers(numServers) { /* */ }
|
|
|
+ EpochReadyHandler(struct synchronization_tool *exitSync, struct synchronization_tool *readySync, size_t numServers)
|
|
|
+ : exitSync(exitSync), readySync(readySync), numServers(numServers)
|
|
|
+ { /* */ }
|
|
|
|
|
|
bool handleGet(CivetServer *server, struct mg_connection *conn)
|
|
|
{
|
|
|
- unique_lock<mutex> exitLock(exitSync.mtx, defer_lock);
|
|
|
- unique_lock<mutex> readyLock(readySync.mtx);
|
|
|
+ unique_lock<mutex> exitLock(exitSync->mtx, defer_lock);
|
|
|
+ unique_lock<mutex> readyLock(readySync->mtx);
|
|
|
|
|
|
- if (readySync.val < numServers)
|
|
|
+ if (readySync->val < numServers)
|
|
|
{
|
|
|
mg_printf(conn,
|
|
|
"HTTP/1.1 503 Service Unavailable\r\nContent-Type: "
|
|
@@ -883,6 +883,7 @@ class EpochReadyHandler : public CivetHandler
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
+ struct synchronization_tool *exitSync, *readySync;
|
|
|
const size_t numServers;
|
|
|
|
|
|
};
|
|
@@ -890,15 +891,90 @@ class EpochReadyHandler : public CivetHandler
|
|
|
class EpochNumHandler : public CivetHandler
|
|
|
{
|
|
|
public:
|
|
|
+ EpochNumHandler(atomic<size_t> *epochNum)
|
|
|
+ : epochNum(epochNum)
|
|
|
+ { /* */ }
|
|
|
+
|
|
|
bool handleGet(CivetServer *server, struct mg_connection *conn)
|
|
|
{
|
|
|
mg_printf(conn,
|
|
|
"HTTP/1.1 200 OK\r\nContent-Type: "
|
|
|
"text/plain\r\nConnection: close\r\n\r\n");
|
|
|
- mg_printf(conn, "Epoch num: %lu\n", epochNum.load());
|
|
|
+ mg_printf(conn, "Epoch num: %lu\n", epochNum->load());
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
+ private:
|
|
|
+ atomic<size_t> *epochNum;
|
|
|
+};
|
|
|
+
|
|
|
+class UpdateLockWebSocketHandler : public CivetWebSocketHandler
|
|
|
+{
|
|
|
+ public:
|
|
|
+ UpdateLockWebSocketHandler(mutex *updateMtx, unique_lock<mutex> **lockHolder, bool isLocking)
|
|
|
+ : updateMtx(updateMtx), lockHolder(lockHolder), isLocking(isLocking)
|
|
|
+ { /* */ }
|
|
|
+
|
|
|
+ ~UpdateLockWebSocketHandler()
|
|
|
+ { delete *lockHolder; }
|
|
|
+
|
|
|
+ bool handleConnection(CivetServer *server, const struct mg_connection *conn)
|
|
|
+ { return true; }
|
|
|
+
|
|
|
+ void handleReadyState(CivetServer *server, struct mg_connection *conn)
|
|
|
+ { /* */ }
|
|
|
+
|
|
|
+ bool handleData(CivetServer *server, struct mg_connection *conn, int bits, char *data, size_t data_len)
|
|
|
+ {
|
|
|
+ switch (bits & 0xf)
|
|
|
+ {
|
|
|
+ case MG_WEBSOCKET_OPCODE_DATACOMPLETE:
|
|
|
+ if (isLocking)
|
|
|
+ {
|
|
|
+ unique_lock<mutex> *tempHolder = new unique_lock<mutex>(*updateMtx);
|
|
|
+
|
|
|
+ // Once you get to this line, we now hold the lock,
|
|
|
+ // and lockHolder is guaranteed to be NULL
|
|
|
+ *lockHolder = tempHolder;
|
|
|
+
|
|
|
+ // Respond to notify that the requesting process holds the lock
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // You must do things in this order so that *lockHolder will be
|
|
|
+ // guaranteed to be NULL at the time the lock unlocks
|
|
|
+ // (deletion of the lock object)
|
|
|
+ unique_lock<mutex> *tempHolder = *lockHolder;
|
|
|
+ *lockHolder = NULL;
|
|
|
+
|
|
|
+ delete tempHolder;
|
|
|
+
|
|
|
+ // Respond to notify that the requesting process has released the lock
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE:
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ cerr << "Unknown opcode: failing." << endl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ void handleClose(CivetServer *server, const struct mg_connection *conn)
|
|
|
+ { /* */ }
|
|
|
+
|
|
|
+
|
|
|
+ private:
|
|
|
+ mutex *updateMtx;
|
|
|
+ unique_lock<mutex> **lockHolder;
|
|
|
+ const bool isLocking;
|
|
|
};
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
@@ -1034,6 +1110,11 @@ int main(int argc, char *argv[])
|
|
|
if (maliciousServers)
|
|
|
PrsonaBase::set_server_malicious();
|
|
|
|
|
|
+ struct synchronization_tool exitSync, readySync;
|
|
|
+ mutex updateMtx;
|
|
|
+ unique_lock<mutex> *updateLockHolder;
|
|
|
+ atomic<size_t> epochNum(0);
|
|
|
+
|
|
|
cout << "[" << seedStr << "] Creating PrsonaServer entity." << endl;
|
|
|
|
|
|
// Entities we operate with
|
|
@@ -1089,7 +1170,7 @@ int main(int argc, char *argv[])
|
|
|
prsonaServer = create_server_from_bgn_file(numServers, &bgnSync, bgnFilename);
|
|
|
|
|
|
remove(bgnFilename);
|
|
|
- delete bgnFilename;
|
|
|
+ delete [] bgnFilename;
|
|
|
}
|
|
|
|
|
|
CivetServer server(options);
|
|
@@ -1149,6 +1230,12 @@ int main(int argc, char *argv[])
|
|
|
RemoteControlHandler exitHandler(&exitSync, "Server coming down!");
|
|
|
server.addHandler(EXIT_URI, exitHandler);
|
|
|
|
|
|
+ UpdateLockWebSocketHandler lockHandler(&updateMtx, &updateLockHolder, true);
|
|
|
+ UpdateLockWebSocketHandler unlockHandler(&updateMtx, &updateLockHolder, false);
|
|
|
+
|
|
|
+ server.addWebSocketHandler(UPDATE_LOCK_URI, lockHandler);
|
|
|
+ server.addWebSocketHandler(UPDATE_UNLOCK_URI, unlockHandler);
|
|
|
+
|
|
|
cout << "[" << seedStr << "] Entering main ready loop." << endl;
|
|
|
|
|
|
if (bgnDealer)
|
|
@@ -1156,10 +1243,10 @@ int main(int argc, char *argv[])
|
|
|
AltRemoteControlHandler triggerEpochHandler(1, &exitSync, "Server will initiate epoch!");
|
|
|
server.addHandler(TRIGGER_EPOCH_URI, triggerEpochHandler);
|
|
|
|
|
|
- EpochReadyHandler epochReadyHandler(numServers);
|
|
|
+ EpochReadyHandler epochReadyHandler(&exitSync, &readySync, numServers);
|
|
|
server.addHandler(EPOCH_READY_URI, epochReadyHandler);
|
|
|
|
|
|
- EpochNumHandler epochNumHandler;
|
|
|
+ EpochNumHandler epochNumHandler(&epochNum);
|
|
|
server.addHandler(WHICH_EPOCH_URI, epochNumHandler);
|
|
|
|
|
|
while (!exitSync.val)
|
|
@@ -1171,7 +1258,7 @@ int main(int argc, char *argv[])
|
|
|
{
|
|
|
cout << "[" << seedStr << "] Executing epoch." << endl;
|
|
|
|
|
|
- epoch(prsonaServer, rng, serverIPs, serverPorts, selfIP, selfPort);
|
|
|
+ epoch(&updateMtx, &epochNum, prsonaServer, rng, serverIPs, serverPorts, selfIP, selfPort);
|
|
|
|
|
|
exitSync.val2 = 0;
|
|
|
}
|