public boolean handleGenericDeliverable(OFMessage reply) { counters.updateReadStats(reply); @SuppressWarnings("unchecked") Deliverable<OFMessage> deliverable = (Deliverable<OFMessage>) this.xidDeliverableMap.get(reply.getXid()); if (deliverable != null) { if(reply instanceof OFErrorMsg) { deliverable.deliverError(new OFErrorMsgException((OFErrorMsg) reply)); } else { deliverable.deliver(reply); } if (deliverable.isDone()) this.xidDeliverableMap.remove(reply.getXid()); return true; } else { return false; } }
public void disconnected() { SwitchDisconnectedException exception = new SwitchDisconnectedException(getDatapathId()); for (Long xid : xidDeliverableMap.keySet()) { // protect against other mechanisms running at the same time // (timeout) Deliverable<?> removed = xidDeliverableMap.remove(xid); if (removed != null) { removed.deliverError(exception); } } }
@Override public void cancelAllPendingRequests() { /* * we don't need to be synchronized here. Even if another thread * modifies the map while we're cleaning up the future will eventually * timeout */ for (Deliverable<?> d : xidDeliverableMap.values()) { d.cancel(true); } xidDeliverableMap.clear(); }
@Override public void run(Timeout timeout) throws Exception { Deliverable<?> removed = xidDeliverableMap.remove(xid); if (removed != null && !removed.isDone()) { removed.deliverError(new TimeoutException( "timeout - did not receive answer for xid " + xid)); } }
@Override public <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> writeStatsRequest( OFStatsRequest<REPLY> request) { if (!isConnected()) { return Futures.immediateFailedFuture(new SwitchDisconnectedException(getDatapathId())); } final DeliverableListenableFuture<List<REPLY>> future = new DeliverableListenableFuture<List<REPLY>>(); Deliverable<REPLY> deliverable = new Deliverable<REPLY>() { private final List<REPLY> results = Collections .synchronizedList(new ArrayList<REPLY>()); @Override public void deliver(REPLY reply) { results.add(reply); if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { // done future.deliver(results); } } @Override public void deliverError(Throwable cause) { future.deliverError(cause); } @Override public boolean isDone() { return future.isDone(); } @Override public boolean cancel(boolean mayInterruptIfRunning) { return future.cancel(mayInterruptIfRunning); } }; registerDeliverable(request.getXid(), deliverable); this.write(request); return future; }
private void registerDeliverable(long xid, Deliverable<?> deliverable) { this.xidDeliverableMap.put(xid, deliverable); timer.newTimeout(new TimeOutDeliverable(xid), DELIVERABLE_TIME_OUT, DELIVERABLE_TIME_OUT_UNIT); }