<commit_before>// Copyright (c) 1999 <NAME> (<EMAIL>)
// Portions Copyright (c) 1999 Network Associates, Inc.

package org.xbill.DNS;

import java.util.*;
import java.io.*;
import java.net.*;
import org.xbill.Task.*;

/**
 * An implementation of Resolver that can send queries to multiple servers,
 * sending the queries multiple times if necessary.
 * @see Resolver
 *
 * @author <NAME>
 */

public class ExtendedResolver implements Resolver {

private static class Resolution implements ResolverListener {
	Resolver [] resolvers;
	int [] sent;
	Object [] inprogress;
	int retries;
	int outstanding;
	boolean done;
	Message query;
	Message response;
	Exception exception;
	ResolverListener listener;

	public
	Resolution(ExtendedResolver eres, Message query) {
		List l = eres.resolvers;
		resolvers = (Resolver []) l.toArray (new Resolver[l.size()]);
		if (eres.loadBalance) {
			int nresolvers = resolvers.length;
			/*
			 * Note: this is not synchronized, since the
			 * worst thing that can happen is a random
			 * ordering, which is ok.
			 */
			int start = eres.lbStart++ % nresolvers;
			if (eres.lbStart > nresolvers)
				eres.lbStart %= nresolvers;
			if (start > 0) {
				Resolver [] shuffle = new Resolver[nresolvers];
				for (int i = 0; i <= start; i++)
					shuffle[i + start] = resolvers[i];
				for (int i = start; i < nresolvers; i++)
					shuffle[i - start] = resolvers[i];
				resolvers = shuffle;
			}
		}
		sent = new int[resolvers.length];
		inprogress = new Object[resolvers.length];
		retries = eres.retries;
		this.query = query;
	}

	public void
	send(int n) {
		sent[n]++;
		outstanding++;
		inprogress[n] = resolvers[n].sendAsync(query, this);
	}

	public Message
	start() throws IOException {
		send(0);
		synchronized (this) {
			while (!done) {
				try {
					wait();
				}
				catch (InterruptedException e) {
				}
			}
		}
		if (response != null)
			return response;
		else if (exception instanceof IOException)
			throw (IOException) exception;
		else if (exception instanceof RuntimeException)
			throw (RuntimeException) exception;
		else
			throw new RuntimeException("ExtendedResolver failure");
	}

	public void
	startAsync(ResolverListener listener) {
		this.listener = listener;
		send(0);
	}

	public void
	receiveMessage(Object id, Message m) {
		if (Options.check("verbose"))
			System.err.println("ExtendedResolver: " +
					   "received message " + id);
		synchronized (this) {
			if (done)
				return;
			response = m;
			done = true;
			if (listener == null)
				notifyAll();
			else
				listener.receiveMessage(this, response);
		}
	}

	public void
	handleException(Object id, Exception e) {
		if (Options.check("verbose"))
			System.err.println("ExtendedResolver: " +
					   "exception on message " + id);
		synchronized (this) {
			outstanding--;
			if (done)
				return;
			int n;
			for (n = 0; n < inprogress.length; n++)
				if (inprogress[n] == id)
					break;
			if (n == inprogress.length)
				return;
			boolean startnext = false;
			boolean waiting = false;
			if (sent[n] == 1 && n < resolvers.length - 1)
				startnext = true;
			if (e instanceof InterruptedIOException) {
				/* Got a timeout; retry */
				if (sent[n] < retries)
					send(n);
				if (exception == null)
					exception = e;
			} else if (e instanceof SocketException) {
				if (exception == null ||
				    exception instanceof InterruptedIOException)
					exception = e;
			} else {
				exception = e;
			}
			if (startnext)
				send(n + 1);
			if (outstanding == 0) {
				done = true;
				if (listener == null)
					notifyAll();
				else
					listener.handleException(this,
								 exception);
			}
		}
	}
}

private static final int quantum = 5;
<commit_msg>Avoid race conditions.<commit_after>// Copyright (c) 1999 <NAME> (<EMAIL>)
// Portions Copyright (c) 1999 Network Associates, Inc.

package org.xbill.DNS;

import java.util.*;
import java.io.*;
import java.net.*;
import org.xbill.Task.*;

/**
 * An implementation of Resolver that can send queries to multiple servers,
 * sending the queries multiple times if necessary.
 * @see Resolver
 *
 * @author <NAME>
 */

public class ExtendedResolver implements Resolver {

private static class Resolution implements ResolverListener {
	Resolver [] resolvers;
	int [] sent;
	Object [] inprogress;
	int retries;
	int outstanding;
	boolean done;
	Message query;
	Message response;
	Exception exception;
	ResolverListener listener;

	public
	Resolution(ExtendedResolver eres, Message query) {
		List l = eres.resolvers;
		resolvers = (Resolver []) l.toArray (new Resolver[l.size()]);
		if (eres.loadBalance) {
			int nresolvers = resolvers.length;
			/*
			 * Note: this is not synchronized, since the
			 * worst thing that can happen is a random
			 * ordering, which is ok.
			 */
			int start = eres.lbStart++ % nresolvers;
			if (eres.lbStart > nresolvers)
				eres.lbStart %= nresolvers;
			if (start > 0) {
				Resolver [] shuffle = new Resolver[nresolvers];
				for (int i = 0; i <= start; i++)
					shuffle[i + start] = resolvers[i];
				for (int i = start; i < nresolvers; i++)
					shuffle[i - start] = resolvers[i];
				resolvers = shuffle;
			}
		}
		sent = new int[resolvers.length];
		inprogress = new Object[resolvers.length];
		retries = eres.retries;
		this.query = query;
	}

	public void
	send(int n) {
		sent[n]++;
		outstanding++;
		inprogress[n] = resolvers[n].sendAsync(query, this);
	}

	public Message
	start() throws IOException {
		send(0);
		synchronized (this) {
			while (!done) {
				try {
					wait();
				}
				catch (InterruptedException e) {
				}
			}
		}
		if (response != null)
			return response;
		else if (exception instanceof IOException)
			throw (IOException) exception;
		else if (exception instanceof RuntimeException)
			throw (RuntimeException) exception;
		else
			throw new RuntimeException("ExtendedResolver failure");
	}

	public void
	startAsync(ResolverListener listener) {
		this.listener = listener;
		send(0);
	}

	public void
	receiveMessage(Object id, Message m) {
		if (Options.check("verbose"))
			System.err.println("ExtendedResolver: " +
					   "received message " + id);
		synchronized (this) {
			if (done)
				return;
			response = m;
			done = true;
			if (listener == null) {
				notifyAll();
				return;
			}
		}
		listener.receiveMessage(this, response);
	}

	public void
	handleException(Object id, Exception e) {
		if (Options.check("verbose"))
			System.err.println("ExtendedResolver: " +
					   "exception on message " + id);
		synchronized (this) {
			outstanding--;
			if (done)
				return;
			int n;
			for (n = 0; n < inprogress.length; n++)
				if (inprogress[n] == id)
					break;
			if (n == inprogress.length)
				return;
			boolean startnext = false;
			boolean waiting = false;
			if (sent[n] == 1 && n < resolvers.length - 1)
				startnext = true;
			if (e instanceof InterruptedIOException) {
				/* Got a timeout; retry */
				if (sent[n] < retries)
					send(n);
				if (exception == null)
					exception = e;
			} else if (e instanceof SocketException) {
				if (exception == null ||
				    exception instanceof InterruptedIOException)
					exception = e;
			} else {
				exception = e;
			}
			if (startnext)
				send(n + 1);
			if (outstanding == 0) {
				done = true;
				if (listener == null) {
					notifyAll();
					return;
				}
			}
			if (!done)
				return;
		}
		listener.handleException(this, exception);
	}
}

private static final int quantum = 5;

{'fraction_non_alphanumeric': 0.12348830959419511, 'fraction_numerical': 0.004837409298575652, 'mean_word_length': 3.038524145415084, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2473675', 'n_tokens_mistral': 2922, 'n_tokens_neox': 2372, 'n_words': 705}