111 if (parent != null) {
112
113 // Close the fd via the parent stream's close method. The parent
114 // will reinvoke our close method, which is defined in the
115 // superclass AbstractInterruptibleChannel, but the isOpen logic in
116 // that method will prevent this method from being reinvoked.
117 //
118 ((java.io.Closeable)parent).close();
119 } else {
120 nd.close(fd);
121 }
122
123 }
124
125 public int read(ByteBuffer dst) throws IOException {
126 ensureOpen();
127 if (!readable)
128 throw new NonReadableChannelException();
129 synchronized (positionLock) {
130 int n = 0;
131 int ti = threads.add();
132 try {
133 begin();
134 if (!isOpen())
135 return 0;
136 do {
137 n = IOUtil.read(fd, dst, -1, nd, positionLock);
138 } while ((n == IOStatus.INTERRUPTED) && isOpen());
139 return IOStatus.normalize(n);
140 } finally {
141 threads.remove(ti);
142 end(n > 0);
143 assert IOStatus.check(n);
144 }
145 }
146 }
147
148 private long read0(ByteBuffer[] dsts) throws IOException {
149 ensureOpen();
150 if (!readable)
151 throw new NonReadableChannelException();
152 synchronized (positionLock) {
153 long n = 0;
154 int ti = threads.add();
155 try {
156 begin();
157 if (!isOpen())
158 return 0;
159 do {
160 n = IOUtil.read(fd, dsts, nd);
161 } while ((n == IOStatus.INTERRUPTED) && isOpen());
162 return IOStatus.normalize(n);
163 } finally {
164 threads.remove(ti);
165 end(n > 0);
166 assert IOStatus.check(n);
167 }
168 }
169 }
170
171 public long read(ByteBuffer[] dsts, int offset, int length)
172 throws IOException
173 {
174 if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
175 throw new IndexOutOfBoundsException();
176 // ## Fix IOUtil.write so that we can avoid this array copy
177 return read0(Util.subsequence(dsts, offset, length));
178 }
179
180 public int write(ByteBuffer src) throws IOException {
181 ensureOpen();
182 if (!writable)
183 throw new NonWritableChannelException();
184 synchronized (positionLock) {
185 int n = 0;
186 int ti = threads.add();
187 try {
188 begin();
189 if (!isOpen())
190 return 0;
191 do {
192 n = IOUtil.write(fd, src, -1, nd, positionLock);
193 } while ((n == IOStatus.INTERRUPTED) && isOpen());
194 return IOStatus.normalize(n);
195 } finally {
196 threads.remove(ti);
197 end(n > 0);
198 assert IOStatus.check(n);
199 }
200 }
201 }
202
203 private long write0(ByteBuffer[] srcs) throws IOException {
204 ensureOpen();
205 if (!writable)
206 throw new NonWritableChannelException();
207 synchronized (positionLock) {
208 long n = 0;
209 int ti = threads.add();
210 try {
211 begin();
212 if (!isOpen())
213 return 0;
214 do {
215 n = IOUtil.write(fd, srcs, nd);
216 } while ((n == IOStatus.INTERRUPTED) && isOpen());
217 return IOStatus.normalize(n);
218 } finally {
219 threads.remove(ti);
220 end(n > 0);
221 assert IOStatus.check(n);
222 }
223 }
224 }
225
226 public long write(ByteBuffer[] srcs, int offset, int length)
227 throws IOException
228 {
229 if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
230 throw new IndexOutOfBoundsException();
231 // ## Fix IOUtil.write so that we can avoid this array copy
232 return write0(Util.subsequence(srcs, offset, length));
233 }
234
235
236 // -- Other operations --
237
238 public long position() throws IOException {
239 ensureOpen();
240 synchronized (positionLock) {
241 long p = -1;
242 int ti = threads.add();
243 try {
244 begin();
245 if (!isOpen())
246 return 0;
247 do {
248 p = position0(fd, -1);
249 } while ((p == IOStatus.INTERRUPTED) && isOpen());
250 return IOStatus.normalize(p);
251 } finally {
252 threads.remove(ti);
253 end(p > -1);
254 assert IOStatus.check(p);
255 }
256 }
257 }
258
259 public FileChannel position(long newPosition) throws IOException {
260 ensureOpen();
261 if (newPosition < 0)
262 throw new IllegalArgumentException();
263 synchronized (positionLock) {
264 long p = -1;
265 int ti = threads.add();
266 try {
267 begin();
268 if (!isOpen())
269 return null;
270 do {
271 p = position0(fd, newPosition);
272 } while ((p == IOStatus.INTERRUPTED) && isOpen());
273 return this;
274 } finally {
275 threads.remove(ti);
276 end(p > -1);
277 assert IOStatus.check(p);
278 }
279 }
280 }
281
282 public long size() throws IOException {
283 ensureOpen();
284 synchronized (positionLock) {
285 long s = -1;
286 int ti = threads.add();
287 try {
288 begin();
289 if (!isOpen())
290 return -1;
291 do {
292 s = nd.size(fd);
293 } while ((s == IOStatus.INTERRUPTED) && isOpen());
294 return IOStatus.normalize(s);
295 } finally {
296 threads.remove(ti);
297 end(s > -1);
298 assert IOStatus.check(s);
299 }
300 }
301 }
302
303 public FileChannel truncate(long size) throws IOException {
304 ensureOpen();
305 if (size < 0)
306 throw new IllegalArgumentException();
307 if (size > size())
308 return this;
309 if (!writable)
310 throw new NonWritableChannelException();
311 synchronized (positionLock) {
312 int rv = -1;
313 long p = -1;
314 int ti = threads.add();
315 try {
316 begin();
317 if (!isOpen())
318 return null;
319
320 // get current position
321 do {
322 p = position0(fd, -1);
323 } while ((p == IOStatus.INTERRUPTED) && isOpen());
324 if (!isOpen())
325 return null;
326 assert p >= 0;
327
328 // truncate file
329 do {
330 rv = nd.truncate(fd, size);
331 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
332 if (!isOpen())
333 return null;
334
335 // set position to size if greater than size
336 if (p > size)
337 p = size;
338 do {
339 rv = (int)position0(fd, p);
340 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
341 return this;
342 } finally {
343 threads.remove(ti);
344 end(rv > -1);
345 assert IOStatus.check(rv);
346 }
347 }
348 }
349
350 public void force(boolean metaData) throws IOException {
351 ensureOpen();
352 int rv = -1;
353 int ti = threads.add();
354 try {
355 begin();
356 if (!isOpen())
357 return;
358 do {
359 rv = nd.force(fd, metaData);
360 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
361 } finally {
362 threads.remove(ti);
363 end(rv > -1);
364 assert IOStatus.check(rv);
365 }
366 }
367
368 // Assume at first that the underlying kernel supports sendfile();
369 // set this to false if we find out later that it doesn't
370 //
371 private static volatile boolean transferSupported = true;
372
373 // Assume that the underlying kernel sendfile() will work if the target
374 // fd is a pipe; set this to false if we find out later that it doesn't
375 //
389
390 FileDescriptor targetFD = null;
391 if (target instanceof FileChannelImpl) {
392 if (!fileSupported)
393 return IOStatus.UNSUPPORTED_CASE;
394 targetFD = ((FileChannelImpl)target).fd;
395 } else if (target instanceof SelChImpl) {
396 // Direct transfer to pipe causes EINVAL on some configurations
397 if ((target instanceof SinkChannelImpl) && !pipeSupported)
398 return IOStatus.UNSUPPORTED_CASE;
399 targetFD = ((SelChImpl)target).getFD();
400 }
401 if (targetFD == null)
402 return IOStatus.UNSUPPORTED;
403 int thisFDVal = IOUtil.fdVal(fd);
404 int targetFDVal = IOUtil.fdVal(targetFD);
405 if (thisFDVal == targetFDVal) // Not supported on some configurations
406 return IOStatus.UNSUPPORTED;
407
408 long n = -1;
409 int ti = threads.add();
410 try {
411 begin();
412 if (!isOpen())
413 return -1;
414 do {
415 n = transferTo0(thisFDVal, position, icount, targetFDVal);
416 } while ((n == IOStatus.INTERRUPTED) && isOpen());
417 if (n == IOStatus.UNSUPPORTED_CASE) {
418 if (target instanceof SinkChannelImpl)
419 pipeSupported = false;
420 if (target instanceof FileChannelImpl)
421 fileSupported = false;
422 return IOStatus.UNSUPPORTED_CASE;
423 }
424 if (n == IOStatus.UNSUPPORTED) {
425 // Don't bother trying again
426 transferSupported = false;
427 return IOStatus.UNSUPPORTED;
428 }
429 return IOStatus.normalize(n);
430 } finally {
431 threads.remove(ti);
595 if ((position < 0) || (count < 0))
596 throw new IllegalArgumentException();
597 if (position > size())
598 return 0;
599 if (src instanceof FileChannelImpl)
600 return transferFromFileChannel((FileChannelImpl)src,
601 position, count);
602
603 return transferFromArbitraryChannel(src, position, count);
604 }
605
606 public int read(ByteBuffer dst, long position) throws IOException {
607 if (dst == null)
608 throw new NullPointerException();
609 if (position < 0)
610 throw new IllegalArgumentException("Negative position");
611 if (!readable)
612 throw new NonReadableChannelException();
613 ensureOpen();
614 int n = 0;
615 int ti = threads.add();
616 try {
617 begin();
618 if (!isOpen())
619 return -1;
620 do {
621 n = IOUtil.read(fd, dst, position, nd, positionLock);
622 } while ((n == IOStatus.INTERRUPTED) && isOpen());
623 return IOStatus.normalize(n);
624 } finally {
625 threads.remove(ti);
626 end(n > 0);
627 assert IOStatus.check(n);
628 }
629 }
630
631 public int write(ByteBuffer src, long position) throws IOException {
632 if (src == null)
633 throw new NullPointerException();
634 if (position < 0)
635 throw new IllegalArgumentException("Negative position");
636 if (!writable)
637 throw new NonWritableChannelException();
638 ensureOpen();
639 int n = 0;
640 int ti = threads.add();
641 try {
642 begin();
643 if (!isOpen())
644 return -1;
645 do {
646 n = IOUtil.write(fd, src, position, nd, positionLock);
647 } while ((n == IOStatus.INTERRUPTED) && isOpen());
648 return IOStatus.normalize(n);
649 } finally {
650 threads.remove(ti);
651 end(n > 0);
652 assert IOStatus.check(n);
653 }
654 }
655
656
657 // -- Memory-mapped buffers --
658
659 private static class Unmapper
660 implements Runnable
661 {
662 // keep track of mapped buffer usage
714 if (size < 0L)
715 throw new IllegalArgumentException("Negative size");
716 if (position + size < 0)
717 throw new IllegalArgumentException("Position + size overflow");
718 if (size > Integer.MAX_VALUE)
719 throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
720 int imode = -1;
721 if (mode == MapMode.READ_ONLY)
722 imode = MAP_RO;
723 else if (mode == MapMode.READ_WRITE)
724 imode = MAP_RW;
725 else if (mode == MapMode.PRIVATE)
726 imode = MAP_PV;
727 assert (imode >= 0);
728 if ((mode != MapMode.READ_ONLY) && !writable)
729 throw new NonWritableChannelException();
730 if (!readable)
731 throw new NonReadableChannelException();
732
733 long addr = -1;
734 int ti = threads.add();
735 try {
736 begin();
737 if (!isOpen())
738 return null;
739 if (size() < position + size) { // Extend file size
740 if (!writable) {
741 throw new IOException("Channel not open for writing " +
742 "- cannot extend file to required size");
743 }
744 int rv;
745 do {
746 rv = nd.truncate(fd, position + size);
747 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
748 }
749 if (size == 0) {
750 addr = 0;
751 if ((!writable) || (imode == MAP_RO))
752 return Util.newMappedByteBufferR(0, 0, null);
753 else
754 return Util.newMappedByteBuffer(0, 0, null);
755 }
756
883 fileLockTable = new SimpleFileLockTable();
884 }
885 }
886 }
887 }
888 return fileLockTable;
889 }
890
891 public FileLock lock(long position, long size, boolean shared)
892 throws IOException
893 {
894 ensureOpen();
895 if (shared && !readable)
896 throw new NonReadableChannelException();
897 if (!shared && !writable)
898 throw new NonWritableChannelException();
899 FileLockImpl fli = new FileLockImpl(this, position, size, shared);
900 FileLockTable flt = fileLockTable();
901 flt.add(fli);
902 boolean i = true;
903 int ti = threads.add();
904 try {
905 begin();
906 if (!isOpen())
907 return null;
908 int result = nd.lock(fd, true, position, size, shared);
909 if (result == FileDispatcher.RET_EX_LOCK) {
910 assert shared;
911 FileLockImpl fli2 = new FileLockImpl(this, position, size,
912 false);
913 flt.replace(fli, fli2);
914 return fli2;
915 }
916 if (result == FileDispatcher.INTERRUPTED || result == FileDispatcher.NO_LOCK) {
917 flt.remove(fli);
918 i = false;
919 }
920 } catch (IOException e) {
921 flt.remove(fli);
922 throw e;
923 } finally {
924 threads.remove(ti);
925 try {
|
111 if (parent != null) {
112
113 // Close the fd via the parent stream's close method. The parent
114 // will reinvoke our close method, which is defined in the
115 // superclass AbstractInterruptibleChannel, but the isOpen logic in
116 // that method will prevent this method from being reinvoked.
117 //
118 ((java.io.Closeable)parent).close();
119 } else {
120 nd.close(fd);
121 }
122
123 }
124
125 public int read(ByteBuffer dst) throws IOException {
126 ensureOpen();
127 if (!readable)
128 throw new NonReadableChannelException();
129 synchronized (positionLock) {
130 int n = 0;
131 int ti = -1;
132 try {
133 begin();
134 ti = threads.add();
135 if (!isOpen())
136 return 0;
137 do {
138 n = IOUtil.read(fd, dst, -1, nd, positionLock);
139 } while ((n == IOStatus.INTERRUPTED) && isOpen());
140 return IOStatus.normalize(n);
141 } finally {
142 threads.remove(ti);
143 end(n > 0);
144 assert IOStatus.check(n);
145 }
146 }
147 }
148
149 private long read0(ByteBuffer[] dsts) throws IOException {
150 ensureOpen();
151 if (!readable)
152 throw new NonReadableChannelException();
153 synchronized (positionLock) {
154 long n = 0;
155 int ti = -1;
156 try {
157 begin();
158 ti = threads.add();
159 if (!isOpen())
160 return 0;
161 do {
162 n = IOUtil.read(fd, dsts, nd);
163 } while ((n == IOStatus.INTERRUPTED) && isOpen());
164 return IOStatus.normalize(n);
165 } finally {
166 threads.remove(ti);
167 end(n > 0);
168 assert IOStatus.check(n);
169 }
170 }
171 }
172
173 public long read(ByteBuffer[] dsts, int offset, int length)
174 throws IOException
175 {
176 if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
177 throw new IndexOutOfBoundsException();
178 // ## Fix IOUtil.write so that we can avoid this array copy
179 return read0(Util.subsequence(dsts, offset, length));
180 }
181
182 public int write(ByteBuffer src) throws IOException {
183 ensureOpen();
184 if (!writable)
185 throw new NonWritableChannelException();
186 synchronized (positionLock) {
187 int n = 0;
188 int ti = -1;
189 try {
190 begin();
191 ti = threads.add();
192 if (!isOpen())
193 return 0;
194 do {
195 n = IOUtil.write(fd, src, -1, nd, positionLock);
196 } while ((n == IOStatus.INTERRUPTED) && isOpen());
197 return IOStatus.normalize(n);
198 } finally {
199 threads.remove(ti);
200 end(n > 0);
201 assert IOStatus.check(n);
202 }
203 }
204 }
205
206 private long write0(ByteBuffer[] srcs) throws IOException {
207 ensureOpen();
208 if (!writable)
209 throw new NonWritableChannelException();
210 synchronized (positionLock) {
211 long n = 0;
212 int ti = -1;
213 try {
214 begin();
215 ti = threads.add();
216 if (!isOpen())
217 return 0;
218 do {
219 n = IOUtil.write(fd, srcs, nd);
220 } while ((n == IOStatus.INTERRUPTED) && isOpen());
221 return IOStatus.normalize(n);
222 } finally {
223 threads.remove(ti);
224 end(n > 0);
225 assert IOStatus.check(n);
226 }
227 }
228 }
229
230 public long write(ByteBuffer[] srcs, int offset, int length)
231 throws IOException
232 {
233 if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
234 throw new IndexOutOfBoundsException();
235 // ## Fix IOUtil.write so that we can avoid this array copy
236 return write0(Util.subsequence(srcs, offset, length));
237 }
238
239
240 // -- Other operations --
241
242 public long position() throws IOException {
243 ensureOpen();
244 synchronized (positionLock) {
245 long p = -1;
246 int ti = -1;
247 try {
248 begin();
249 ti = threads.add();
250 if (!isOpen())
251 return 0;
252 do {
253 p = position0(fd, -1);
254 } while ((p == IOStatus.INTERRUPTED) && isOpen());
255 return IOStatus.normalize(p);
256 } finally {
257 threads.remove(ti);
258 end(p > -1);
259 assert IOStatus.check(p);
260 }
261 }
262 }
263
264 public FileChannel position(long newPosition) throws IOException {
265 ensureOpen();
266 if (newPosition < 0)
267 throw new IllegalArgumentException();
268 synchronized (positionLock) {
269 long p = -1;
270 int ti = -1;
271 try {
272 begin();
273 ti = threads.add();
274 if (!isOpen())
275 return null;
276 do {
277 p = position0(fd, newPosition);
278 } while ((p == IOStatus.INTERRUPTED) && isOpen());
279 return this;
280 } finally {
281 threads.remove(ti);
282 end(p > -1);
283 assert IOStatus.check(p);
284 }
285 }
286 }
287
288 public long size() throws IOException {
289 ensureOpen();
290 synchronized (positionLock) {
291 long s = -1;
292 int ti = -1;
293 try {
294 begin();
295 ti = threads.add();
296 if (!isOpen())
297 return -1;
298 do {
299 s = nd.size(fd);
300 } while ((s == IOStatus.INTERRUPTED) && isOpen());
301 return IOStatus.normalize(s);
302 } finally {
303 threads.remove(ti);
304 end(s > -1);
305 assert IOStatus.check(s);
306 }
307 }
308 }
309
310 public FileChannel truncate(long size) throws IOException {
311 ensureOpen();
312 if (size < 0)
313 throw new IllegalArgumentException();
314 if (size > size())
315 return this;
316 if (!writable)
317 throw new NonWritableChannelException();
318 synchronized (positionLock) {
319 int rv = -1;
320 long p = -1;
321 int ti = -1;
322 try {
323 begin();
324 ti = threads.add();
325 if (!isOpen())
326 return null;
327
328 // get current position
329 do {
330 p = position0(fd, -1);
331 } while ((p == IOStatus.INTERRUPTED) && isOpen());
332 if (!isOpen())
333 return null;
334 assert p >= 0;
335
336 // truncate file
337 do {
338 rv = nd.truncate(fd, size);
339 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
340 if (!isOpen())
341 return null;
342
343 // set position to size if greater than size
344 if (p > size)
345 p = size;
346 do {
347 rv = (int)position0(fd, p);
348 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
349 return this;
350 } finally {
351 threads.remove(ti);
352 end(rv > -1);
353 assert IOStatus.check(rv);
354 }
355 }
356 }
357
358 public void force(boolean metaData) throws IOException {
359 ensureOpen();
360 int rv = -1;
361 int ti = -1;
362 try {
363 begin();
364 ti = threads.add();
365 if (!isOpen())
366 return;
367 do {
368 rv = nd.force(fd, metaData);
369 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
370 } finally {
371 threads.remove(ti);
372 end(rv > -1);
373 assert IOStatus.check(rv);
374 }
375 }
376
377 // Assume at first that the underlying kernel supports sendfile();
378 // set this to false if we find out later that it doesn't
379 //
380 private static volatile boolean transferSupported = true;
381
382 // Assume that the underlying kernel sendfile() will work if the target
383 // fd is a pipe; set this to false if we find out later that it doesn't
384 //
398
399 FileDescriptor targetFD = null;
400 if (target instanceof FileChannelImpl) {
401 if (!fileSupported)
402 return IOStatus.UNSUPPORTED_CASE;
403 targetFD = ((FileChannelImpl)target).fd;
404 } else if (target instanceof SelChImpl) {
405 // Direct transfer to pipe causes EINVAL on some configurations
406 if ((target instanceof SinkChannelImpl) && !pipeSupported)
407 return IOStatus.UNSUPPORTED_CASE;
408 targetFD = ((SelChImpl)target).getFD();
409 }
410 if (targetFD == null)
411 return IOStatus.UNSUPPORTED;
412 int thisFDVal = IOUtil.fdVal(fd);
413 int targetFDVal = IOUtil.fdVal(targetFD);
414 if (thisFDVal == targetFDVal) // Not supported on some configurations
415 return IOStatus.UNSUPPORTED;
416
417 long n = -1;
418 int ti = -1;
419 try {
420 begin();
421 ti = threads.add();
422 if (!isOpen())
423 return -1;
424 do {
425 n = transferTo0(thisFDVal, position, icount, targetFDVal);
426 } while ((n == IOStatus.INTERRUPTED) && isOpen());
427 if (n == IOStatus.UNSUPPORTED_CASE) {
428 if (target instanceof SinkChannelImpl)
429 pipeSupported = false;
430 if (target instanceof FileChannelImpl)
431 fileSupported = false;
432 return IOStatus.UNSUPPORTED_CASE;
433 }
434 if (n == IOStatus.UNSUPPORTED) {
435 // Don't bother trying again
436 transferSupported = false;
437 return IOStatus.UNSUPPORTED;
438 }
439 return IOStatus.normalize(n);
440 } finally {
441 threads.remove(ti);
605 if ((position < 0) || (count < 0))
606 throw new IllegalArgumentException();
607 if (position > size())
608 return 0;
609 if (src instanceof FileChannelImpl)
610 return transferFromFileChannel((FileChannelImpl)src,
611 position, count);
612
613 return transferFromArbitraryChannel(src, position, count);
614 }
615
616 public int read(ByteBuffer dst, long position) throws IOException {
617 if (dst == null)
618 throw new NullPointerException();
619 if (position < 0)
620 throw new IllegalArgumentException("Negative position");
621 if (!readable)
622 throw new NonReadableChannelException();
623 ensureOpen();
624 int n = 0;
625 int ti = -1;
626 try {
627 begin();
628 ti = threads.add();
629 if (!isOpen())
630 return -1;
631 do {
632 n = IOUtil.read(fd, dst, position, nd, positionLock);
633 } while ((n == IOStatus.INTERRUPTED) && isOpen());
634 return IOStatus.normalize(n);
635 } finally {
636 threads.remove(ti);
637 end(n > 0);
638 assert IOStatus.check(n);
639 }
640 }
641
642 public int write(ByteBuffer src, long position) throws IOException {
643 if (src == null)
644 throw new NullPointerException();
645 if (position < 0)
646 throw new IllegalArgumentException("Negative position");
647 if (!writable)
648 throw new NonWritableChannelException();
649 ensureOpen();
650 int n = 0;
651 int ti = -1;
652 try {
653 begin();
654 ti = threads.add();
655 if (!isOpen())
656 return -1;
657 do {
658 n = IOUtil.write(fd, src, position, nd, positionLock);
659 } while ((n == IOStatus.INTERRUPTED) && isOpen());
660 return IOStatus.normalize(n);
661 } finally {
662 threads.remove(ti);
663 end(n > 0);
664 assert IOStatus.check(n);
665 }
666 }
667
668
669 // -- Memory-mapped buffers --
670
671 private static class Unmapper
672 implements Runnable
673 {
674 // keep track of mapped buffer usage
726 if (size < 0L)
727 throw new IllegalArgumentException("Negative size");
728 if (position + size < 0)
729 throw new IllegalArgumentException("Position + size overflow");
730 if (size > Integer.MAX_VALUE)
731 throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
732 int imode = -1;
733 if (mode == MapMode.READ_ONLY)
734 imode = MAP_RO;
735 else if (mode == MapMode.READ_WRITE)
736 imode = MAP_RW;
737 else if (mode == MapMode.PRIVATE)
738 imode = MAP_PV;
739 assert (imode >= 0);
740 if ((mode != MapMode.READ_ONLY) && !writable)
741 throw new NonWritableChannelException();
742 if (!readable)
743 throw new NonReadableChannelException();
744
745 long addr = -1;
746 int ti = -1;
747 try {
748 begin();
749 ti = threads.add();
750 if (!isOpen())
751 return null;
752 if (size() < position + size) { // Extend file size
753 if (!writable) {
754 throw new IOException("Channel not open for writing " +
755 "- cannot extend file to required size");
756 }
757 int rv;
758 do {
759 rv = nd.truncate(fd, position + size);
760 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
761 }
762 if (size == 0) {
763 addr = 0;
764 if ((!writable) || (imode == MAP_RO))
765 return Util.newMappedByteBufferR(0, 0, null);
766 else
767 return Util.newMappedByteBuffer(0, 0, null);
768 }
769
896 fileLockTable = new SimpleFileLockTable();
897 }
898 }
899 }
900 }
901 return fileLockTable;
902 }
903
904 public FileLock lock(long position, long size, boolean shared)
905 throws IOException
906 {
907 ensureOpen();
908 if (shared && !readable)
909 throw new NonReadableChannelException();
910 if (!shared && !writable)
911 throw new NonWritableChannelException();
912 FileLockImpl fli = new FileLockImpl(this, position, size, shared);
913 FileLockTable flt = fileLockTable();
914 flt.add(fli);
915 boolean i = true;
916 int ti = -1;
917 try {
918 begin();
919 ti = threads.add();
920 if (!isOpen())
921 return null;
922 int result = nd.lock(fd, true, position, size, shared);
923 if (result == FileDispatcher.RET_EX_LOCK) {
924 assert shared;
925 FileLockImpl fli2 = new FileLockImpl(this, position, size,
926 false);
927 flt.replace(fli, fli2);
928 return fli2;
929 }
930 if (result == FileDispatcher.INTERRUPTED || result == FileDispatcher.NO_LOCK) {
931 flt.remove(fli);
932 i = false;
933 }
934 } catch (IOException e) {
935 flt.remove(fli);
936 throw e;
937 } finally {
938 threads.remove(ti);
939 try {
|