code: @Override
      public void run()
      {
          if (!running.compareAndSet(false, true))
          {
              throw new IllegalStateException("Thread is already running");
          }
          sequenceBarrier.clearAlert();
  
          notifyStart();
  
          boolean processedSequence = true;
          long cachedAvailableSequence = Long.MIN_VALUE;
          long nextSequence = sequence.get();
          T event = null;
          while (true)
          {
              try
              {
                  // if previous sequence was processed - fetch the next sequence and set
                  // that we have successfully processed the previous sequence
                  // typically, this will be true
                  // this prevents the sequence getting too far forward if an exception
                  // is thrown from the WorkHandler
                  if (processedSequence)
                  {
                      processedSequence = false;
                      do
                      {
                          nextSequence = workSequence.get() + 1L;
                          sequence.set(nextSequence - 1L);
                      }
                      while (!workSequence.compareAndSet(nextSequence - 1L, nextSequence));
                  }
  
                  if (cachedAvailableSequence >= nextSequence)
                  {
                      event = ringBuffer.get(nextSequence);
                      workHandler.onEvent(event);
                      processedSequence = true;
                  }
                  else
                  {
                      cachedAvailableSequence = sequenceBarrier.waitFor(nextSequence);
                  }
              }
              catch (final TimeoutException e)
              {
                  notifyTimeout(sequence.get());
              }
              catch (final AlertException ex)
              {
                  if (!running.get())
                  {
                      break;
                  }
              }
              catch (final Throwable ex)
              {
                  // handle, mark as processed, unless the exception handler threw an exception
                  exceptionHandler.handleEventException(ex, nextSequence, event);
                  processedSequence = true;
              }
          }
  
          notifyShutdown();
  
          running.set(false);
      }
docs: It is ok to have another thread re-run this method after a halt().
  
  @throws IllegalStateException if this processor is already running