You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by "Vera Petrashkova (JIRA)" <ji...@apache.org> on 2007/06/07 07:13:26 UTC

[jira] Created: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

[classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
---------------------------------------------------------------------------

                 Key: HARMONY-4081
                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
             Project: Harmony
          Issue Type: Bug
          Components: Classlib
         Environment: Windows
            Reporter: Vera Petrashkova
            Priority: Minor


According to J2SE specification
"File channels are safe for use by multiple concurrent threads."

But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
some threads try to write bytes to the same channel.

Not all data are written to the file.
---------------fchTest.java---------------
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;

public class fchTest {
        
    public static int N_TH = 20;
    public static final int BUF_SIZE = 2000;
    public static final int N_BUF = 20;
    public static final int N_WRITES = 20;

    boolean passed = true;
  
    String fileName = "FileChannel.file";
    FileChannel outChannel = null;
    FileChannel inChannel = null;

    public static void main(String[] args) {
        try {
             if (args.length > 0) {
                N_TH = Integer.parseInt(args[0]);
            }
        } catch (Throwable e) {
        }    
        int res = new fchTest().test(args);
        System.err.println(res == 104 ? "Test passed" : "Test failed");          
    }
    public int test(String[] params) {
        File f = null;
        passed = true;
        try {
            f = new File(fileName);
            if (f.exists()) {
                f.delete();
            }
            outChannel = new FileOutputStream(f).getChannel();
            inChannel = new FileInputStream(f).getChannel();

            Thread[] t = new Thread[N_TH];
            for (int i = 0; i < t.length; ++i) {
                t[i] = new thWriter(this); 
                t[i].start();
            }

            for (int i = 0; i < t.length; ++i) {
                t[i].join();
            }
        } catch (Throwable t) {
            t.printStackTrace();
            return 105;
        } finally {
            try {
                if (outChannel != null){
                    outChannel.close();
                }
                if (inChannel != null){
                    inChannel.close();
                }                    
            } catch (Throwable t){
                t.printStackTrace();
            }
            if (f != null){
                f.delete();
            }
        }
        return (passed ? 104 : 106);
    }

}
class thWriter extends Thread {
    FileChannel outChannel = null;
    fchTest base = null;
    
    thWriter(fchTest base) {
        this.outChannel = base.outChannel;
        this.base = base;
    }

public void run () {
        try {
            long allW = 0;
            long allC = 0;
            for (int i = 0; i < fchTest.N_WRITES; ++i) {
                ByteBuffer[] bbb = createByteChunks();
                for (int t = 0; t < bbb.length; t++)  {
                    allC += bbb[i].capacity();
                }
                long written = outChannel.write(bbb);
                if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
                    System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
                    base.passed = false;
                }
                allW+=written;
                Thread.yield();
                Thread.sleep(10);
            }
            System.err.println(this+" - after write: "+allW+"  "+allC);
            if (allW != allC) {
                base.passed = false;
            }
            outChannel.force(false);

        } catch (Throwable e){
            System.err.println(this+" unexpected exception " + e);
            e.printStackTrace();
            base.passed = false;
        }
    }

    ByteBuffer[] createByteChunks() {
        ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
        byte [] bb = new byte[fchTest.BUF_SIZE];    
        for (int i = 0; i < bb.length; i++) {
            bb[i] = (byte)i;
        }
        for (int i = 0; i < bb_arr.length; ++i) {
            bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
        }       
        return bb_arr;
    }
}
----------------------------------------------------
Run this test several times and change the number of created threads
java fchTest
java fchTest 30

Output on RI:
==============
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)

Thread[Thread-1,5,main] - after write: 800000  800000
Thread[Thread-11,5,main] - after write: 800000  800000
Thread[Thread-19,5,main] - after write: 800000  800000
Thread[Thread-17,5,main] - after write: 800000  800000
Thread[Thread-9,5,main] - after write: 800000  800000
Thread[Thread-13,5,main] - after write: 800000  800000
Thread[Thread-15,5,main] - after write: 800000  800000
Thread[Thread-7,5,main] - after write: 800000  800000
Thread[Thread-3,5,main] - after write: 800000  800000
Thread[Thread-0,5,main] - after write: 800000  800000
Thread[Thread-5,5,main] - after write: 800000  800000
Thread[Thread-16,5,main] - after write: 800000  800000
Thread[Thread-6,5,main] - after write: 800000  800000
Thread[Thread-12,5,main] - after write: 800000  800000
Thread[Thread-2,5,main] - after write: 800000  800000
Thread[Thread-8,5,main] - after write: 800000  800000
Thread[Thread-10,5,main] - after write: 800000  800000
Thread[Thread-4,5,main] - after write: 800000  800000
Thread[Thread-14,5,main] - after write: 800000  800000
Thread[Thread-18,5,main] - after write: 800000  800000
Test passed


Output on DRLVM:
==============
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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
http://harmony.apache.org
The GC did not provide gc_add_weak_root_set_entry()
Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
Thread[Thread-20,5,main] - after write: 800000  800000
Thread[Thread-16,5,main] - after write: 800000  800000
Thread[Thread-8,5,main] - after write: 800000  800000
Thread[Thread-12,5,main] - after write: 800000  800000
Thread[Thread-22,5,main] - after write: 800000  800000
Thread[Thread-14,5,main] - after write: 800000  800000
Thread[Thread-18,5,main] - after write: 800000  800000
Thread[Thread-23,5,main] - after write: 800000  800000
Thread[Thread-11,5,main] - after write: 800000  800000
Thread[Thread-10,5,main] - after write: 800000  800000
Thread[Thread-24,5,main] - after write: 800000  800000
Thread[Thread-7,5,main] - after write: 800000  800000
Thread[Thread-15,5,main] - after write: 800000  800000
Thread[Thread-9,5,main] - after write: 793100  800000
Thread[Thread-6,5,main] - after write: 800000  800000
Thread[Thread-25,5,main] - after write: 800000  800000
Thread[Thread-17,5,main] - after write: 800000  800000
Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
Thread[Thread-19,5,main] - after write: 800000  800000
Thread[Thread-13,5,main] - after write: 797700  800000
Thread[Thread-21,5,main] - after write: 800000  800000
Test failed

This bug causes the failure of the test
    api.nio.channels.filechannel.FileChannelThrSafetyTest
from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918


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


[jira] Commented: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Mikhail Markov (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12520216 ] 

Mikhail Markov commented on HARMONY-4081:
-----------------------------------------

Paulex,

Thanks for the patch review!

In the beginning, i've created the patch withouth MappedPlatformAddress and AbstractMemorySpy modifications, but this lead to exceptions. Seems like after explicit temporary buffers freeing at the end of FileChannelImpl.write() method, another attempt to free the same resources is made in RuntimeMemorySpy.alloc() method.

About MappedPlatformAddress modification: yes - on Linux it's as you described, but unfortunately on Windows UnmapViewOfFile function is used, which does not physically free the memory.

About AbstractMemorySpy modification: the modification is related to the one in MappedPlatformAddress. Usually, the following construction is used for resources explicit freeing:
        if(memorySpy.free(this)){
            osMemory.free(osaddr);
        }
i.e. after removing the address from memoryInUse, physical freeing happens - in this case. The only place where this was not so is MappedPlatformAddress (at least for Windows), so after i added explicit memory freeing in MappedPlatformAddress, the address could be safely removed from refToShadow.
You're right - is this case the mechanizm of auto-freeing is not necessary.
I did not found places where free() method explicity used except  *PlatformAddress classes. Do you know any?
If not then do we really need this mechanizm if all physical freeing is done in *PlatformAddress classes?

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Assignee: Alexei Zakharov
>            Priority: Minor
>         Attachments: H-4081_fix.patch, H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Updated: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Mikhail Markov (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Mikhail Markov updated HARMONY-4081:
------------------------------------

    Attachment: H-4081_temp_workaround.patch

I've found the root cause of the problem:
In the method FileChannelImpl.write(ByteBuffer[], int, int) in the beginning of it, all non-direct ByteBuffers are temporarily copied to direct ByteBuffers and then native method is called using the created handles to these buffers. The problem is that between these parts, the newly created direct ByteBuffers are GC-ed, and another thread working on the same method also allocating temporary direct ByteBuffers on the same addresses, which leads to the described race conditions.

Here is the temporary workaround demonstrating/fixing the problem - it just does not allow the created temporary direct ByteBuffers to be GC-ed before the write method exits.
More elegant solution is needed, as we're duplicating the array and allocating potentially too much memory for direct ByteBuffers.

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>         Attachments: H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Assigned: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Alexei Zakharov (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Alexei Zakharov reassigned HARMONY-4081:
----------------------------------------

    Assignee: Alexei Zakharov

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Assignee: Alexei Zakharov
>            Priority: Minor
>         Attachments: H-4081_fix.patch, H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Commented: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Ilya Leviev (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12505840 ] 

Ilya Leviev commented on HARMONY-4081:
--------------------------------------

I have run test from JIRA with TC and have located points of code where the problems related to hyfile.c issues have occurred. 
There are following race conditions were detected. 


1) Write -> Read data-race Memory read at "hyfile.c":896 conflicts with a prior memory write at "osmemory.c":87
2) Read -> Write data-race Memory write at "osmemory.c":87 conflicts with a prior memory read at "hyfile.c":896


See also Source View screenshots. 


> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Commented: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Mikhail Markov (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12505905 ] 

Mikhail Markov commented on HARMONY-4081:
-----------------------------------------

Thanks, Ilia!
Seems i was wrong and ERROR_INVALID_USER_BUFFER is really caused by simultaneous read/write-s and not "too many requests" as i gueseed before. Seems like additional synchronized blocks should be added to FileChannelImpl code. I'll try to fix the problem.

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>         Attachments: SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Commented: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Mikhail Markov (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12504709 ] 

Mikhail Markov commented on HARMONY-4081:
-----------------------------------------

I've figured out that the problem happens in portlib's hyfile_write function: call to WriteFile() function from Windows API returns ERROR_INVALID_USER_BUFFER (1784) error code.
MSDN documentation for WriteFile() function says that "The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests."
So we need to somehow avoid "too many requests"...

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Updated: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Alexei Zakharov (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Alexei Zakharov updated HARMONY-4081:
-------------------------------------

    Patch Info: [Patch Available]

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Assignee: Alexei Zakharov
>            Priority: Minor
>         Attachments: H-4081_fix.patch, H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Updated: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Alexei Zakharov (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Alexei Zakharov updated HARMONY-4081:
-------------------------------------

    Assignee:     (was: Alexei Zakharov)

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>         Attachments: H-4081_fix.patch, H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Commented: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Paulex Yang (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12520200 ] 

Paulex Yang commented on HARMONY-4081:
--------------------------------------

Mikhail,

I agree the FileChannelImpl part of your patch, but I'm not sure I understand the modifications on AbstractMemorySpy and MappedPlatformAddress, would you please explain a little more on this? 

I'm a little confused on MappedPlatformAddress, because it actually holds a pointer to a mapped memory(got from mmap() on Linux), and the native method unmap(osaddr, size) is right method to free the native resource, for example on Linux, unmap() invokes munmap() system call. So why to add another call to free()?  

About the AbstractMemorySpy, if the address is removed from memoryInUse, supposingly its relevant native resource will be freed in next call to orphandMemory() after GC run. If the relevant reference object is removed from refToShadow, the mechanism won't work, because the wrapper.shadow.free() (Line.110, AbstractMemorySpy) cannot be reached any more.

Anything I missed? 

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Assignee: Alexei Zakharov
>            Priority: Minor
>         Attachments: H-4081_fix.patch, H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Updated: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Mikhail Markov (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Mikhail Markov updated HARMONY-4081:
------------------------------------

    Attachment: H-4081_fix.patch

Here is the patch fixing the issue.

Fix description: seems like copying non-direct buffers to the direct ones is the intended behavior of this method, so I've improved the previous workaround by doing useful operations like explicit freeing of allocated direct buffers. This revealed the problem in memory spys implementation so the patch incorporates the fixes for them as well.

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>         Attachments: H-4081_fix.patch, H-4081_temp_workaround.patch, SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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


[jira] Updated: (HARMONY-4081) [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly

Posted by "Ilya Leviev (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-4081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Ilya Leviev updated HARMONY-4081:
---------------------------------

    Attachment: SourceViewScreenshot-1.jpg

> [classlib][nio] FileChannel.write(ByteBuffer[]) sometimes works incorrectly
> ---------------------------------------------------------------------------
>
>                 Key: HARMONY-4081
>                 URL: https://issues.apache.org/jira/browse/HARMONY-4081
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>         Environment: Windows
>            Reporter: Vera Petrashkova
>            Priority: Minor
>         Attachments: SourceViewScreenshot-1.jpg
>
>
> According to J2SE specification
> "File channels are safe for use by multiple concurrent threads."
> But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
> some threads try to write bytes to the same channel.
> Not all data are written to the file.
> ---------------fchTest.java---------------
> import java.io.File;
> import java.io.IOException;
> import java.io.FileOutputStream;
> import java.io.FileInputStream;
> import java.nio.channels.FileChannel;
> import java.nio.ByteBuffer;
> public class fchTest {
>         
>     public static int N_TH = 20;
>     public static final int BUF_SIZE = 2000;
>     public static final int N_BUF = 20;
>     public static final int N_WRITES = 20;
>     boolean passed = true;
>   
>     String fileName = "FileChannel.file";
>     FileChannel outChannel = null;
>     FileChannel inChannel = null;
>     public static void main(String[] args) {
>         try {
>              if (args.length > 0) {
>                 N_TH = Integer.parseInt(args[0]);
>             }
>         } catch (Throwable e) {
>         }    
>         int res = new fchTest().test(args);
>         System.err.println(res == 104 ? "Test passed" : "Test failed");          
>     }
>     public int test(String[] params) {
>         File f = null;
>         passed = true;
>         try {
>             f = new File(fileName);
>             if (f.exists()) {
>                 f.delete();
>             }
>             outChannel = new FileOutputStream(f).getChannel();
>             inChannel = new FileInputStream(f).getChannel();
>             Thread[] t = new Thread[N_TH];
>             for (int i = 0; i < t.length; ++i) {
>                 t[i] = new thWriter(this); 
>                 t[i].start();
>             }
>             for (int i = 0; i < t.length; ++i) {
>                 t[i].join();
>             }
>         } catch (Throwable t) {
>             t.printStackTrace();
>             return 105;
>         } finally {
>             try {
>                 if (outChannel != null){
>                     outChannel.close();
>                 }
>                 if (inChannel != null){
>                     inChannel.close();
>                 }                    
>             } catch (Throwable t){
>                 t.printStackTrace();
>             }
>             if (f != null){
>                 f.delete();
>             }
>         }
>         return (passed ? 104 : 106);
>     }
> }
> class thWriter extends Thread {
>     FileChannel outChannel = null;
>     fchTest base = null;
>     
>     thWriter(fchTest base) {
>         this.outChannel = base.outChannel;
>         this.base = base;
>     }
> public void run () {
>         try {
>             long allW = 0;
>             long allC = 0;
>             for (int i = 0; i < fchTest.N_WRITES; ++i) {
>                 ByteBuffer[] bbb = createByteChunks();
>                 for (int t = 0; t < bbb.length; t++)  {
>                     allC += bbb[i].capacity();
>                 }
>                 long written = outChannel.write(bbb);
>                 if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF)) {
>                     System.err.println(this+"  Written: "+written+"  should be "+ fchTest.BUF_SIZE*fchTest.N_BUF+" outChannel position: "+outChannel.position());
>                     base.passed = false;
>                 }
>                 allW+=written;
>                 Thread.yield();
>                 Thread.sleep(10);
>             }
>             System.err.println(this+" - after write: "+allW+"  "+allC);
>             if (allW != allC) {
>                 base.passed = false;
>             }
>             outChannel.force(false);
>         } catch (Throwable e){
>             System.err.println(this+" unexpected exception " + e);
>             e.printStackTrace();
>             base.passed = false;
>         }
>     }
>     ByteBuffer[] createByteChunks() {
>         ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
>         byte [] bb = new byte[fchTest.BUF_SIZE];    
>         for (int i = 0; i < bb.length; i++) {
>             bb[i] = (byte)i;
>         }
>         for (int i = 0; i < bb_arr.length; ++i) {
>             bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb);
>         }       
>         return bb_arr;
>     }
> }
> ----------------------------------------------------
> Run this test several times and change the number of created threads
> java fchTest
> java fchTest 30
> Output on RI:
> ==============
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
> Thread[Thread-1,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-3,5,main] - after write: 800000  800000
> Thread[Thread-0,5,main] - after write: 800000  800000
> Thread[Thread-5,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-2,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-4,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Test passed
> Output on DRLVM:
> ==============
> 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 = r544707, (Jun  6 2007), Windows/ia32/msvc 1310, release build
> http://harmony.apache.org
> The GC did not provide gc_add_weak_root_set_entry()
> Thread[Thread-9,5,main]  Written: 33100  should be 40000 outChannel position: 6874000
> Thread[Thread-20,5,main] - after write: 800000  800000
> Thread[Thread-16,5,main] - after write: 800000  800000
> Thread[Thread-8,5,main] - after write: 800000  800000
> Thread[Thread-12,5,main] - after write: 800000  800000
> Thread[Thread-22,5,main] - after write: 800000  800000
> Thread[Thread-14,5,main] - after write: 800000  800000
> Thread[Thread-18,5,main] - after write: 800000  800000
> Thread[Thread-23,5,main] - after write: 800000  800000
> Thread[Thread-11,5,main] - after write: 800000  800000
> Thread[Thread-10,5,main] - after write: 800000  800000
> Thread[Thread-24,5,main] - after write: 800000  800000
> Thread[Thread-7,5,main] - after write: 800000  800000
> Thread[Thread-15,5,main] - after write: 800000  800000
> Thread[Thread-9,5,main] - after write: 793100  800000
> Thread[Thread-6,5,main] - after write: 800000  800000
> Thread[Thread-25,5,main] - after write: 800000  800000
> Thread[Thread-17,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main]  Written: 37700  should be 40000 outChannel position: 15872000
> Thread[Thread-19,5,main] - after write: 800000  800000
> Thread[Thread-13,5,main] - after write: 797700  800000
> Thread[Thread-21,5,main] - after write: 800000  800000
> Test failed
> This bug causes the failure of the test
>     api.nio.channels.filechannel.FileChannelThrSafetyTest
> from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918

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