/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.j2objc.nio; import com.google.j2objc.annotations.AutoreleasePool; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import junit.framework.TestCase; /** * Functional tests for correct memory behavior of FileChannel. * * @author Lukhnos Liu */ public class FileChannelTest extends TestCase { /** * Make sure that FileChannelImpl uses @RetainedWith on the stream object field. @Weak should not * be used there -- the problem being the channel one gets from FileOutputStream.getChannel() can * outlive the stream. When that happens, a dangling pointer can cause either of the two problems: * either the pointer is bad, and an EXC_BAD_ADDRESS is thrown right away; or (this is harder to * debug) if the stream object is stale, yet the closed flag is set, and the subsequent uses of * the channel throws out a ClosedChannelException because the stream closes itself upon its * finalize(). */ public void testFileChannelRetainedWithFileOutputStream() throws Exception { useFileChannel(); } /** * A contrived ChannelGetter that autoreleases the FileOutputStream created from a File but * retains the resulting FileChannel. */ static class ChannelGetter { FileChannel channel; @AutoreleasePool void createChannel(File f) throws IOException { FileOutputStream fos = new FileOutputStream(f); channel = fos.getChannel(); } FileChannel get() { return channel; } } private void useFileChannel() throws IOException { File file = File.createTempFile("j2objc", "tmp"); ChannelGetter channelGetter = new ChannelGetter(); channelGetter.createChannel(file); // The FileOutputStream used to create the channel is released at this point. FileChannel channel = channelGetter.get(); FileLock lock = channel.lock(); lock.close(); channel.close(); assertTrue(file.delete()); } }