(final ArrayList<Object> arg)
| 1131 | return Deferred.group(d).addCallback( |
| 1132 | new Callback<Object, ArrayList<Object>>() { |
| 1133 | public Object call(final ArrayList<Object> arg) { |
| 1134 | // Normally, now that we've shutdown() every client, all our caches should |
| 1135 | // be empty since each shutdown() generates a DISCONNECTED event, which |
| 1136 | // causes RegionClientPipeline to call removeClientFromCache(). |
| 1137 | HashMap<String, RegionClient> logme = null; |
| 1138 | synchronized (ip2client) { |
| 1139 | if (!ip2client.isEmpty()) { |
| 1140 | logme = new HashMap<String, RegionClient>(ip2client); |
| 1141 | } |
| 1142 | } |
| 1143 | if (logme != null) { |
| 1144 | // Putting this logging statement inside the synchronized block |
| 1145 | // can lead to a deadlock, since HashMap.toString() is going to |
| 1146 | // call RegionClient.toString() on each entry, and this locks the |
| 1147 | // client briefly. Other parts of the code lock clients first and |
| 1148 | // the ip2client HashMap second, so this can easily deadlock. |
| 1149 | LOG.error("Some clients are left in the client cache and haven't" |
| 1150 | + " been cleaned up: " + logme); |
| 1151 | logme = null; |
| 1152 | return disconnectEverything(); // Try again. |
| 1153 | } |
| 1154 | zkclient.disconnectZK(); |
| 1155 | return arg; |
| 1156 | } |
| 1157 | public String toString() { |
| 1158 | return "wait " + size + " RegionClient.shutdown()"; |
| 1159 | } |
nothing calls this directly
no test coverage detected