...
Code Block | ||
---|---|---|
| ||
// Class Page is defined separately. It stores and returns the Page name via getName()
public final boolean SUCCESS = true;
public final boolean FAILURE = false;
Page[] pageBuff = new Page[MAX_PAGE_SIZE];
public synchronized boolean sendPage(Socket socket, String pageName) throws IOException {
// Get the output stream to write the Page to
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
Page targetPage = null;
// Find the Page requested by the client (this operation requires synchronization)
for(Page p : pageBuff) {
if(p.getName().compareTo(pageName) == 0) {
targetPage = p;
}
}
// Page requested does not exist
if(targetPage == null) {
return FAILURE;
}
// Send the Page to the client (does not require any synchronization)
out.writeObject(targetPage);
out.flush();
out.close();
return SUCCESS;
}
|
Compliant Solution
This compliant solution entails separating the actions into a sequence of steps:
...
Code Block | ||
---|---|---|
| ||
public boolean sendReply(Socket socket, String pageName) { // No synchronization Page targetPage = getPage(pageName); if(targetPage == null) return FAILURE; return sendPage(socket, targetPage); } private synchronized Page getPage(String pageName) { // Requires synchronization Page targetPage = null; for(Page p : pageBuff) { if(p.getName().equals(pageName)) { targetPage = p; } } return targetPage; } public boolean sendPage(Socket socket, Page page) throws IOException { try{ // Get the output stream to write the Page to ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); // Send the Page to the client out.writeObject(page); out.flush(); out.close(); return SUCCESS; }catch(IOException io){ // Handle exception } return FAILURE; } |
Risk Assessment
If synchronized
methods and statements contain network transactional logic, temporary or permanent deadlocks may result.
...