package com.emc.mongoose.concurrent;

import com.github.akurilov.commons.concurrent.AsyncRunnableBase;

import java.io.Closeable;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 Modifies the async runnable to make sure that all instances are closed even if an user hits ^C
 */
public abstract class DaemonBase
extends AsyncRunnableBase
implements Daemon {

	private static final Logger LOG = Logger.getLogger(DaemonBase.class.getSimpleName());
	private static final Queue<WeakReference<Daemon>> REGISTRY = new ConcurrentLinkedQueue<>();

	private final WeakReference<Daemon> daemonRef;

	protected DaemonBase() {
		daemonRef = new WeakReference<>(this);
		REGISTRY.add(daemonRef);
	}

	@Override
	public final void close()
	throws IOException {
		super.close();
		REGISTRY.remove(daemonRef);
	}

	public static void closeAll() {
		while(!REGISTRY.isEmpty()) {
			final Closeable daemon = REGISTRY.peek().get();
			if(daemon != null) {
				try {
					daemon.close();
				} catch(final Throwable cause) {
					LOG.log(Level.WARNING, "Failed to close the daemon instance", cause);
				}
			}
		}
	}
}

@@ -809,16 +809,44 @@
 (this);%0A
+%09%09synchronized(REGISTRY) %7B%0A%09
 %09%09REGIST
@@ -860,24 +860,28 @@
 daemonRef);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09@Overri
@@ -949,16 +949,44 @@
 lose();%0A
+%09%09synchronized(REGISTRY) %7B%0A%09
 %09%09REGIST
@@ -1007,16 +1007,20 @@
 onRef);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09pub
@@ -1054,37 +1054,92 @@
 %7B%0A%09%09
-while(!REGISTRY.isEmpty()
+synchronized(REGISTRY) %7B%0A%09%09%09for(final WeakReference%3CDaemon%3E daemonRef: REGISTRY
 ) %7B%0A
+%09
 %09%09%09f
@@ -1166,31 +1166,25 @@
 n = 
-REGISTRY.peek()
+daemonRef
 .get();%0A
 %09%09%09i
@@ -1179,16 +1179,17 @@
 .get();%0A
+%09
 %09%09%09if(da
@@ -1212,14 +1212,16 @@
 %09%09%09%09
+%09
 try %7B%0A
+%09
 %09%09%09%09
@@ -1241,16 +1241,17 @@
 ();%0A%09%09%09%09
+%09
 %7D catch(
@@ -1271,24 +1271,25 @@
 le cause) %7B%0A
+%09
 %09%09%09%09%09LOG.log
@@ -1359,14 +1359,42 @@
 %09%09%09%09
-%7D%0A%09%09%09%7D
+%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09REGISTRY.clear();
 %0A%09%09%7D

save [skip ci]