/*******************************************************************************
 * This file is part of TERMINAL RECALL
 * Copyright (c) 2015 Chuck Ritola
 * Part of the jTRFP.org project
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     chuck - initial API and implementation
 ******************************************************************************/
package org.jtrfp.trcl.ext.tr;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import org.jtrfp.trcl.ext.Extension;
import org.jtrfp.trcl.gpu.GPU;

public class GPUResourceFinalizer implements Extension<GPU> {
    private ExecutorService      finalizationExecutor;

    @Override
    public void init(GPU extended) {
    }

    @Override
    public void apply(GPU extended) {
	 finalizationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*3, new GPURFThreadFactory());
    }//end apply(...)

    @Override
    public void remove(GPU extended) {
	finalizationExecutor = null;
    }

    @Override
    public Class<GPU> getExtendedClass() {
	return GPU.class;
    }

    @Override
    public String getHumanReadableName() {
	return "GPU Resource Finalizer.";
    }

    @Override
    public String getDescription() {
	return "Handles the release of GPU resources while decoupled from the GC's finalizer thread.";
    }
    
    public void submitFinalizationAction(Callable<Void> c){
	finalizationExecutor.submit(c);
    }//end submitFinalizationAction(...)
    
    private final AtomicInteger threadID = new AtomicInteger();
    
    private final class GPURFThreadFactory implements ThreadFactory{
	@Override
	public Thread newThread(final Runnable r) {
	    final Thread result = new Thread(null,r,"GPUResourceFinalizer-"+threadID.getAndIncrement(),0);
	    return result;
	}
    }//end GPURFThreadFactory

}//end GPUResourceFinalizer

@@ -675,56 +675,189 @@
 ecut
-orService;%0Aimport java.util.concurrent.Executors
+ionException;%0Aimport java.util.concurrent.ExecutorService;%0Aimport java.util.concurrent.Executors;%0Aimport java.util.concurrent.Future;%0Aimport java.util.concurrent.LinkedBlockingQueue
 ;%0Aim
@@ -1133,16 +1133,434 @@
 xecutor;
+%0A    private LinkedBlockingQueue%3CFuture%3CVoid%3E%3E    finalizationFutures = new LinkedBlockingQueue%3CFuture%3CVoid%3E%3E();%0A    %0A    private final Thread finalizationFutureCheckerThread = new Thread()%7B%0A%09@Override%0A%09public void run()%7B%0A%09    try%7B%0A%09%09while(true)%0A%09%09    %7BfinalizationFutures.take().get();%7D%0A%09    %7D//end try%7B%7D%0A%09    catch(ExecutionException e)%7Be.printStackTrace();%7D%0A%09    catch(InterruptedException e)%7B%7D%0A%09%7D//end run()%0A    %7D;
 %0A%0A    @O
@@ -1664,17 +1664,58 @@
 ded) %7B%0A%09
- 
+finalizationFutureCheckerThread.start();%0A%09
 finaliza
@@ -1937,16 +1937,72 @@
 = null;%0A
+%09finalizationFutureCheckerThread.interrupt();//UNTESTED%0A
     %7D%0A%0A 
@@ -2401,16 +2401,40 @@
 d%3E c)%7B%0A%09
+finalizationFutures.add(
 finaliza
@@ -2455,16 +2455,17 @@
 ubmit(c)
+)
 ;%0A    %7D/

Add getter thread to GPUResourceFinalizer for catching exceptions during execution.