From 9034c954790c7f8e2a6bc65b66e631100f5dd3af Mon Sep 17 00:00:00 2001 From: Ozzy Espaillat Date: Thu, 23 Jun 2022 21:06:48 -0700 Subject: [PATCH] Update BinLogWriter.java Add fix for file descriptor leak on cutover by closing channel when cutover happens. Prevent leak of newRaf when there is an error. --- .../java/org/jpos/binlog/BinLogWriter.java | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/modules/binlog/src/main/java/org/jpos/binlog/BinLogWriter.java b/modules/binlog/src/main/java/org/jpos/binlog/BinLogWriter.java index 88b55115c5..f363071557 100644 --- a/modules/binlog/src/main/java/org/jpos/binlog/BinLogWriter.java +++ b/modules/binlog/src/main/java/org/jpos/binlog/BinLogWriter.java @@ -129,35 +129,43 @@ public void cutover () throws IOException { if (readStatus() != Status.OPEN) throw new IOException ("BinLog not open"); AsynchronousFileChannel newRaf = openOrCreateFile(dir, ++fileNumber); - ByteBuffer index = ByteBuffer.allocate(4); - index.putInt(fileNumber); - index.flip(); try { - int write = raf.write(index, NEXT_LOG_INDEX_OFFSET).get(); - if (write != 4) { - throw new IOException ("Failed to write 4 byte NEXT_LOG_INDEX_OFFSET, return: " + write); + ByteBuffer index = ByteBuffer.allocate(4); + index.putInt(fileNumber); + index.flip(); + try { + int write = raf.write(index, NEXT_LOG_INDEX_OFFSET).get(); + if (write != 4) { + throw new IOException ("Failed to write 4 byte NEXT_LOG_INDEX_OFFSET, return: " + write); + } + } catch (InterruptedException e) { + throw new IOException (e.getMessage()); + } catch (ExecutionException e) { + throw new IOException (e.getMessage()); } - } catch (InterruptedException e) { - throw new IOException (e.getMessage()); - } catch (ExecutionException e) { - throw new IOException (e.getMessage()); - } - ByteBuffer status = ByteBuffer.allocate(2); - status.putShort(Status.CLOSED.shortValue()); - status.flip(); - try { - int write = raf.write(status, STATUS_OFFSET).get(); - if (write != 2) { - throw new IOException ("Failed to write 2 byte STATUS_OFFSET, return: " + write); + ByteBuffer status = ByteBuffer.allocate(2); + status.putShort(Status.CLOSED.shortValue()); + status.flip(); + try { + int write = raf.write(status, STATUS_OFFSET).get(); + if (write != 2) { + throw new IOException ("Failed to write 2 byte STATUS_OFFSET, return: " + write); + } + } catch (InterruptedException e) { + throw new IOException (e.getMessage()); + } catch (ExecutionException e) { + throw new IOException (e.getMessage()); + } + channel.force(false); + raf = newRaf; + } finally { + lock.release(); + if (newRaf == raf) { + channel.close(); + } else { + newRaf.close(); } - } catch (InterruptedException e) { - throw new IOException (e.getMessage()); - } catch (ExecutionException e) { - throw new IOException (e.getMessage()); } - channel.force(false); - raf = newRaf; - lock.release(); } else { throw new IOException ("Failed to acquire file lock"); }