<commit_before>package com.vltgroup.ccTalk.devices;

import com.vltgroup.ccTalk.bus.Bus;
import com.vltgroup.ccTalk.bus.DeviceInfo;
import com.vltgroup.ccTalk.commands.Command;
import com.vltgroup.ccTalk.commands.CommandHeader;
import com.vltgroup.ccTalk.commands.Responce;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class BaseDevice implements Runnable{
  private static final Logger log = LoggerFactory.getLogger(BaseDevice.class.getName());
  protected final long[]   channelCostInCents = new long[16];  //command 231 - Modify inhibit status suport only 16 channels
  protected final String[] channelCostString = new String[16];
  
  public final        Bus             bus;
  public final        DeviceInfo      info;
  private volatile    boolean         run;
  protected final     ExecutorService eventExecutor;
  
  private   volatile boolean  notRespond;
  protected volatile boolean  m_lastInhibit;
  private final BaseController controller;
  private long                prevEnd;   
  
  public BaseDevice(Bus bus, DeviceInfo info, BaseController controller){
    this.bus=bus;
    this.info=info;
    run=true;
    eventExecutor=Executors.newCachedThreadPool();
    notRespond=false;
    m_lastInhibit=true;
    this.controller=controller;
    prevEnd=System.currentTimeMillis();
  }
  
  public String[] getChannelCost(){
    return channelCostString;
  }
  
  protected boolean getNotRespondStatus(){
    return notRespond;
  }
  
  @Override
  public void run() {
    log.info(info.shortString() +" thread started");
    while(run) {
      try {
        Thread.sleep(info.pollingInterval/2);
        long tickBegin = System.currentTimeMillis();
                  
        if(notRespond){
          init(true);
          notRespond=false;
          eventExecutor.submit(new Runnable() {
            @Override
            public void run() {
              controller.onDeviceRestored(BaseDevice.this);
            }
          });
        }
        
        if(!notRespond) deviceTick();
        long tickEnd = System.currentTimeMillis();
        log.debug(info.shortString()+" between={}ms  self={}ms", tickBegin-prevEnd, tickEnd-tickBegin);
        prevEnd=tickEnd;
        
      } catch (Exception ex){
        log.warn("",ex);
      }
    }
    setMasterInhibitStatusSync(true);
  }
  public void stop(){
    run=false;
  }

  
  public Responce executeCommandSync(CommandHeader command, int expectedDataLength){<commit_msg>make device stop synchronous<commit_after>package com.vltgroup.ccTalk.devices;

import com.vltgroup.ccTalk.bus.Bus;
import com.vltgroup.ccTalk.bus.DeviceInfo;
import com.vltgroup.ccTalk.commands.Command;
import com.vltgroup.ccTalk.commands.CommandHeader;
import com.vltgroup.ccTalk.commands.Responce;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class BaseDevice implements Runnable{
  private static final Logger log = LoggerFactory.getLogger(BaseDevice.class.getName());
  protected final long[]   channelCostInCents = new long[16];  //command 231 - Modify inhibit status suport only 16 channels
  protected final String[] channelCostString = new String[16];
  
  public final        Bus             bus;
  public final        DeviceInfo      info;
  private volatile    boolean         run;
  protected final     ExecutorService eventExecutor;
  
  private   volatile boolean  notRespond;
  protected volatile boolean  m_lastInhibit;
  private final BaseController controller;
  private long                prevEnd;   
  private final Semaphore     finishSemaphore;
  
  public BaseDevice(Bus bus, DeviceInfo info, BaseController controller){
    this.bus=bus;
    this.info=info;
    run=true;
    eventExecutor=Executors.newCachedThreadPool();
    notRespond=false;
    m_lastInhibit=true;
    this.controller=controller;
    prevEnd=System.currentTimeMillis();
    finishSemaphore=new Semaphore(0);
  }
  
  public String[] getChannelCost(){
    return channelCostString;
  }
  
  protected boolean getNotRespondStatus(){
    return notRespond;
  }
  
  @Override
  public void run() {
    log.info(info.shortString() +" thread started");
    while(run) {
      try {
        Thread.sleep(info.pollingInterval/2);
        long tickBegin = System.currentTimeMillis();
                  
        if(notRespond){
          init(true);
          notRespond=false;
          eventExecutor.submit(new Runnable() {
            @Override
            public void run() {
              controller.onDeviceRestored(BaseDevice.this);
            }
          });
        }
        
        if(!notRespond) deviceTick();
        long tickEnd = System.currentTimeMillis();
        log.debug(info.shortString()+" between={}ms  self={}ms", tickBegin-prevEnd, tickEnd-tickBegin);
        prevEnd=tickEnd;
        
      } catch (Exception ex){
        log.warn("",ex);
      }
    }
    setMasterInhibitStatusSync(true);
    finishSemaphore.release();
  }
  
  public void stop(){
    run=false;
    try{
      finishSemaphore.acquire();
    }catch(InterruptedException ignored){
    }
  }

  
  public Responce executeCommandSync(CommandHeader command, int expectedDataLength){
{'fraction_non_alphanumeric': 0.09287176623860041, 'fraction_numerical': 0.004652894100130281, 'mean_word_length': 2.911208151382824, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2557644', 'n_tokens_mistral': 1572, 'n_tokens_neox': 1513, 'n_words': 331}