JDK-6604107 : PrintServiceLookup.lookupPrintServices is not thread-safe
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2007-09-13
  • Updated: 2011-02-16
  • Resolved: 2009-07-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0u21Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux firenze 2.4.21-32.ELsmp #1 SMP Fri Apr 15 21:17:59 EDT 2005 i686 i686 i386 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
CUPS with a couple of printers (I used 4 printers to reproduce this, but in production we have something like 70 printers)

A DESCRIPTION OF THE PROBLEM :
The method PrintServiceLookup.lookupPrintServices is not thread-safe on Linux. It either causes threads to hang or it causes a VM crash due to a race-condition in  an OpenSSL call.

This is fixed in JDK-1.6, but it is still a major bug in 1-5, which should be fixed there (even if just synchronizing the call on Linux).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Call PrintServiceLookup.lookupPrintServices from multiple threads.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
PrintServiceLookup.lookupPrintServices should be thread-safe.
ACTUAL -
VM crashes in OpenSSL call or PrintServiceLookup.lookupPrintServices hangs.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Stack of hung threads:

Thread 30235: (state = IN_NATIVE)
 - sun.print.CUPSPrinter.canConnect(java.lang.String, int) @bci=0 (Interpreted frame)
 - sun.print.CUPSPrinter.isCupsRunning() @bci=71, line=352 (Interpreted frame)
 - sun.print.UnixPrintServiceLookup.getPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=125, line=351 (Interpreted frame)
 - javax.print.PrintServiceLookup.getServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=65, line=359 (Interpreted frame)
 - javax.print.PrintServiceLookup.lookupPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=2, line=105 (Interpreted frame)
 - Test$Job.run() @bci=42, line=42 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=595 (Interpreted frame)


Thread 30220: (state = IN_NATIVE)
 - sun.print.CUPSPrinter.canConnect(java.lang.String, int) @bci=0 (Interpreted frame)
 - sun.print.CUPSPrinter.isCupsRunning() @bci=71, line=352 (Interpreted frame)
 - sun.print.UnixPrintServiceLookup.getPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=125, line=351 (Interpreted frame)
 - javax.print.PrintServiceLookup.getServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=65, line=359 (Interpreted frame)
 - javax.print.PrintServiceLookup.lookupPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=2, line=105 (Interpreted frame)
 - Test$Job.run() @bci=42, line=42 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=595 (Interpreted frame)



Dump of crash in OpenSSL:
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  SIGSEGV (0xb) at pc=0x66c0bbda, pid=31106, tid=1745222576
#
# Java VM: Java HotSpot(TM) Server VM (1.5.0_12-b04 mixed mode)
# Problematic frame:
# C  [libcrypto.so.4+0x73bda]
#
d, id=31112]

Other Threads:
  0x08111300 VMThread [id=31111]
  0x0806dda8 WatcherThread [id=31119]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
 PSYoungGen      total 21952K, used 19948K [0xa9aa0000, 0xab080000, 0xb09b0000)
  eden space 21696K, 90% used [0xa9aa0000,0xaaddd100,0xaafd0000)
  from space 256K, 96% used [0xab020000,0xab05e050,0xab060000)
  to   space 320K, 0% used [0xaafd0000,0xaafd0000,0xab020000)
 PSOldGen        total 56896K, used 0K [0x721b0000, 0x75940000, 0xa9aa0000)
  object space 56896K, 0% used [0x721b0000,0x721b0000,0x75940000)
 PSPermGen       total 16384K, used 2336K [0x6e1b0000, 0x6f1b0000, 0x721b0000)
  object space 16384K, 14% used [0x6e1b0000,0x6e3f83

---------------  S Y S T E M  ---------------

OS:Red Hat Enterprise Linux ES release 3 (Taroon Update 5)

uname:Linux 2.4.21-32.ELsmp #1 SMP Fri Apr 15 21:17:59 EDT 2005 i686
libc:glibc 2.3.2 NPTL 0.60
rlimit: STACK 10240k, CORE 0k, NPROC 16384, NOFILE 65536, AS infinity
load average:0.46 0.60 0.31

CPU:total 4 (cores per cpu 1, threads per core 2) family 15 model 4 stepping 3, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ht

Memory: 4k page, physical 4093444k(35696k free), swap 2000k(1810k free)

vm_info: Java HotSpot(TM) Server VM (1.5.0_12-b04) for linux-x86, built on May  2 2007 02:13:16 by java_re with gcc 3.2.1-7a (J2SE release)



REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;

/**
 * On JDK-1.5.0_12 on Linux x86 this test case hangs or crashes.
 *
 * @author Ortwin Gl��ck
 */
public class Test implements Runnable{
    Object latch = new Object();
    
    public static void main(String[] args) {
        Test app = new Test();
        app.run();
    }

    public void run() {
        int THREADS = 200;
        for (int i=0; i<THREADS; i++) {
            Thread t = new Thread(new Job());
            t.setDaemon(false);
            t.start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        
        synchronized (latch) {
            latch.notifyAll();
        }
        
    }
    
    private class Job implements Runnable {

        public void run() {
            synchronized (latch) {
                try {
                    latch.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            PrintService[] services = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
            System.out.println(services.length);
        }
        
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Synchronize calls to PrintServiceLookup.lookupPrintServices().
  Fixed in JDK-1.6.