Shortcut method to create a JoinPoint waiting for the given synchronization points, <b>the JoinPoint is started by this method.</b>
If some given synchronization points are null, they are just skipped.
177449
@SafeVarargs
	public static <T extends Exception> JoinPoint<T> fromSynchronizationPointsSimilarError(ISynchronizationPoint<T>... synchPoints) {
		JoinPoint<T> jp = new JoinPoint<>();
		for (int i = 0; i < synchPoints.length; ++i)
			if (synchPoints[i] != null)
				jp.addToJoin(synchPoints[i]);
		jp.start();
		return jp;
	}
611793
private void startPartitions(List<Integer> partitionsToExecute,
                                 List<Integer> startedPartitions,
                                 List<Integer> finishedPartitions,
                                 PartitionPlanDescriptor currentPlan) {

        while (startedPartitions.size() < partitionsToExecute.size()
               && startedPartitions.size() - finishedPartitions.size() < currentPlan.getThreads()) {

            int nextPartitionNumber = partitionsToExecute.get(startedPartitions.size());
            PartitionPlanConfig config = buildPartitionPlanConfig(currentPlan, nextPartitionNumber);

            Boolean nextPartitionStarted = null;
            StopLock stopLock = getStopLock(); // Store in local variable to facilitate Ctrl+Shift+G search in Eclipse
            synchronized (stopLock) {
                nextPartitionStarted = startPartition(config);
            }

            if (nextPartitionStarted) {
                startedPartitions.add(nextPartitionNumber);
            } else {
                // The partition wasn't started (probably because we're stopping).
                // Add the partitionNumber to both the started and finished lists,
                // so that the while-loop logic works as expected.
                startedPartitions.add(nextPartitionNumber);
                finishedPartitions.add(nextPartitionNumber);
            }
        }
    }
921802
public static ISynchronizationPoint<NoException> getClassLoadingSP(String name) {
		synchronized (classLoadingSP) {
			Pair<Thread,JoinPoint<NoException>> p = classLoadingSP.get(name);
			if (p == null) {
				JoinPoint<NoException> jp = new JoinPoint<NoException>();
				jp.addToJoin(1);
				jp.start();
				classLoadingSP.put(name, new Pair<Thread,JoinPoint<NoException>>(Thread.currentThread(), jp));
				return null;
			}
			if (p.getValue1() == Thread.currentThread()) {
				p.getValue2().addToJoin(1);
				return null;
			}
			return p.getValue2();
		}
	}
756002
public void asyncOperationStarted() {
    if (syncThread == Thread.currentThread()) {
      synchronized (entry) {
        while (entry.isProcessing()) {
          try {
            entry.wait();
          } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
          }
        }
      }
    } else {
      entryLocked = false;
    }
  }
582741
@Pure
	@SuppressWarnings("checkstyle:cyclomaticcomplexity")
	public PT getStartingPointFor(int index) {
		if ((index < 1) || (this.segmentList.size() <= 1)) {
			if (this.startingPoint != null) {
				return this.startingPoint;
			}
		} else {
			int idx = index;
			ST currentSegment = this.segmentList.get(idx);
			ST previousSegment = this.segmentList.get(--idx);

			// Because the two segments are the same
			// we must go deeper in the path elements
			// to detect the right segment
			int count = 0;
			while ((previousSegment != null) && (previousSegment.equals(currentSegment))) {
				currentSegment = previousSegment;
				idx--;
				previousSegment = (idx >= 0) ? this.segmentList.get(idx) : null;
				count++;
			}

			if (count > 0) {
				PT sp = null;
				if (previousSegment != null) {
					final PT p1 = currentSegment.getBeginPoint();
					final PT p2 = currentSegment.getEndPoint();
					final PT p3 = previousSegment.getBeginPoint();
					final PT p4 = previousSegment.getEndPoint();

					assert p1 != null && p2 != null && p3 != null && p4 != null;
					if (p1.equals(p3) || p1.equals(p4)) {
						sp = p1;
					} else if (p2.equals(p3) || p2.equals(p4)) {
						sp = p2;
					}

				} else {
					sp = this.startingPoint;
				}
				if (sp != null) {
					return ((count % 2) == 0) ? sp : currentSegment.getOtherSidePoint(sp);
				}

			} else if ((currentSegment != null) && (previousSegment != null)) {
				// if the two segments are different
				// it is simple to detect the
				// common point
				final PT p1 = currentSegment.getBeginPoint();
				final PT p2 = currentSegment.getEndPoint();
				final PT p3 = previousSegment.getBeginPoint();
				final PT p4 = previousSegment.getEndPoint();

				assert p1 != null && p2 != null && p3 != null && p4 != null;
				if (p1.equals(p3) || p1.equals(p4)) {
					return p1;
				}
				if (p2.equals(p3) || p2.equals(p4)) {
					return p2;
				}
			}
		}

		return null;
	}
1316722
public T join() {

        try {
            long spin = 1;
            while (!done) {
                LockSupport.parkNanos(spin++);
            }
            if (completedExceptionally)
                throw new SimpleReactCompletionException(
                                                         exception());
            return result();
        } finally {
            markComplete();
        }
    }
914765
void onJoinStart()
  {
    //long now = CurrentTime.getCurrentTime();
    ArrayList<UpdatePod> updatePods = new ArrayList<>();
    
    updateClusterRoot();

    /*
    for (UpdatePod updatePod : _podUpdateMap.values()) {
      if (updatePod.getSequence() == 0) {
        updatePods.add(new UpdatePod(updatePod, now));
      }
    }
    */
    
    /*
    for (UpdatePod updatePod : updatePods) {
      updatePod(updatePod);
    }
    */
    
    updatePods.addAll(_podUpdateMap.values());
    
    for (UpdatePod updatePod : updatePods) {
      updatePod(updatePod);
    }
    
    // XXX:
  }
716316
public CountDownLatch requestJoin(final long joiningSite) throws Exception {
        final CountDownLatch cdl = new CountDownLatch(1);
        final Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    final long txnId = m_idManager.getNextUniqueTransactionId();

                    for (long initiatorHSId : m_hsIds) {
                        if (initiatorHSId == m_hsId) continue;
                        JSONObject jsObj = new JSONObject();
                        jsObj.put("txnId", txnId);
                        jsObj.put("initiatorHSId", m_hsId);
                        jsObj.put("joiningHSId", joiningSite);
                        jsObj.put("lastSafeTxnId", m_safetyState.getNewestSafeTxnIdForExecutorBySiteId(initiatorHSId));
                        byte payload[] = jsObj.toString(4).getBytes("UTF-8");
                        ByteBuffer metadata = ByteBuffer.allocate(1);
                        metadata.put(BINARY_PAYLOAD_JOIN_REQUEST);
                        BinaryPayloadMessage bpm = new BinaryPayloadMessage(metadata.array(), payload);
                        m_mailbox.send( initiatorHSId, bpm);
                    }

                    m_txnQueue.noteTransactionRecievedAndReturnLastSeen(m_hsId,
                            txnId,
                            m_safetyState.getNewestGloballySafeTxnId());

                    AgreementRejoinTransactionState arts =
                        new AgreementRejoinTransactionState( txnId, m_hsId, joiningSite, cdl );

                    if (!m_txnQueue.add(arts)) {
                        org.voltdb.VoltDB.crashLocalVoltDB("Shouldn't have failed to add txn", true, null);
                    }
                    m_transactionsById.put(arts.txnId, arts);
                } catch (Throwable e) {
                    org.voltdb.VoltDB.crashLocalVoltDB("Error constructing JSON", false, e);
                }
            }
        };
        LocalObjectMessage lom = new LocalObjectMessage(r);
        lom.m_sourceHSId = m_hsId;
        m_mailbox.deliver(lom);
        return cdl;
    }
1125344
private void join(Iterator<RaftMemberContext> iterator) {
    if (iterator.hasNext()) {
      cancelJoinTimer();
      joinTimeout = raft.getThreadContext().schedule(raft.getElectionTimeout().multipliedBy(2), () -> {
        join(iterator);
      });

      RaftMemberContext member = iterator.next();

      log.debug("Attempting to join via {}", member.getMember().memberId());

      JoinRequest request = JoinRequest.builder()
          .withMember(new DefaultRaftMember(getMember().memberId(), getMember().getType(), getMember().getLastUpdated()))
          .build();
      raft.getProtocol().join(member.getMember().memberId(), request).whenCompleteAsync((response, error) -> {
        // Cancel the join timer.
        cancelJoinTimer();

        if (error == null) {
          if (response.status() == RaftResponse.Status.OK) {
            log.debug("Successfully joined via {}", member.getMember().memberId());

            Configuration configuration = new Configuration(response.index(), response.term(), response.timestamp(), response.members());

            // Configure the cluster with the join response.
            // Commit the configuration as we know it was committed via the successful join response.
            configure(configuration).commit();

            // If the local member is not present in the configuration, fail the future.
            if (!members.contains(this.member)) {
              joinFuture.completeExceptionally(new IllegalStateException("not a member of the cluster"));
            } else if (joinFuture != null) {
              joinFuture.complete(null);
            }
          } else if (response.error() == null || response.error().type() == RaftError.Type.CONFIGURATION_ERROR) {
            // If the response error is null, that indicates that no error occurred but the leader was
            // in a state that was incapable of handling the join request. Attempt to join the leader
            // again after an election timeout.
            log.debug("Failed to join {}", member.getMember().memberId());
            resetJoinTimer();
          } else {
            // If the response error was non-null, attempt to join via the next server in the members list.
            log.debug("Failed to join {}", member.getMember().memberId());
            join(iterator);
          }
        } else {
          log.debug("Failed to join {}", member.getMember().memberId());
          join(iterator);
        }
      }, raft.getThreadContext());
    }
    // If join attempts remain, schedule another attempt after two election timeouts. This allows enough time
    // for servers to potentially timeout and elect a leader.
    else {
      log.debug("Failed to join cluster, retrying...");
      resetJoinTimer();
    }
  }
60559
protected final void addEndpoint(Endpoint e) {
        final List<Endpoint> newEndpoints;
        endpointsLock.lock();
        try {
            List<Endpoint> newEndpointsUnsorted = Lists.newArrayList(endpoints);
            newEndpointsUnsorted.add(e);
            endpoints = newEndpoints = ImmutableList.sortedCopyOf(newEndpointsUnsorted);
        } finally {
            endpointsLock.unlock();
        }

        notifyListeners(newEndpoints);
        completeInitialEndpointsFuture(newEndpoints);
    }
1133265
public List<Endpoint> awaitInitialEndpoints() throws InterruptedException {
        try {
            return initialEndpointsFuture.get();
        } catch (ExecutionException e) {
            throw new CompletionException(e.getCause());
        }
    }
916813
private CompletableFuture<CopycatServer> start(Supplier<CompletableFuture<Void>> joiner) {
    if (started)
      return CompletableFuture.completedFuture(this);

    if (openFuture == null) {
      synchronized (this) {
        if (openFuture == null) {
          Function<Void, CompletionStage<CopycatServer>> completionFunction = state -> {
            CompletableFuture<CopycatServer> future = new CompletableFuture<>();
            openFuture = null;
            joiner.get().whenComplete((result, error) -> {
              if (error == null) {
                if (cluster().leader() != null) {
                  started = true;
                  future.complete(this);
                } else {
                  electionListener = cluster().onLeaderElection(leader -> {
                    if (electionListener != null) {
                      started = true;
                      future.complete(this);
                      electionListener.close();
                      electionListener = null;
                    }
                  });
                }
              } else {
                future.completeExceptionally(error);
              }
            });
            return future;
          };

          if (closeFuture == null) {
            openFuture = listen().thenCompose(completionFunction);
          } else {
            openFuture = closeFuture.thenCompose(c -> listen().thenCompose(completionFunction));
          }
        }
      }
    }

    return openFuture.whenComplete((result, error) -> {
      if (error == null) {
        LOGGER.info("Server started successfully!");
      } else {
        LOGGER.warn("Failed to start server!");
      }
    });
  }
677833
public ISynchronizationPoint<Exception> startRootElement() {
		ISynchronizationPoint<Exception> start = start();
		if (start.isUnblocked()) {
			if (start.hasError()) return start;
			if (Type.START_ELEMENT.equals(event.type)) return start;
			return nextStartElement();
		}
		SynchronizationPoint<Exception> sp = new SynchronizationPoint<>();
		start.listenAsync(new ParsingTask(() -> {
			if (Type.START_ELEMENT.equals(event.type)) sp.unblock();
			else nextStartElement().listenInline(sp);
		}), sp);
		return sp;
	}
130886
public synchronized void addToJoinDoNotCancel(ISynchronizationPoint<? extends TError> sp) {
		nbToJoin++;
		sp.listenInline(new Runnable() {
			@Override
			public void run() {
				if (sp.hasError())
					error(sp.getError());
				else
					joined();
			}
		});
		if (Threading.debugSynchronization) ThreadingDebugHelper.registerJoin(this, sp);
	}
1109428
protected void init() {
        // create a synchronisation task which makes sure that the change requested by
        // the internal future has at one time been synchronized to the remote
        synchronisationFuture = GlobalCachedExecutorService.submit(() -> {
            dataProvider.addDataObserver(notifyChangeObserver);
            try {
                dataProvider.waitForData();
                T result = internalFuture.get();
                waitForSynchronization(result);
            } catch (CouldNotPerformException ex) {
                ExceptionPrinter.printHistory("Could not sync with internal future!", ex, logger);
            } finally {
                dataProvider.removeDataObserver(notifyChangeObserver);
            }
            return null;
        });
    }
1080071
public void waitForApproval(boolean isWorkspaceInitialized)
   {

      if (disabled)
      {
         if (LOG.isTraceEnabled())
         {
            LOG.trace("The RepositoryCreationSynchronizer has been disabled so no need to make it wait.");
         }
         return;
      }
      if (rpcService == null)
      {
         if (LOG.isTraceEnabled())
         {
            LOG.trace("No RPCService has been defined so we assume that we are in"
               + " a non cluster environment so no need to make it wait.");
         }
         return;
      }

      // The RPC Service has been defined so we assume that we are in a cluster environment
      if (!isWorkspaceInitialized)
      {
         // Set locally the value
         needToInitWorkspace();
         // A workspace has not been initialized, we need to notify everybody
         if (LOG.isDebugEnabled())
         {
            LOG.debug("Notify all the nodes that there is at least one workspace to initialize.");
         }
         try
         {
            rpcService.executeCommandOnAllNodes(needToInitWorkspaceCommand, false);
         }
         catch (Exception e)
         {
            LOG.warn("Could not notify all the nodes that there is at least one workspace to initialize.", e);
         }
      }
      if (lock.getCount() <= 0)
      {
         // We already have been released so no need to wait
         if (LOG.isTraceEnabled())
         {
            LOG.trace("We already have been released so no need to make it wait.");
         }
         return;
      }
      try
      {
         if (!needToInitWorkspace && isWorkspaceInitialized)
         {
            // Asking the coordinator if we have to wait since the workspace could be currently
            // initialized by the coordinator
            if (LOG.isDebugEnabled())
            {
               LOG.debug("Ask the coordinator if the local node needs to wait.");
            }
            Object result = rpcService.executeCommandOnCoordinator(shouldIWaitCommand, 0);
            if (LOG.isDebugEnabled())
            {
               LOG.debug("The response from the coordinator was " + result);
            }
            if (result instanceof Boolean && (Boolean)result)
            {
               // We wait to be release by the coordinator
               waitForCoordinator();
            }
         }
         else
         {
            // We wait to be release by the coordinator
            waitForCoordinator();
         }
      }
      catch (RPCException e)
      {
         LOG.warn("An error occured while executing the method waitForApproval()", e);
      }
   }
1088235
public static Method getMethodFromTarget(JoinPoint joinPoint) {
        Method method = null;
        if (joinPoint.getSignature() instanceof MethodSignature) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            method = getDeclaredMethod(joinPoint.getTarget().getClass(), signature.getName(),
                    getParameterTypes(joinPoint));
        }
        return method;
    }