Skip to content

Commit d213d5f

Browse files
committed
Fix multithread issue in FJavascriptOutputDevice
1 parent bf0a793 commit d213d5f

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

Source/V8/Private/JavascriptOutputDevice.cpp

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "UObject/UObjectThreadContext.h"
33

44
/** This class is to capture all log output even if the log window is closed */
5-
class FJavascriptOutputDevice : public FOutputDevice
5+
class FJavascriptOutputDevice : public FOutputDevice, public FTickableGameObject
66
{
77
public:
88
UJavascriptOutputDevice* OutputDevice;
@@ -23,20 +23,74 @@ class FJavascriptOutputDevice : public FOutputDevice
2323
GLog->RemoveOutputDevice(this);
2424
}
2525
}
26+
27+
virtual void Tick(float DeltaTime) override
28+
{
29+
SubmitPendingMessages();
30+
}
31+
32+
virtual TStatId GetStatId() const override
33+
{
34+
RETURN_QUICK_DECLARE_CYCLE_STAT(FJavascriptOutputDevice, STATGROUP_Tickables);
35+
}
2636

2737
protected:
38+
struct FLogMessage
39+
{
40+
TSharedRef<FString> Message;
41+
ELogVerbosity::Type Verbosity;
42+
FName Category;
43+
44+
FLogMessage(const TSharedRef<FString>& NewMessage, ELogVerbosity::Type NewVerbosity, FName NewCategory)
45+
: Message(NewMessage)
46+
, Verbosity(NewVerbosity)
47+
, Category(NewCategory)
48+
{
49+
}
50+
};
2851

2952
virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category) override
3053
{
54+
FScopeLock PendingMessagesAccess(&PendingMessagesCriticalSection);
55+
PendingMessages.Add(MakeShared<FLogMessage>(MakeShared<FString>(V), Verbosity, Category));
56+
}
57+
58+
void SubmitPendingMessages()
59+
{
60+
TArray<TSharedPtr<FLogMessage>> Messages;
61+
62+
if (PendingMessagesCriticalSection.TryLock())
63+
{
64+
Messages = MoveTemp(PendingMessages);
65+
PendingMessages.Reset();
66+
PendingMessagesCriticalSection.Unlock();
67+
}
68+
else
69+
{
70+
return;
71+
}
72+
73+
for (const auto& Message : Messages)
74+
{
75+
SubmitPendingMessage(Message->Message, Message->Verbosity, Message->Category);
76+
}
77+
}
78+
79+
void SubmitPendingMessage(TSharedPtr<FString> Message, ELogVerbosity::Type Verbosity, const class FName& Category)
80+
{
3181
static bool bIsReentrant = false;
3282
if (bIsReentrant) return;
3383

3484
TGuardValue<bool> ReentrantGuard(bIsReentrant, true);
3585
if (!OutputDevice->IsUnreachable() && !FUObjectThreadContext::Get().IsRoutingPostLoad)
3686
{
37-
OutputDevice->OnMessage(V, (ELogVerbosity_JS)Verbosity, Category);
38-
}
87+
OutputDevice->OnMessage(*Message, (ELogVerbosity_JS)Verbosity, Category);
88+
}
3989
}
90+
91+
private:
92+
TArray<TSharedPtr<FLogMessage>> PendingMessages;
93+
FCriticalSection PendingMessagesCriticalSection;
4094
};
4195

4296
UJavascriptOutputDevice::UJavascriptOutputDevice(const FObjectInitializer& ObjectInitializer)

UnrealJS.uplugin

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"FileVersion": 3,
33
"FriendlyName": "Unreal.js - Javascript Runtime",
44
"Version": 2,
5-
"VersionName": "0.6.3",
6-
"FriendlyVersion": "0.6.3",
5+
"VersionName": "0.6.4",
6+
"FriendlyVersion": "0.6.4",
77
"EngineVersion": "5.1.0",
88
"Description": "Javascript powered UnrealEngine",
99
"Category": "Programming",

0 commit comments

Comments
 (0)