9
9
#include " llama.h"
10
10
#include " napi.h"
11
11
12
- Napi::FunctionReference loggerCallbackFunctionReference;
13
- Napi::ThreadSafeFunction threadSafeLoggerCallback;
14
- bool loggerCallbackSet = false ;
15
- int addonLoggerLogLevel = 5 ;
16
-
17
12
struct addon_logger_log {
18
13
const int logLevelNumber;
19
14
const std::stringstream* stringStream;
20
15
};
21
16
17
+ using AddonThreadSafeLogCallbackFunctionContext = Napi::Reference<Napi::Value>;
18
+ void addonCallJsLogCallback (
19
+ Napi::Env env,
20
+ Napi::Function callback,
21
+ AddonThreadSafeLogCallbackFunctionContext *context,
22
+ addon_logger_log* data
23
+ );
24
+ using AddonThreadSafeLogCallbackFunction = Napi::TypedThreadSafeFunction<
25
+ AddonThreadSafeLogCallbackFunctionContext,
26
+ addon_logger_log,
27
+ addonCallJsLogCallback
28
+ >;
29
+
30
+ AddonThreadSafeLogCallbackFunction addonThreadSafeLoggerCallback;
31
+ bool addonJsLoggerCallbackSet = false ;
32
+ int addonLoggerLogLevel = 5 ;
33
+
22
34
std::string addon_model_token_to_piece (const struct llama_model * model, llama_token token) {
23
35
std::vector<char > result (8 , 0 );
24
36
const int n_tokens = llama_token_to_piece (model, token, result.data (), result.size ());
@@ -820,14 +832,31 @@ int addonGetGgmlLogLevelNumber(ggml_log_level level) {
820
832
return 1 ;
821
833
}
822
834
823
- static void addonWrapperJSLogCallback (Napi::Env env, Napi::Function jsCallback, addon_logger_log* data) {
824
- auto status = jsCallback.Call ({
825
- Napi::Number::New (env, data->logLevelNumber ),
826
- Napi::String::New (env, data->stringStream ->str ())
827
- });
835
+ void addonCallJsLogCallback (
836
+ Napi::Env env,
837
+ Napi::Function callback,
838
+ AddonThreadSafeLogCallbackFunctionContext * context,
839
+ addon_logger_log * data
840
+ ) {
841
+ if (env != nullptr && callback != nullptr ) {
842
+ callback.Call ({
843
+ Napi::Number::New (env, data->logLevelNumber ),
844
+ Napi::String::New (env, data->stringStream ->str ())
845
+ });
846
+ } else if (data != nullptr ) {
847
+ if (data->logLevelNumber == 2 ) {
848
+ fputs (data->stringStream ->str ().c_str (), stderr);
849
+ fflush (stderr);
850
+ } else {
851
+ fputs (data->stringStream ->str ().c_str (), stdout);
852
+ fflush (stdout);
853
+ }
854
+ }
828
855
829
- delete data->stringStream ;
830
- delete data;
856
+ if (data != nullptr ) {
857
+ delete data->stringStream ;
858
+ delete data;
859
+ }
831
860
}
832
861
833
862
static void addonLlamaCppLogCallback (ggml_log_level level, const char * text, void * user_data) {
@@ -837,7 +866,7 @@ static void addonLlamaCppLogCallback(ggml_log_level level, const char * text, vo
837
866
return ;
838
867
}
839
868
840
- if (loggerCallbackSet ) {
869
+ if (addonJsLoggerCallbackSet ) {
841
870
std::stringstream* stringStream = new std::stringstream ();
842
871
if (text != nullptr ) {
843
872
*stringStream << text;
@@ -848,14 +877,14 @@ static void addonLlamaCppLogCallback(ggml_log_level level, const char * text, vo
848
877
stringStream
849
878
};
850
879
851
- auto status = threadSafeLoggerCallback .NonBlockingCall (data, addonWrapperJSLogCallback );
880
+ auto status = addonThreadSafeLoggerCallback .NonBlockingCall (data);
852
881
853
882
if (status == napi_ok) {
854
883
return ;
855
884
}
856
885
}
857
886
858
- if (level == GGML_LOG_LEVEL_ERROR ) {
887
+ if (level == 2 ) {
859
888
fputs (text, stderr);
860
889
fflush (stderr);
861
890
} else {
@@ -866,28 +895,41 @@ static void addonLlamaCppLogCallback(ggml_log_level level, const char * text, vo
866
895
867
896
Napi::Value setLogger (const Napi::CallbackInfo& info) {
868
897
if (info.Length () < 1 || !info[0 ].IsFunction ()) {
869
- if (loggerCallbackSet) {
870
- threadSafeLoggerCallback.Release ();
871
- threadSafeLoggerCallback = nullptr ;
872
- loggerCallbackFunctionReference.Unref ();
873
- loggerCallbackSet = false ;
898
+ if (addonJsLoggerCallbackSet) {
899
+ addonJsLoggerCallbackSet = false ;
900
+ addonThreadSafeLoggerCallback.Release ();
874
901
}
875
902
876
903
return info.Env ().Undefined ();
877
904
}
878
905
879
- loggerCallbackFunctionReference = Napi::Persistent (info[0 ].As <Napi::Function>());
880
- loggerCallbackFunctionReference.Ref ();
881
- threadSafeLoggerCallback = Napi::ThreadSafeFunction::New (info.Env (), loggerCallbackFunctionReference.Value (), " loggerCallback" , 0 , 1 );
882
- loggerCallbackSet = true ;
906
+ auto addonLoggerJSCallback = info[0 ].As <Napi::Function>();
907
+ AddonThreadSafeLogCallbackFunctionContext *context = new Napi::Reference<Napi::Value>(Napi::Persistent (info.This ()));
908
+ addonThreadSafeLoggerCallback = AddonThreadSafeLogCallbackFunction::New (
909
+ info.Env (),
910
+ addonLoggerJSCallback,
911
+ " loggerCallback" ,
912
+ 0 ,
913
+ 1 ,
914
+ context,
915
+ []( Napi::Env, void *, AddonThreadSafeLogCallbackFunctionContext *ctx ) {
916
+ addonJsLoggerCallbackSet = false ;
917
+
918
+ delete ctx;
919
+ }
920
+ );
921
+ addonJsLoggerCallbackSet = true ;
922
+
923
+ // prevent blocking the main node process from exiting due to active resources
924
+ addonThreadSafeLoggerCallback.Unref (info.Env ());
883
925
884
926
return info.Env ().Undefined ();
885
927
}
886
928
887
929
Napi::Value setLoggerLogLevel (const Napi::CallbackInfo& info) {
888
930
if (info.Length () < 1 || !info[0 ].IsNumber ()) {
889
931
addonLoggerLogLevel = 5 ;
890
-
932
+
891
933
return info.Env ().Undefined ();
892
934
}
893
935
0 commit comments