/* This file is part of Reactive Cascade which is released under The MIT License. See license.md , https://github.com/futurice/cascade and http://reactivecascade.com for details. This is open source for the common good. Please contribute improvements by pull request or contact paulirotta@gmail.com */ package com.reactivecascade.util; import android.support.annotation.NonNull; import com.reactivecascade.Async; import com.reactivecascade.i.IThreadType; import com.reactivecascade.i.NotCallOrigin; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * This is a marker class to aid in runtime tests. * <p> * TODO Remove completed thread types from this structure */ @NotCallOrigin public class TypedThread extends Thread { public static final ThreadGroup THREAD_GROUP = new ThreadGroup("ThreadTypeThreadGroup") { @Override public void uncaughtException(@NonNull final Thread t, @NonNull Throwable throwable) { RCLog.e(this, "uncaughtException in " + t, throwable); } }; /* * Each thread may belong to multiple threadTypes. At the moment we only track the * first ThreadType which created it. But since the Thread may outlive the ThreadType * (if used by other ThreadTypes) we use a WeakReference to allow the original * ThreadType to be garbage collected. * * TODO A better solution would be to track ThreadTypes split Threads without this potential for confusion. To be determined. */ private final CopyOnWriteArrayList<IThreadType> threadTypes = new CopyOnWriteArrayList<>(); public TypedThread(@NonNull IThreadType threadType, @NonNull Runnable runnable) { super(THREAD_GROUP, runnable); this.threadTypes.add(threadType); } public TypedThread(@NonNull IThreadType threadType, @NonNull Runnable runnable, @NonNull String threadName) { super(THREAD_GROUP, runnable, threadName); this.threadTypes.add(threadType); } public TypedThread(@NonNull IThreadType threadType, @NonNull String threadName) { super(THREAD_GROUP, threadName); this.threadTypes.add(threadType); } public TypedThread(@NonNull IThreadType threadType, @NonNull ThreadGroup group, @NonNull Runnable runnable) { super(group, runnable); this.threadTypes.add(threadType); } public TypedThread(@NonNull IThreadType threadType, @NonNull ThreadGroup group, @NonNull Runnable runnable, @NonNull String threadName) { super(group, runnable, threadName); this.threadTypes.add(threadType); } public TypedThread(@NonNull IThreadType threadType, @NonNull ThreadGroup group, @NonNull String threadName) { super(group, threadName); this.threadTypes.add(threadType); } public TypedThread(@NonNull IThreadType threadType, @NonNull ThreadGroup group, @NonNull Runnable runnable, @NonNull String threadName, long stackSize) { super(group, runnable, threadName, stackSize); this.threadTypes.add(threadType); } @NonNull public List<IThreadType> getThreadTypes() { return threadTypes; } @NonNull public IThreadType getThreadType() { List<IThreadType> currentThreadTypes = getThreadTypes(); IThreadType currentThreadType = Async.NON_CASCADE_THREAD; if (currentThreadTypes.size() == 1) { currentThreadType = currentThreadTypes.get(0); } else { RCLog.v(this, currentThreadTypes.size() + " threadTypes for this Thread, can not disambiguate"); } return currentThreadType; } }