United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6427312 (fc) FileChannel.transferTo() throws IOException "system call interrupted"
JDK-6427312 : (fc) FileChannel.transferTo() throws IOException "system call interrupted"

Details
Type:
Bug
Submit Date:
2006-05-18
Status:
Closed
Updated Date:
2011-05-18
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
core-libs
OS:
linux
Sub-Component:
java.nio
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:

Related Reports
Backport:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux c001n01 2.6.5-SLES9-SP2-62670d15449ecdfe8084f3f4aa6e38ac #1 SMP Thu Mar 16 09:28:14 EST 2006 i686 i686 i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
On Linux, FileChannel.transferTo() occasionally throws a "java.io.IOException: Interrupted system call".

The reason seems to be that the linux implementation of sun.nio.ch.FileChannelImpl.transferTo0() does not handle -EINTR return values from the sendfile() system call correctly.

Proposed solution: when sendfile() returns a negative value, check whether offset was incremented. If it was, return the delta (i.e.: the nr of bytes transferred) instead of throwing an exception. This allows the client to resume the transfer from the new position.

The Solaris implementation handles this case correctly.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Repeatedly transfer a large file (100MB or larger) to a blocking NIO socket using FileChannel.transferTo(). Eventually, the sendfile() system call will be interrupted and an IOException will be thrown.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When interrupted, sun.nio.ch.FileChannelImpl.transferTo0() should return the actual nr of bytes transferred (can be 0) instead of throwing an IOException.

Throwing the exception leaves no option to recover since information about the nr of bytes already transferred is lost.

ACTUAL -
FileChannel.transferTo() threw the exception below.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.io.IOException: Interrupted system call
        at sun.nio.ch.FileChannelImpl.transferTo0(Native Method)
        at sun.nio.ch.FileChannelImpl.transferToDirectly(Unknown Source)
        at sun.nio.ch.FileChannelImpl.transferTo(Unknown Source)
        at com.emc.centera.library.io.transfer.TransferChannelAdaptor.doTransfer(TransferChannelAdaptor.java:94)


REPRODUCIBILITY :
This bug can be reproduced often.

CUSTOMER SUBMITTED WORKAROUND :
The only workaround is to replace FileChannel.transferTo() calls by code that does explicit FileChannel.read() and SocketChannel.write() calls.

This results in a significant performance degradation.

                                    

Comments
EVALUATION

Yes, we need to fix this. The original man pages for sendfile(2) didn't document EINTR but the updated pages suggest it can only be interrupted before any data is transmitted - we need to verify this and if true, retry the sendfile as we do with other interrupted calls.
                                     
2006-05-18



Hardware and Software, Engineered to Work Together