You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by "Mikhail Markov (JIRA)" <ji...@apache.org> on 2007/05/15 12:21:16 UTC

[jira] Updated: (HARMONY-3785) [classlib][nio] FileChannel.transferFrom[To] methods throw unexpected IOException

     [ https://issues.apache.org/jira/browse/HARMONY-3785?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Mikhail Markov updated HARMONY-3785:
------------------------------------

    Attachment: H-3785.patch

Here is the patch fixing the issue.

Fix description: the RuntimeMemorySpy.allocate() method 1) allocates the memory (i.e. add PlatformAddress to the hash map of memory which is in use and GC references table) 2) and after that frees the memory from pending requests. Sometimes the queue to be processed in 2-nd step contains pending requests of freeing from previous allocations of the same PlatformAddress. So if we put new PlatformAddress object representing the same address to the hash map of used memory in 1-st step, 2-nd step will find it and tries to fix it which will result in "Memory Spy! Fixed memory leak by freeing PlatformAddress[...]" messages and newly allocated memory freeing. So the patch swaps these 2 steps, so the queue cleanup is done before new address allocation.


> [classlib][nio] FileChannel.transferFrom[To] methods throw unexpected IOException
> ---------------------------------------------------------------------------------
>
>                 Key: HARMONY-3785
>                 URL: https://issues.apache.org/jira/browse/HARMONY-3785
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows and Linux
>            Reporter: Vera Petrashkova
>         Attachments: H-3785.patch
>
>
> When FileChannel.transferFrom[To] methods are invoked in several threads and they try to read from the same file
> then these methods throw unexpected IOException.
> IOException is also thrown by these methods when one thread which invokes transfer methods and is created and started several times.
> To reproduce this bug run the following test:
> ------------------test.java------------
> import java.io.*;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class test extends Thread{
>      static int nThreads = 10;
>      static int nIters = 100;
>      static volatile boolean passed = true;
>      FileChannel from = null;
>      FileChannel to = null;
>      public static void main(String[] args) {
>          int fail = 0;
>          if (args.length >= 1) {
>              try {
>                  nThreads = Integer.parseInt(args[0]);
>              } catch (Throwable e) {
>              }
>          }
>          if (args.length >= 2) {
>              try {
>                  nIters = Integer.parseInt(args[1]);
>              } catch (Throwable e) {
>              }
>          }
>          for (int i = 0; i < nIters; i++) {
>             if (new test().test(i) != 104) {
>                 fail ++;
>             }
>          }
>          if (fail == 0) {
>              System.err.println("Test passed");
>          }
>      }
>      public int test(int step) {
>          File f_from = null;
>          passed = true;
>          try {
>              f_from = new File("test.java");
>              copy(f_from);
>              if (!passed) {
>                  System.err.println("Step: "+ step+" Test failed");
>                  return 105;
>              }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             System.err.println("Step: "+ step+" Exception thrown: " + t);
>             return 105;
>         }
>         return 104;
>     }
>     public void copy(File f_from) throws Exception {
>         Thread[] t = new Thread[nThreads];
>         File[] f_to = new File[nThreads];
>         FileChannel[] outChannels = new FileChannel[nThreads];
>         FileChannel inChannel = null;
>         try {
>             inChannel = new FileInputStream(f_from).getChannel();
>             for (int i = 0; i < t.length; ++i) {
>                 f_to[i] = new File(f_from.getAbsolutePath() + "_copy_" + i);
>                 outChannels[i] = new FileOutputStream(f_to[i]).getChannel();
>                 t[i] = new test("" + i, inChannel, outChannels[i]);
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }                               
>         } catch (Throwable tr) {
>             tr.printStackTrace();
>             System.err.println("Exception thrown: " + tr);
>             passed = false;
>         } finally {
>             if (inChannel != null){
>                 inChannel.close();
>             }
>             for (int i = 0; i < outChannels.length; ++i) {
>                 if (outChannels[i] != null) {
>                     outChannels[i].close();
>                 }
>                 if (f_to[i] != null) {
>                     f_to[i].delete();
>                 }
>             }
>         }
>         return;
>     }
>     test (String id, FileChannel from, FileChannel to) {
>         super(id);
>         this.from = from;
>         this.to = to;
>     }
>     test () {
>         super();
>     }
>     public void run()  {
>         long size = 0l;
>         long size1 = 0l;
>         long transfered = 0l;
>         long sz = 0l;
>         try {
>             synchronized (from) {
>                 Thread.yield();
>                 from.position(0); 
>                 size = from.size() / 4; 
>                 size1 = from.size()  - size; 
>                 sz = size;
>                 Thread.yield();
>                 transfered = to.transferFrom(from, 0, sz);
>                 if (transfered != sz) {
>                     System.err.println("Thread " + this.getName() + ": transferFrom transfered " + 
>                                   transfered + " bytes, instead of expected " + sz + " bytes");
>                     passed = false;
>    
>                 }
>                 transfered = 0;
>                 sz = size1;
>                 to.force(false);
>                 to.position(size);
>                 transfered = from.transferTo(size, sz, to);
>                 if (transfered != size1) {
>                     System.err.println("Thread " + this.getName() + ": transferTo transfered " + 
>                                  transfered + " bytes, instead of expected " + sz + " bytes ");
>                     passed = false;
>    
>                 }
>                 to.force(false);
>             }
>         } catch (Exception e) {
>             e.printStackTrace();
>             System.err.println("Thread " + this + ": " + e 
>                     + " while transferFrom/To() operation"+"  size: "
>                     + sz+"  transfered: "+transfered +"  "//);
>                                + from+"  "+to);
>             passed = false;
>         }
>     }
> }
> ------------------------
> Run test creating  several threads or one thread
> java test 10
> java test 1 1000
> Test passes on RI in both cases but it fails on Harmony.
> Output for one thread is:
> ===================
> Apache Harmony Launcher : (c) Copyright 1991, 2006 The Apache Software Foundation or its l
> icensors, as applicable.
> java version "1.5.0"
> pre-alpha : not complete or compatible
> svn = r532358, (Apr 25 2007), Windows/ia32/msvc 1310, debug build
> http://incubator.apache.org/harmony
> Memory Spy! Fixed memory leak by freeing PlatformAddress[57540608]
> Memory Spy! Fixed attempt to free memory that was not allocated PlatformAddress[57540608]
> java.io.IOException
>         at org.apache.harmony.luni.platform.OSFileSystem.writeDirect(OSFileSystem.java:134)
>         at org.apache.harmony.nio.internal.FileChannelImpl.writeImpl(FileChannelImpl.java:548)
>         at org.apache.harmony.nio.internal.FileChannelImpl.write(FileChannelImpl.java:524)
>         at org.apache.harmony.nio.internal.FileChannelImpl.transferFrom(FileChannelImpl.java:419)
>         at test.run(test.java:124)
> Thread Thread[5,5,main]: java.io.IOException while transferFrom/To() operation  size: 1182 transfered: 0  
> org.apache.harmony.nio.internal.ReadOnlyFileChannel@14  org.apache.harmony.nio.internal.WriteOnlyFileChannel@dc
> Step: 63 Test failed
> Output for onr thread is:
> Apache Harmony Launcher : (c) Copyright 1991, 2006 The Apache Software Foundation or its licensors, as applicable.
> java version "1.5.0" 
> pre-alpha : not complete or compatible
> svn = r532358, (Apr 25 2007), Linux/ia32/gcc 3.3.3, release build
> http://incubator.apache.org/harmony
> Memory Spy! Fixed memory leak by freeing PlatformAddress[2118897664]
> Memory Spy! Fixed attempt to free memory that was not allocated PlatformAddress[2118897664]
> java.io.IOException
>         at org.apache.harmony.luni.platform.OSFileSystem.writeDirect(Unknown Source)
>         at org.apache.harmony.nio.internal.FileChannelImpl.writeImpl(Unknown Source)
>         at org.apache.harmony.nio.internal.FileChannelImpl.write(Unknown Source)
>         at org.apache.harmony.nio.internal.FileChannelImpl.transferFrom(Unknown Source)
>         at test.run(test.java:124)
> Thread Thread[0,5,main]: java.io.IOException while transferFrom/To() operation  size: 1182  transfered: 0  
> org.apache.harmony.nio.internal.ReadOnlyFileChannel@b0  org.apache.harmony.nio.internal.WriteOnlyFileChannel@138
> Step: 349 Test failed
> Memory Spy! Fixed memory leak by freeing PlatformAddress[2120998912]
> Memory Spy! Fixed attempt to free memory that was not allocated PlatformAddress[2120998912]
> java.io.IOException
>         at org.apache.harmony.luni.platform.OSFileSystem.writeDirect(Unknown Source)
>         at org.apache.harmony.nio.internal.FileChannelImpl.writeImpl(Unknown Source)
>         at org.apache.harmony.nio.internal.FileChannelImpl.write(Unknown Source)
>         at org.apache.harmony.nio.internal.FileChannelImpl.transferFrom(Unknown Source)
>         at test.run(test.java:124)
> Thread Thread[0,5,main]: java.io.IOException while transferFrom/To() operation  size: 1182  transfered: 0  
> org.apache.harmony.nio.internal.ReadOnlyFileChannel@b0  org.apache.harmony.nio.internal.WriteOnlyFileChannel@138
> Step: 699 Test failed

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.