/* * 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; /** * 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; } public void close() { synchronized (lock) { this.ids = null; // set null to prevent memory leak after closure! } } @Override public void outOfOffHeapMemory(final OutOfOffHeapMemoryException cause) { synchronized (lock) { if (this.ids == null) { return; } if (Boolean.getBoolean(OffHeapStorage.STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY)) { return; } final InternalDistributedSystem dsToDisconnect = this.ids; this.ids = null; // set null to prevent memory leak after closure! if (dsToDisconnect.getDistributionManager().getRootCause() == null) { dsToDisconnect.getDistributionManager().setRootCause(cause); } Runnable runnable = new Runnable() { @Override public void run() { dsToDisconnect.getLogWriter() .info("OffHeapStorage about to invoke disconnect on " + dsToDisconnect); dsToDisconnect.disconnect(cause.getMessage(), cause, false); } }; // invoking disconnect is async because caller may be a DM pool thread which will block until // DM shutdown times out // LogWriterImpl.LoggingThreadGroup group = LogWriterImpl.createThreadGroup("MemScale // Threads", ids.getLogWriterI18n()); String name = this.getClass().getSimpleName() + "@" + this.hashCode() + " Handle OutOfOffHeapMemoryException Thread"; // Thread thread = new Thread(group, runnable, name); Thread thread = new Thread(runnable, name); thread.setDaemon(true); thread.start(); } } }