Skip to content

Commit 6f27ad9

Browse files
committed
GXDebugStream was being closed instantly after creating it (#785)
* GXDebugStream was being closed too instantly after creating it * fix lint warnings (cherry picked from commit fbd9a0d)
1 parent 48f6b22 commit 6f27ad9

File tree

1 file changed

+80
-81
lines changed

1 file changed

+80
-81
lines changed

common/src/main/java/com/genexus/diagnostics/GXDebugManager.java

+80-81
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
import com.genexus.ModelContext;
44

55
import java.io.*;
6-
import java.nio.channels.FileChannel;
6+
import java.util.Date;
77
import java.util.HashSet;
88
import java.util.UUID;
9-
import java.util.Date;
109
import java.util.concurrent.*;
1110
import java.util.concurrent.atomic.AtomicInteger;
1211

@@ -37,7 +36,7 @@ public static GXDebugManager getInstance()
3736
return instance;
3837
}
3938

40-
private static int BUFFER_INITIAL_SIZE = 16383;
39+
private static final int BUFFER_INITIAL_SIZE = 16383;
4140
private static final long TICKS_NOT_SET = Long.MAX_VALUE;
4241
private static final long TICKS_NOT_NEEDED = 0;
4342
private static String fileName = "gxperf.gxd";
@@ -54,7 +53,7 @@ private GXDebugManager()
5453
}
5554
sessionGuid = UUID.randomUUID();
5655
lastSId = new AtomicInteger();
57-
executorService = new ThreadPoolExecutor(0, 1, 5, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());
56+
executorService = new ThreadPoolExecutor(0, 1, 5, TimeUnit.MINUTES, new SynchronousQueue<>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
5857
pushSystem(GXDebugMsgCode.INITIALIZE.toByteInt(), new Date());
5958
}
6059

@@ -88,11 +87,11 @@ private int newSId()
8887

8988
private GXDebugItem [] current, next, toSave;
9089
private boolean saving = false;
91-
private int dbgIndex = 0;
90+
private volatile int dbgIndex = 0;
9291
private final Object saveLock = new Object();
9392
private final Object mSaveLock = new Object();
94-
private final ConcurrentHashMap<String, GXDebugInfo> parentTable = new ConcurrentHashMap<String, GXDebugInfo>();
95-
private final HashSet<IntPair> pgmInfoTable = new HashSet<IntPair>();
93+
private final ConcurrentHashMap<String, GXDebugInfo> parentTable = new ConcurrentHashMap<>();
94+
private final HashSet<IntPair> pgmInfoTable = new HashSet<>();
9695

9796
private static ExecutorService executorService;
9897

@@ -119,13 +118,13 @@ protected GXDebugItem pushRange(GXDebugInfo dbgInfo, int lineNro, int colNro, in
119118
else return mPush(dbgInfo, GXDebugMsgType.PGM_TRACE_RANGE, lineNro, lineNro2, null);
120119
}
121120

122-
private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, int arg2, Object argObj)
121+
private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, int arg2, Object argObj)
123122
{
124123
synchronized (saveLock)
125124
{
126125
if (toSave != null)
127126
{
128-
save(toSave);
127+
save(toSave, -1, true);
129128
toSave = null;
130129
}
131130
GXDebugItem currentItem = current[dbgIndex];
@@ -183,13 +182,9 @@ private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1,
183182

184183
}
185184

186-
private void save(GXDebugItem[] toSave)
187-
{
188-
save(toSave, -1, true);
189-
}
190-
191185
private void save(GXDebugItem[] toSave, int saveTop, boolean saveInThread)
192186
{
187+
// This method always runs inside the critical section defined by saveLock
193188
int saveCount = 0;
194189
if (saveTop == -1)
195190
{
@@ -237,15 +232,16 @@ else if(saveTop == 0)
237232
final GXDebugItem[] mToSave = toSave;
238233
final int mSaveTop = saveTop;
239234
final int mSaveCount = saveCount;
240-
executorService.execute(new Runnable(){public void run(){mSave(mToSave, mSaveTop, mSaveCount);}});
235+
executorService.execute(() -> mSave(mToSave, mSaveTop, mSaveCount));
241236
}
242237
else mSave(toSave, saveTop, saveCount );
243-
}
238+
}
244239

245240
protected void onExit(GXDebugInfo dbgInfo)
246241
{
247242
pushSystem(GXDebugMsgCode.EXIT.toByteInt());
248243
save();
244+
executorService.shutdown();
249245
}
250246

251247
protected void onCleanup(GXDebugInfo dbgInfo)
@@ -270,7 +266,7 @@ private void save()
270266
{
271267
if (toSave != null)
272268
{
273-
save(toSave);
269+
save(toSave, -1, true);
274270
toSave = null;
275271
}
276272
save(current, dbgIndex, false);
@@ -288,7 +284,7 @@ private void clearDebugItem(GXDebugItem dbgItem)
288284

289285
private void mSave(GXDebugItem [] data, int saveTop, int saveCount)
290286
{
291-
synchronized(mSaveLock)
287+
synchronized(mSaveLock)
292288
{
293289
// Obtengo chunk a grabar
294290
int idx = 0;
@@ -302,65 +298,66 @@ private void mSave(GXDebugItem [] data, int saveTop, int saveCount)
302298
for (; idx < saveTop; idx++)
303299
{
304300
GXDebugItem dbgItem = data[idx];
305-
switch (dbgItem.msgType)
306-
{
307-
case SYSTEM:
308-
{
309-
stream.writeByte((dbgItem.msgType.toByteInt() | (GXDebugMsgCode.valueOf(dbgItem.arg1).toByteInt())));
310-
switch (GXDebugMsgCode.valueOf(dbgItem.arg1))
311-
{
312-
case INITIALIZE:
313-
stream.writeLong(ToTicks((Date) dbgItem.argObj));
314-
break;
315-
case OBJ_CLEANUP:
316-
stream.writeVLUInt((Integer) dbgItem.argObj);
317-
break;
318-
case EXIT:
301+
switch (dbgItem.msgType)
302+
{
303+
case SYSTEM:
304+
{
305+
stream.writeByte((dbgItem.msgType.toByteInt() | (GXDebugMsgCode.valueOf(dbgItem.arg1).toByteInt())));
306+
switch (GXDebugMsgCode.valueOf(dbgItem.arg1))
307+
{
308+
case INITIALIZE:
309+
stream.writeLong(ToTicks((Date) dbgItem.argObj));
310+
break;
311+
case OBJ_CLEANUP:
312+
stream.writeVLUInt((Integer) dbgItem.argObj);
313+
break;
314+
case EXIT:
315+
break;
319316
case PGM_INFO:
320-
Object [] info = (Object[])dbgItem.argObj;
321-
stream.writeVLUInt(((IntPair)info[0]).left);
322-
stream.writeVLUInt(((IntPair)info[0]).right);
323-
stream.writeVLUInt(((PgmInfo)info[1]).dbgLines);
324-
stream.writeInt(((PgmInfo)info[1]).hash);
325-
break;
326-
default:
327-
throw new IllegalArgumentException(String.format("Invalid DbgItem: %s", dbgItem));
328-
}
329-
}
330-
break;
331-
case PGM_TRACE:
332-
{
333-
stream.writePgmTrace(dbgItem.dbgInfo.sId, dbgItem.arg1, dbgItem.arg2, dbgItem.ticks);
334-
}
335-
break;
317+
Object[] info = (Object[]) dbgItem.argObj;
318+
stream.writeVLUInt(((IntPair) info[0]).left);
319+
stream.writeVLUInt(((IntPair) info[0]).right);
320+
stream.writeVLUInt(((PgmInfo) info[1]).dbgLines);
321+
stream.writeInt(((PgmInfo) info[1]).hash);
322+
break;
323+
default:
324+
throw new IllegalArgumentException(String.format("Invalid DbgItem: %s", dbgItem));
325+
}
326+
}
327+
break;
328+
case PGM_TRACE:
329+
{
330+
stream.writePgmTrace(dbgItem.dbgInfo.sId, dbgItem.arg1, dbgItem.arg2, dbgItem.ticks);
331+
}
332+
break;
336333
case PGM_TRACE_RANGE:
337334
case PGM_TRACE_RANGE_WITH_COLS:
338335
{
339336
stream.writeByte(dbgItem.msgType.toByteInt());
340337
stream.writeVLUInt(dbgItem.dbgInfo.sId);
341338
stream.writeVLUInt(dbgItem.arg1);
342339
stream.writeVLUInt(dbgItem.arg2);
343-
if(dbgItem.msgType == GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS)
340+
if (dbgItem.msgType == GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS)
344341
{
345-
stream.writeVLUInt(((IntPair)dbgItem.argObj).left);
346-
stream.writeVLUInt(((IntPair)dbgItem.argObj).right);
342+
stream.writeVLUInt(((IntPair) dbgItem.argObj).left);
343+
stream.writeVLUInt(((IntPair) dbgItem.argObj).right);
347344
}
348345
}
349346
break;
350-
case REGISTER_PGM:
351-
{
352-
stream.writeByte(dbgItem.msgType.toByteInt());
353-
stream.writeVLUInt(dbgItem.dbgInfo.sId);
354-
stream.writeVLUInt(dbgItem.arg1);
355-
stream.writeVLUInt(((IntPair) dbgItem.argObj).left);
356-
stream.writeVLUInt(((IntPair) dbgItem.argObj).right);
357-
}
358-
break;
359-
case SKIP:
360-
continue;
361-
}
362-
clearDebugItem(dbgItem);
363-
}
347+
case REGISTER_PGM:
348+
{
349+
stream.writeByte(dbgItem.msgType.toByteInt());
350+
stream.writeVLUInt(dbgItem.dbgInfo.sId);
351+
stream.writeVLUInt(dbgItem.arg1);
352+
stream.writeVLUInt(((IntPair) dbgItem.argObj).left);
353+
stream.writeVLUInt(((IntPair) dbgItem.argObj).right);
354+
}
355+
break;
356+
case SKIP:
357+
continue;
358+
}
359+
clearDebugItem(dbgItem);
360+
}
364361
} finally
365362
{
366363
if (stream != null)
@@ -460,7 +457,7 @@ private int toByteInt()
460457
}
461458

462459

463-
class GXDebugItem
460+
static class GXDebugItem
464461
{
465462
GXDebugInfo dbgInfo;
466463
int arg1;
@@ -478,7 +475,7 @@ public String toString()
478475
private String toStringTicks(){ return (msgType == GXDebugMsgType.PGM_TRACE ? String.format(" elapsed:%d", ticks) : ""); }
479476
}
480477

481-
class IntPair
478+
static class IntPair
482479
{
483480
final int left;
484481
final int right;
@@ -505,7 +502,7 @@ public boolean equals(Object o)
505502

506503
}
507504

508-
class PgmInfo
505+
static class PgmInfo
509506
{
510507
final int dbgLines;
511508
final long hash;
@@ -552,7 +549,7 @@ public final void restart()
552549

553550
static class GXDebugStream extends FilterOutputStream
554551
{
555-
class ESCAPE
552+
static class ESCAPE
556553
{
557554
static final byte PROLOG = 0;
558555
static final byte EPILOG = 1;
@@ -565,15 +562,12 @@ class ESCAPE
565562

566563
static GXDebugStream getStream(String fileName) throws IOException
567564
{
568-
try (FileOutputStream stream = new FileOutputStream(fileName, true)){
569-
return new GXDebugStream(new BufferedOutputStream(stream), stream.getChannel());
570-
}
565+
return new GXDebugStream(fileName);
571566
}
572567

573-
private GXDebugStream(OutputStream stream, FileChannel channel) throws IOException
568+
private GXDebugStream(String fileName) throws IOException
574569
{
575-
this(stream);
576-
channel.lock();
570+
this(new BufferedOutputStream(new FileOutputStream(fileName, true)));
577571
}
578572

579573
GXDebugStream(OutputStream stream)
@@ -588,8 +582,8 @@ private GXDebugStream(OutputStream stream, FileChannel channel) throws IOExcepti
588582
public void close() throws IOException
589583
{
590584
writeEpilog();
591-
super.close();
592-
}
585+
super.close();
586+
}
593587

594588
private void writeProlog(short version) throws IOException
595589
{
@@ -610,7 +604,11 @@ public void write(byte[] data) throws IOException
610604

611605
void writeRaw(byte[] data, int from, int length) throws IOException
612606
{
613-
super.write(data, from, length);
607+
if ((from | length | (data.length - (length + from)) | (from + length)) < 0)
608+
throw new IndexOutOfBoundsException();
609+
610+
while (length-- > 0)
611+
writeRaw(data[from++]);
614612
}
615613

616614
void writeRaw(byte value) throws IOException
@@ -625,16 +623,17 @@ public void write(byte[] data, int offset, int count) throws IOException
625623
writeByte(data[offset++]);
626624
}
627625

628-
private int last, lastLast;
626+
private volatile int last, lastLast;
629627

630628
@Override
631-
public void write(int value)throws IOException
629+
public void write(int value) throws IOException
632630
{
633631
writeByte(value);
634632
}
635633

636634
void writeByte(int value) throws IOException
637635
{
636+
value &= 0xFF;
638637
super.write(value);
639638
if (value == 0xFF &&
640639
value == last &&
@@ -703,7 +702,7 @@ void writeInt(long value) throws IOException
703702
}
704703
}
705704

706-
private int LastSId, LastLine1;
705+
private volatile int LastSId, LastLine1;
707706

708707
void writePgmTrace(int SId, int line1, int col, long ticks) throws IOException
709708
{

0 commit comments

Comments
 (0)