/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;
import sun.misc.CVM;

public class DaemonThread {
 static ThreadGroup tg;
 static int id;

 public interface Code {
  public void run(Object args[]);
 }

 public static class Helper extends Thread {
  Code code;
  Object args[];

  public Helper(Code run,Object objtab[]) {
   super(tg,"DaemonThread #"+id);

   code=run;
   args=objtab;

   id++;
  }

  public void run() {
   code.run(args);
  }
 }

 private static ThreadGroup get_root_grup() {
  ThreadGroup group=Thread.currentThread().getThreadGroup();

  while(group.getParent()!=null) {
   group=group.getParent();
  }
  
  return group;
 }

 static {
  id=1;

  int pid=CVM.attachProcess(-1);

  tg=new ThreadGroup(get_root_grup(),"Daemon Threads Group");
  tg.setDaemon(true);

  CVM.detachProcess(pid);
 }

 public static Thread start(Code run,Object objtab[]) {
  int pid=CVM.attachProcess(-1);

  Helper h=new Helper(run,objtab);
  h.start();

  CVM.detachProcess(pid);

  return h;
 }

}
