Skip to content

Commit

Permalink
Fix multithread issue in FJavascriptOutputDevice
Browse files Browse the repository at this point in the history
  • Loading branch information
dochigun-nc committed Mar 27, 2023
1 parent bf0a793 commit d213d5f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
60 changes: 57 additions & 3 deletions Source/V8/Private/JavascriptOutputDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "UObject/UObjectThreadContext.h"

/** This class is to capture all log output even if the log window is closed */
class FJavascriptOutputDevice : public FOutputDevice
class FJavascriptOutputDevice : public FOutputDevice, public FTickableGameObject
{
public:
UJavascriptOutputDevice* OutputDevice;
Expand All @@ -23,20 +23,74 @@ class FJavascriptOutputDevice : public FOutputDevice
GLog->RemoveOutputDevice(this);
}
}

virtual void Tick(float DeltaTime) override
{
SubmitPendingMessages();
}

virtual TStatId GetStatId() const override
{
RETURN_QUICK_DECLARE_CYCLE_STAT(FJavascriptOutputDevice, STATGROUP_Tickables);
}

protected:
struct FLogMessage
{
TSharedRef<FString> Message;
ELogVerbosity::Type Verbosity;
FName Category;

FLogMessage(const TSharedRef<FString>& NewMessage, ELogVerbosity::Type NewVerbosity, FName NewCategory)
: Message(NewMessage)
, Verbosity(NewVerbosity)
, Category(NewCategory)
{
}
};

virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category) override
{
FScopeLock PendingMessagesAccess(&PendingMessagesCriticalSection);
PendingMessages.Add(MakeShared<FLogMessage>(MakeShared<FString>(V), Verbosity, Category));
}

void SubmitPendingMessages()
{
TArray<TSharedPtr<FLogMessage>> Messages;

if (PendingMessagesCriticalSection.TryLock())
{
Messages = MoveTemp(PendingMessages);
PendingMessages.Reset();
PendingMessagesCriticalSection.Unlock();
}
else
{
return;
}

for (const auto& Message : Messages)
{
SubmitPendingMessage(Message->Message, Message->Verbosity, Message->Category);
}
}

void SubmitPendingMessage(TSharedPtr<FString> Message, ELogVerbosity::Type Verbosity, const class FName& Category)
{
static bool bIsReentrant = false;
if (bIsReentrant) return;

TGuardValue<bool> ReentrantGuard(bIsReentrant, true);
if (!OutputDevice->IsUnreachable() && !FUObjectThreadContext::Get().IsRoutingPostLoad)
{
OutputDevice->OnMessage(V, (ELogVerbosity_JS)Verbosity, Category);
}
OutputDevice->OnMessage(*Message, (ELogVerbosity_JS)Verbosity, Category);
}
}

private:
TArray<TSharedPtr<FLogMessage>> PendingMessages;
FCriticalSection PendingMessagesCriticalSection;
};

UJavascriptOutputDevice::UJavascriptOutputDevice(const FObjectInitializer& ObjectInitializer)
Expand Down
4 changes: 2 additions & 2 deletions UnrealJS.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"FileVersion": 3,
"FriendlyName": "Unreal.js - Javascript Runtime",
"Version": 2,
"VersionName": "0.6.3",
"FriendlyVersion": "0.6.3",
"VersionName": "0.6.4",
"FriendlyVersion": "0.6.4",
"EngineVersion": "5.1.0",
"Description": "Javascript powered UnrealEngine",
"Category": "Programming",
Expand Down

0 comments on commit d213d5f

Please sign in to comment.