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); }
@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); }