public ClientLockManagerImpl( TCLogger logger, SessionManager sessionManager, ClientIDProvider clientIdProvider, RemoteLockManager remoteLockManager, ThreadIDManager threadManager, ClientLockManagerConfig config, TaskRunner taskRunner) { this.logger = logger; this.clientIdProvider = clientIdProvider; this.remoteLockManager = remoteLockManager; this.threadManager = threadManager; this.sessionManager = sessionManager; this.locks = new ConcurrentHashMap<LockID, ClientLock>(config.getStripedCount()); final long gcPeriod = Math.max(config.getTimeoutInterval(), 100); this.gcTimer = taskRunner.newTimer("ClientLockManager LockGC"); this.lockLeaseTimer = taskRunner.newTimer("ClientLockManager Lock Lease Timer"); this.gcTimer.scheduleWithFixedDelay( new LockGcTimerTask(), gcPeriod, gcPeriod, TimeUnit.MILLISECONDS); }
void shutdownResources() { final TCLogger logger = DSO_LOGGER; if (this.counterManager != null) { try { this.counterManager.shutdown(); } catch (final Throwable t) { logger.error("error shutting down counter manager", t); } finally { this.counterManager = null; } } if (this.tcMemManager != null) { try { this.tcMemManager.shutdown(); } catch (final Throwable t) { logger.error("Error stopping memory manager", t); } finally { this.tcMemManager = null; } } if (this.lockManager != null) { try { this.lockManager.shutdown(false); } catch (final Throwable t) { logger.error("Error stopping lock manager", t); } finally { this.lockManager = null; } } try { this.communicationStageManager.stopAll(); } catch (final Throwable t) { logger.error("Error stopping stage manager", t); } if (this.channel != null) { try { this.channel.close(); } catch (final Throwable t) { logger.error("Error closing channel", t); } finally { this.channel = null; } } if (this.communicationsManager != null) { try { this.communicationsManager.shutdown(); } catch (final Throwable t) { logger.error("Error shutting down communications manager", t); } finally { this.communicationsManager = null; } } if (taskRunner != null) { logger.info("Shutting down TaskRunner"); taskRunner.shutdown(); } CommonShutDownHook.shutdown(); this.cluster.shutdown(); if (this.threadGroup != null) { boolean interrupted = false; try { final long end = System.currentTimeMillis() + TCPropertiesImpl.getProperties() .getLong(TCPropertiesConsts.L1_SHUTDOWN_THREADGROUP_GRACETIME); int threadCount = this.threadGroup.activeCount(); Thread[] t = new Thread[threadCount]; threadCount = this.threadGroup.enumerate(t); final long time = System.currentTimeMillis(); for (int x = 0; x < threadCount; x++) { long start = System.currentTimeMillis(); while (System.currentTimeMillis() < end && t[x].isAlive()) { t[x].join(1000); } logger.info( "Destroyed thread " + t[x].getName() + " time to destroy:" + (System.currentTimeMillis() - start) + " millis"); } logger.info( "time to destroy thread group:" + TimeUnit.SECONDS.convert(System.currentTimeMillis() - time, TimeUnit.MILLISECONDS) + " seconds"); if (this.threadGroup.activeCount() > 0) { logger.warn( "Timed out waiting for TC thread group threads to die - probable shutdown memory leak\n" + "Live threads: " + getLiveThreads(this.threadGroup)); Thread threadGroupCleanerThread = new Thread( this.threadGroup.getParent(), new TCThreadGroupCleanerRunnable(threadGroup), "TCThreadGroup last chance cleaner thread"); threadGroupCleanerThread.setDaemon(true); threadGroupCleanerThread.start(); logger.warn("Spawning TCThreadGroup last chance cleaner thread"); } else { logger.info("Destroying TC thread group"); this.threadGroup.destroy(); } } catch (final Throwable t) { logger.error("Error destroying TC thread group", t); } finally { if (interrupted) { Thread.currentThread().interrupt(); } } } if (TCPropertiesImpl.getProperties() .getBoolean(TCPropertiesConsts.L1_SHUTDOWN_FORCE_FINALIZATION)) System.runFinalization(); }