1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 /**********************************************************************
7 svcworker.cpp -- logic for the runtime implementation of the native
10 Overview: the runtime implementation is accessed via a local COM
11 server implemented in ngen.exe. That server is simply a stub that
12 loads the most recent runtime and calls into the actual implementation
13 in this file. There are three entrypoints in mscorwks.dll that
14 are called by the local service in ngen.exe:
16 NGenWorkerRegisterServer -- called to register ngen.exe as the current
17 COM server for CLSID_CorSvcWorker
18 NGenWorkerUnregisterServer -- unregister ngen.exe as the current COM
19 server for CLSID_CorSvcWorker
20 NGenWorkerEmbedding() -- called when COM invoked the COM server with
21 the "-Embedding" flag. Implements the logic for registering the class
22 factory for CLSID_CorSvcWorker and controlling the lifetime of the
24 **********************************************************************/
33 ILocalServerLifetime *g_pLocalServerLifetime = NULL;
35 SvcLogger::SvcLogger()
41 inline void SvcLogger::CheckInit()
45 StackSString* psstemp = new StackSString();
46 StackSString* pssOrig = InterlockedCompareExchangeT(&pss, psstemp, NULL);
52 SvcLogger::~SvcLogger()
56 // pCorSvcLogger->Release();
63 void SvcLogger::ReleaseLogger()
67 pCorSvcLogger->Release();
72 void SvcLogger::Printf(const CHAR *format, ...)
77 va_start(args, format);
78 s.VPrintf(format, args);
87 wprintf( W("%s"), s.GetUnicode() );
91 void SvcLogger::SvcPrintf(const CHAR *format, ...)
96 va_start(args, format);
97 s.VPrintf(format, args);
103 void SvcLogger::Printf(const WCHAR *format, ...)
108 va_start(args, format);
109 s.VPrintf(format, args);
118 wprintf( W("%s"), s.GetUnicode() );
122 void SvcLogger::Printf(CorSvcLogLevel logLevel, const WCHAR *format, ...)
127 va_start(args, format);
128 s.VPrintf(format, args);
133 LogHelper(s, logLevel);
137 wprintf( W("%s"), s.GetUnicode());
141 void SvcLogger::SvcPrintf(const WCHAR *format, ...)
146 va_start(args, format);
147 s.VPrintf(format, args);
153 void SvcLogger::Log(const WCHAR *message, CorSvcLogLevel logLevel)
155 LogHelper(StackSString(message), logLevel);
158 void SvcLogger::LogHelper(SString s, CorSvcLogLevel logLevel)
163 // Does s contain a newline?
164 SString::Iterator i = pss->Begin();
165 if (pss->FindASCII(i, "\n"))
169 BSTRHolder bstrHolder(::SysAllocString(pss->GetUnicode()));
170 // Can't use the IfFailThrow macro here because in checked
171 // builds that macros will try to log an error message
172 // that will recursively return to this method.
173 HRESULT hr = pCorSvcLogger->Log(logLevel, bstrHolder);
181 void SvcLogger::SetSvcLogger(ICorSvcLogger *pCorSvcLoggerArg)
184 this->pCorSvcLogger = pCorSvcLoggerArg;
185 if (pCorSvcLoggerArg)
187 pCorSvcLogger->AddRef();
191 BOOL SvcLogger::HasSvcLogger()
193 return (this->pCorSvcLogger != NULL);
196 ICorSvcLogger* SvcLogger::GetSvcLogger()
198 return pCorSvcLogger;
204 SvcLogger *g_SvcLogger = NULL;
207 // As NGen is currently single-threaded, this function is intentionally not thread safe.
208 // If necessary, change it into an interlocked function.
209 SvcLogger *GetSvcLogger()
211 if (g_SvcLogger == NULL)
213 g_SvcLogger = new SvcLogger();
220 if (g_SvcLogger != NULL)
222 return g_SvcLogger->HasSvcLogger();
227 #ifdef CROSSGEN_COMPILE
228 void SetSvcLogger(ICorSvcLogger *pCorSvcLogger)
230 GetSvcLogger()->SetSvcLogger(pCorSvcLogger);