Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Nov 2001 13:07:17 -0400
From:      "Jeroen C. van Gelderen" <jeroen@vangelderen.org>
To:        FreeBSD Java <freebsd-java@FreeBSD.ORG>
Subject:   JVM blocks on /dev/random?
Message-ID:  <3BED5EC5.4060405@vangelderen.org>

next in thread | raw e-mail | index | archive | help
Hi All,

I seem to have run into an irritating little problem concerning
the (very latest) jdk12-beta port and the /dev/random device on
(week-old) -STABLE.

As you know, the /dev/random device, when read, delivers random
numbers until it runs out, in which case it will return EAGAIN
(in the non-blocking case) so you can wait and try again (or poll
and get notified) at a later time.

With the JDK 1.2 however, reading from /dev/random is peachy until
it runs out of randomness. The read call then returns EAGAIN, the
Java thread blocks and... never wakes up, despite the fact that
randomness has become available.

Below you will find a little program that demonstrates the problem
when run with 'java_g -Xl9'. The output looks somewhat like this:

[...]
open(/dev/random) fd: 7
Activating fd=7 onto slot=4
Made 7 nonblocking
Read for 1 bytes finished (did not block) on fd: 7
[...]
Read for 1 bytes finished (did not block) on fd: 7
Read sez 35, str: Resource temporarily unavailable
Read for -1 bytes going to block on fd: 7
   NO need for fifo hack on fd: 7
   -false: 2nd read for -1 bytes finished on fd: 7
    false: 2nd read sez 35, str: Resource temporarily unavailable
   errno is EAGAIN!
queueWait: sys_thread_t 0x8051080 q 0x804c298 mid 0x804c280
queueWait: CONDVAR_WAIT
queueSignal: mid 0x804c280 q 0x804c290 sys_thread_t 0x8051080
queueSignal: no waiter, set no monitor owner
reschedule: from TID 0x8051080 to TID 0x8051480
<hangs>

Okay, not precisely, the indented six lines are written by my own
trace statements inserted in java_g but as you can see the thing
reads until read(2) returns EAGAIN upon which the thread blocks (on
sysMonitorWait in iomgr.c's read function), never to wake up again.

In src/freebsd/hpi/green_threads/src/iomgr.c the read funtion blocks
on the following statement:
  if (sysMonitorWait(self, mon, SYS_TIMEOUT_INFINITY) == SYS_INTRPT) {
when I change that to
  if (sysMonitorWait(self, mon, 1000) == SYS_INTRPT) {
the program of course works with a ~1000ms delay, showing that more
randomness is indeed available.

Digging around a bit more seems to indicate that the JVM does not
receive a SIGIO as I would expect but by now it is getting hairy
and it seems time to ask the experts...

So, does anybody have any idea on how to tackle this problem? :)

TIA,
Jeroen

------8<------8<------8<------8<------8<------8<------8<------8<------8<

import java.io.*;

public class Test {

   private static char[] NIBBLE2HEX = {
     '0', '1', '2', '3', '4', '5', '6', '7',
     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
   };

   public static void main(String[] argv) throws Exception {
     File dr = new File("/dev/random");
     FileInputStream fis = new FileInputStream(dr);
     while(true) {
       int b = fis.read();
       if( b == -1 )
         throw new Exception("-1: EOF");
     }
   }
}

-- 
Jeroen C. van Gelderen -- jeroen@vangelderen.org

An eye for an eye only ends up making the whole world blind. -- Gandhi


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-java" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3BED5EC5.4060405>