public void close() { Thread t = null; // This code avoids deadlock of calling close() from different threads // and avoid multiple closes synchronized (access) { if (worker != null) { t = worker; worker = null; } } // Then, releasing the lock, we perform closing, only once: if (t != null) { requestStop = true; t.interrupt(); // While the worker closes, we can free up the queue: EOFException eof = new EOFException(); // synchronized (resultQueue) { for (CommandResult dr : resultQueue.values()) { dr.sendFailure(eof); } resultQueue.clear(); // } // try { // t.join(); // } catch (InterruptedException ignored) { // } connector.close(); } }
private void processReply(Map<String, Object> input, Integer ref) { CommandResult dr; // synchronized (resultQueue) { dr = resultQueue.remove(ref); // } if (dr != null) { Object error = input.get("error"); if (error != null) { dr.sendFailure(RemoteException.makeException(error)); } else { Object result = input.get("result"); dr.sendSuccess(result); } } }
private CommandResult sendToRemote(Object... keysValues) { HashMap<String, Object> packet = Ut.mapFromArray(keysValues); synchronized (access) { if (isClosed()) { CommandResult closedResult = new CommandResult(0); closedResult.sendFailure(new EOFException("farcall is closed")); return closedResult; } packet.put("serial", outSerial); CommandResult result = new CommandResult(outSerial); // synchronized (resultQueue) { resultQueue.put(outSerial, result); // } try { connector.send(packet); } catch (IOException e) { // synchronized (resultQueue) { resultQueue.remove(outSerial); // } result.sendFailure(e); close(); return result; } outSerial++; return result; } }