| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. You may obtain a |
| * copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| |
| package org.apache.geode.internal.offheap; |
| |
| import org.apache.geode.OutOfOffHeapMemoryException; |
| import org.apache.geode.distributed.internal.InternalDistributedSystem; |
| import org.apache.geode.logging.internal.executors.LoggingThread; |
| |
| /** |
| * Used to asynchronously disconnect an InternalDistributedSystem when we run out of off-heap |
| * memory. If the STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY sys prop is set to true then this |
| * listener will not disconnect. |
| */ |
| class DisconnectingOutOfOffHeapMemoryListener implements OutOfOffHeapMemoryListener { |
| private final Object lock = new Object(); |
| private InternalDistributedSystem ids; |
| |
| DisconnectingOutOfOffHeapMemoryListener(InternalDistributedSystem ids) { |
| this.ids = ids; |
| } |
| |
| @Override |
| public void close() { |
| synchronized (lock) { |
| ids = null; // set null to prevent memory leak after closure! |
| } |
| } |
| |
| @Override |
| public void outOfOffHeapMemory(final OutOfOffHeapMemoryException cause) { |
| synchronized (lock) { |
| if (ids == null) { |
| return; |
| } |
| if (Boolean.getBoolean(OffHeapStorage.STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY)) { |
| return; |
| } |
| |
| final InternalDistributedSystem dsToDisconnect = ids; |
| ids = null; // set null to prevent memory leak after closure! |
| |
| if (dsToDisconnect.getDistributionManager().getRootCause() == null) { |
| dsToDisconnect.getDistributionManager().setRootCause(cause); |
| } |
| |
| Runnable runnable = () -> { |
| dsToDisconnect.getLogWriter() |
| .info("OffHeapStorage about to invoke disconnect on " + dsToDisconnect); |
| dsToDisconnect.disconnect(cause.getMessage(), false); |
| }; |
| |
| // invoking disconnect is async because caller may be a DM pool thread which will block until |
| // DM shutdown times out |
| |
| String name = getClass().getSimpleName() + "@" + hashCode() |
| + " Handle OutOfOffHeapMemoryException Thread"; |
| Thread thread = new LoggingThread(name, runnable); |
| thread.start(); |
| } |
| } |
| } |