Skip to content

Commit

Permalink
Use SecureRandom.generateSeed() to generate ThreadLocalRandom's initi…
Browse files Browse the repository at this point in the history
…alSeedUniquifier

Motivation:

Previously, we used SecureRandom.nextLong() to generate the initialSeedUniquifier.  This required more entrophy than necessary because it has to 1) generate the seed of SecureRandom first and then 2) generate a random long integer.  Instead, we can use generateSeed() to skip the step (2)

Modifications:

Use generateSeed() instead of nextLong()

Result:

ThreadLocalRandom requires less amount of entrphy to start up
  • Loading branch information
trustin committed Mar 21, 2014
1 parent d641b6a commit fe279d3
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions common/src/main/java/io/netty/util/internal/ThreadLocalRandom.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ public static synchronized long getInitialSeedUniquifier() {
if (initialSeedUniquifier == 0) {
// Try to generate a real random number from /dev/random.
// Get from a different thread to avoid blocking indefinitely on a machine without much entrophy.
final BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>();
final BlockingQueue<byte[]> queue = new LinkedBlockingQueue<byte[]>();
Thread generatorThread = new Thread("initialSeedUniquifierGenerator") {
@Override
public void run() {
SecureRandom random = new SecureRandom(); // Get the real random seed from /dev/random
queue.add(random.nextLong());
queue.add(random.generateSeed(8));
}
};
generatorThread.start();
Expand All @@ -99,15 +99,23 @@ public void run() {
long waitTime = deadLine - System.nanoTime();
if (waitTime <= 0) {
logger.warn(
"Failed to get the secure random number from SecureRandom within {} seconds. " +
"Failed to generate a seed from SecureRandom within {} seconds. " +
"Not enough entrophy?", timeoutSeconds);
break;
}

try {
Long result = queue.poll(waitTime, TimeUnit.NANOSECONDS);
if (result != null) {
initialSeedUniquifier = result;
byte[] seed = queue.poll(waitTime, TimeUnit.NANOSECONDS);
if (seed != null) {
initialSeedUniquifier =
((long) seed[0] & 0xff) << 56 |
((long) seed[1] & 0xff) << 48 |
((long) seed[2] & 0xff) << 40 |
((long) seed[3] & 0xff) << 32 |
((long) seed[4] & 0xff) << 24 |
((long) seed[5] & 0xff) << 16 |
((long) seed[6] & 0xff) << 8 |
(long) seed[7] & 0xff;
break;
}
} catch (InterruptedException e) {
Expand Down

0 comments on commit fe279d3

Please sign in to comment.