-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwatcardoffice.cc
executable file
·126 lines (104 loc) · 3.51 KB
/
watcardoffice.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "watcardoffice.h"
#include <iostream>
#include <fstream>
void WATCardOffice::main() {
printer.print(Printer::Kind::WATCardOffice, 'S');
std::vector<Courier*> couriers;
for (int i = 0; i < numCouriers; ++i) {
couriers.push_back(
new Courier(
*this,
bank,
printer,
i
)
);
}
for (;;) {
_Accept (~WATCardOffice) {
while (!jobQueue.empty()) {
Job * j = jobQueue.front();
jobQueue.pop();
// if (j->existingCard != nullptr) {
// delete j->existingCard;
// }
delete j;
}
while (!jobsAreAvailable.empty()) {
jobsAreAvailable.signalBlock();
}
for (;;) {
_Accept(requestWork) {}
_Else { break; };
}
while (!jobsAreAvailable.empty()) {
jobsAreAvailable.signalBlock();
}
for (int i = 0; i < numCouriers; ++i) {
delete couriers[i];
}
break;
} or _Accept(create || transfer || requestWork);
}
printer.print(Printer::Kind::WATCardOffice, 'F');
}
WATCardOffice::WATCardOffice( Printer & prt, Bank & bank, unsigned int numCouriers )
: printer{prt}, bank{bank}, numCouriers{numCouriers} {}
WATCard::FWATCard WATCardOffice::create( unsigned int sid, unsigned int amount ) {
Job *j = new Job{sid, amount};
jobQueue.push(j);
jobsAreAvailable.signal();
printer.print(Printer::Kind::WATCardOffice, 'C', sid, amount);
return j->result;
}
WATCard::FWATCard WATCardOffice::transfer( unsigned int sid, unsigned int amount, WATCard * card ) {
Job *j = new Job{sid, amount, card};
jobQueue.push(j);
jobsAreAvailable.signal();
printer.print(Printer::Kind::WATCardOffice, 'T', sid, amount);
return j->result;
}
WATCardOffice::Job * WATCardOffice::requestWork() {
if (jobQueue.empty()) {
jobsAreAvailable.wait(); // Courier blocks until a new job is available;
}
if (jobQueue.empty()) {
return nullptr;
}
Job * j = jobQueue.front();
jobQueue.pop();
printer.print(Printer::Kind::WATCardOffice, 'W');
return j;
}
void WATCardOffice::Courier::main() {
printer.print(Printer::Kind::Courier, id, 'S');
for (;;) {
// Block and wait for work
Job * j = office.requestWork();
if (j == nullptr) {
break;
}
printer.print(Printer::Kind::Courier, id, 't', j->sid, j->amount);
bank.withdraw(j->sid, j->amount); // Potentially blocking call to bank // XXX need to catch RendezvousFailure
_Accept(~Courier) {
delete j;
break;
} _Else {
// Potentially create new card
WATCard* realCard = (j->existingCard == nullptr) ? new WATCard() : j->existingCard;
realCard->deposit(j->amount);
if (prng(6) == 0) {
// WATCard lost; deliver exception
j->result.exception(new Lost);
printer.print(Printer::Kind::Courier, id, 'L', j->sid);
delete realCard;
} else {
// WATCard successfully delivered
j->result.delivery(realCard);
printer.print(Printer::Kind::Courier, id, 'T', j->sid, j->amount);
}
}
delete j;
}
printer.print(Printer::Kind::Courier, 'F');
}