/// <summary> /// Wait until results of bundled requests are retrieved. /// </summary> /// <note> /// Calls to this method must be externally synchronized. /// </note> /// <param name="isFirst"> /// True iff this is the first thread entering the bundle /// </param> /// <returns> /// True if this thread is supposed to perform an actual bundled /// operation (burst); false otherwise /// </returns> public bool WaitForResults(bool isFirst) { m_cThreads++; try { if (isFirst) { m_startTime = DateTimeUtils.GetSafeTimeMillis(); } if (BundleSize < Bundler.SizeThreshold) { if (isFirst) { long lDelay = Bundler.DelayMillis; do { Monitor.Wait(Lock, (int)lDelay); lDelay = 0L; }while (IsPending()); } else { while (true) { Monitor.Wait(Lock); if (IsProcessed()) { return(false); } // spurious wake-up; continue waiting } } } if (IsProcessed()) { return(false); } // this bundle should be closed and processed right away SetStatus(STATUS_PENDING); // update stats TotalSize += BundleSize; long total = ++TotalBundles; if (total > 1000 && // allow the "hotspot" to kick in total % ADJUSTMENT_FREQUENCY == 0 && IsMaster) { // attempt to adjust for every 1000 iterations of the master // bundle Bundler.Adjust(); } } catch (ThreadInterruptedException) { Thread.CurrentThread.Interrupt(); SetStatus(STATUS_EXCEPTION); } catch (Exception e) { // should never happen --m_cThreads; throw e; } return(true); }