예제 #1
0
 private void add(PooledFatPipe child) {
   long start = System.currentTimeMillis();
   while (true) {
     int fails = 0;
     for (int i = 0; i < inUse.length(); i++) {
       if (!inUse.compareAndSet(i, 0, 2)) {
         if (inUse.get(i) != 2) fails++;
       }
     }
     if (fails == 0) break;
     if (start + 100 < System.currentTimeMillis()) {
       logger.warn("unable to add cleanly " + toString());
       break;
     }
   }
   final AtomicIntegerArray updated = new AtomicIntegerArray(inUse.length() + 1);
   final List<Integer> needsReset = new ArrayList<>();
   for (int i = 0; i < inUse.length(); i++) {
     int value = inUse.get(i);
     if (value == 1) {
       updated.set(i, value);
       needsReset.add(i);
     }
   }
   final AtomicIntegerArray oldUse = inUse;
   inUse = updated;
   signals = new ChildSignalImpl[signals.length + poolSize];
   for (int i = 0; i < signals.length; i++) {
     signals[i] = new ChildSignalImpl(inUse, 0);
   }
   children = Arrays.copyOf(children, children.length + 1);
   children[children.length - 1] = child;
   scheduleReset(needsReset, oldUse, updated);
 }
예제 #2
0
 void scheduleReset(
     List<Integer> needsReset, AtomicIntegerArray oldUse, AtomicIntegerArray updated) {
   if (needsReset.size() == 0) return;
   executor.schedule(
       () -> {
         for (int i = 0; i < needsReset.size(); i++) {
           int index = needsReset.get(i);
           int value = oldUse.get(index);
           if (value == 0) {
             updated.set(index, 0);
             needsReset.remove(i--);
           }
         }
         scheduleReset(needsReset, oldUse, updated);
       },
       1,
       TimeUnit.MILLISECONDS);
 }
예제 #3
0
 @Override
 public synchronized Receptor<T> takeReceptor() {
   if (!freeReceptors.isEmpty()) {
     ReceptorImpl impl = (ReceptorImpl) freeReceptors.remove(0);
     impl.skips = 0;
     return impl;
   }
   int length = inputs.length() + 1;
   final AtomicReferenceArray<T> inputs = new AtomicReferenceArray<>(length);
   this.inputs = inputs;
   final List<ReceptorImpl> newReuseReceptors = new ArrayList<>(length);
   for (int i = 0; i < length; i++) {
     newReuseReceptors.add(new ReceptorImpl(i));
   }
   executor.execute(
       () -> {
         long lastTime = System.currentTimeMillis();
         try {
           boolean empty = false;
           while (!empty && started) {
             empty = true;
             for (int i = 0; i < outputs.length(); i++) {
               T result = outputs.get(i);
               if (result == null) continue;
               Thread.sleep(1);
               empty = false;
               if (lastTime + 30_000 < System.currentTimeMillis()) {
                 lastTime = System.currentTimeMillis();
                 logger.error(
                     "unable to set receptors for " + producer + " i=" + i + " result=" + result);
                 if (pool != null) logger.warn("pool=" + pool.producer);
               }
               break;
             }
           }
         } catch (InterruptedException e) {
           logger.warn("takeReceptor", e);
         } finally {
           reuseReceptors = newReuseReceptors;
           outputs = inputs;
         }
       });
   return new ReceptorImpl(length - 1);
 }
예제 #4
0
 /**
  * Look for data from all the inputs
  *
  * @return true if data was consumed
  */
 private boolean poll(Signal signal, Signal parent) {
   AtomicReferenceArray<T> o = outputs;
   for (int i = 0; i < o.length(); i++) {
     T input = o.getAndSet(i, null);
     if (input == null) continue;
     long seq = ++sequence;
     if (parent != null) parent.signal();
     S product = producer.execute(input, reuseReceptors.get(i), signal);
     signal.signal();
     if (!consume(product, seq, 0)) {
       Thread.yield();
       if (!consume(product, seq, 0))
         logger.info(
             "failed to consume product (" + product + ") from producer (" + producer + ")");
     }
     producer.complete(product);
     return product != null;
   }
   return false;
 }