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.
4
5#include "common.h"
6#include "eventpipe.h"
7#include "eventpipeprovider.h"
8#include "eventpipesession.h"
9
10#ifdef FEATURE_PERFTRACING
11
12EventPipeSession::EventPipeSession(
13 EventPipeSessionType sessionType,
14 unsigned int circularBufferSizeInMB,
15 EventPipeProviderConfiguration *pProviders,
16 unsigned int numProviders,
17 UINT64 multiFileTraceLengthInSeconds)
18{
19 CONTRACTL
20 {
21 THROWS;
22 GC_NOTRIGGER;
23 MODE_ANY;
24 }
25 CONTRACTL_END;
26
27 m_sessionType = sessionType;
28 m_circularBufferSizeInBytes = circularBufferSizeInMB * 1024 * 1024; // 1MB;
29 m_rundownEnabled = false;
30 m_pProviderList = new EventPipeSessionProviderList(
31 pProviders,
32 numProviders);
33 m_multiFileTraceLengthInSeconds = multiFileTraceLengthInSeconds;
34 GetSystemTimeAsFileTime(&m_sessionStartTime);
35 QueryPerformanceCounter(&m_sessionStartTimeStamp);
36}
37
38EventPipeSession::~EventPipeSession()
39{
40 CONTRACTL
41 {
42 NOTHROW;
43 GC_NOTRIGGER;
44 MODE_ANY;
45 }
46 CONTRACTL_END;
47
48 if(m_pProviderList != NULL)
49 {
50 delete m_pProviderList;
51 m_pProviderList = NULL;
52 }
53}
54
55bool EventPipeSession::IsValid() const
56{
57 LIMITED_METHOD_CONTRACT;
58
59 if((m_pProviderList == NULL) || (m_pProviderList->IsEmpty()))
60 {
61 return false;
62 }
63
64 return true;
65}
66
67void EventPipeSession::AddSessionProvider(EventPipeSessionProvider *pProvider)
68{
69 CONTRACTL
70 {
71 THROWS;
72 GC_NOTRIGGER;
73 MODE_ANY;
74 }
75 CONTRACTL_END;
76
77 m_pProviderList->AddSessionProvider(pProvider);
78}
79
80EventPipeSessionProvider* EventPipeSession::GetSessionProvider(EventPipeProvider *pProvider)
81{
82 CONTRACTL
83 {
84 THROWS;
85 GC_NOTRIGGER;
86 MODE_ANY;
87 }
88 CONTRACTL_END;
89
90 return m_pProviderList->GetSessionProvider(pProvider);
91}
92
93EventPipeSessionProviderList::EventPipeSessionProviderList(
94 EventPipeProviderConfiguration *pConfigs,
95 unsigned int numConfigs)
96{
97 CONTRACTL
98 {
99 THROWS;
100 GC_NOTRIGGER;
101 MODE_ANY;
102 }
103 CONTRACTL_END;
104
105 m_pProviders = new SList<SListElem<EventPipeSessionProvider*>>();
106 m_pCatchAllProvider = NULL;
107 for(unsigned int i=0; i<numConfigs; i++)
108 {
109 EventPipeProviderConfiguration *pConfig = &pConfigs[i];
110
111 // Enable all events if the provider name == '*', all keywords are on and the requested level == verbose.
112 if((wcscmp(W("*"), pConfig->GetProviderName()) == 0) && (pConfig->GetKeywords() == 0xFFFFFFFFFFFFFFFF) && ((EventPipeEventLevel)pConfig->GetLevel() == EventPipeEventLevel::Verbose) && (m_pCatchAllProvider == NULL))
113 {
114 m_pCatchAllProvider = new EventPipeSessionProvider(NULL, 0xFFFFFFFFFFFFFFFF, EventPipeEventLevel::Verbose, NULL);
115 }
116 else
117 {
118 EventPipeSessionProvider *pProvider = new EventPipeSessionProvider(
119 pConfig->GetProviderName(),
120 pConfig->GetKeywords(),
121 (EventPipeEventLevel)pConfig->GetLevel(),
122 pConfig->GetFilterData());
123
124 m_pProviders->InsertTail(new SListElem<EventPipeSessionProvider*>(pProvider));
125 }
126 }
127}
128
129EventPipeSessionProviderList::~EventPipeSessionProviderList()
130{
131 CONTRACTL
132 {
133 NOTHROW;
134 GC_NOTRIGGER;
135 MODE_ANY;
136 }
137 CONTRACTL_END;
138
139 if(m_pProviders != NULL)
140 {
141 SListElem<EventPipeSessionProvider*> *pElem = m_pProviders->GetHead();
142 while(pElem != NULL)
143 {
144 EventPipeSessionProvider *pProvider = pElem->GetValue();
145 delete pProvider;
146
147 SListElem<EventPipeSessionProvider*> *pCurElem = pElem;
148 pElem = m_pProviders->GetNext(pElem);
149 delete pCurElem;
150 }
151
152 delete m_pProviders;
153 m_pProviders = NULL;
154 }
155 if(m_pCatchAllProvider != NULL)
156 {
157 delete(m_pCatchAllProvider);
158 m_pCatchAllProvider = NULL;
159 }
160}
161
162void EventPipeSessionProviderList::AddSessionProvider(EventPipeSessionProvider *pProvider)
163{
164 CONTRACTL
165 {
166 THROWS;
167 GC_NOTRIGGER;
168 MODE_ANY;
169 }
170 CONTRACTL_END;
171
172 if(pProvider != NULL)
173 {
174 m_pProviders->InsertTail(new SListElem<EventPipeSessionProvider*>(pProvider));
175 }
176}
177
178EventPipeSessionProvider* EventPipeSessionProviderList::GetSessionProvider(
179 EventPipeProvider *pProvider)
180{
181 CONTRACTL
182 {
183 THROWS;
184 GC_NOTRIGGER;
185 MODE_ANY;
186 }
187 CONTRACTL_END;
188
189 // Exists when tracing was enabled at start-up and all events were requested. This is a diagnostic config.
190 if(m_pCatchAllProvider != NULL)
191 {
192 return m_pCatchAllProvider;
193 }
194
195 if(m_pProviders == NULL)
196 {
197 return NULL;
198 }
199
200 SString providerNameStr = pProvider->GetProviderName();
201 LPCWSTR providerName = providerNameStr.GetUnicode();
202
203 EventPipeSessionProvider *pSessionProvider = NULL;
204 SListElem<EventPipeSessionProvider*> *pElem = m_pProviders->GetHead();
205 while(pElem != NULL)
206 {
207 EventPipeSessionProvider *pCandidate = pElem->GetValue();
208 if(wcscmp(providerName, pCandidate->GetProviderName()) == 0)
209 {
210 pSessionProvider = pCandidate;
211 break;
212 }
213 pElem = m_pProviders->GetNext(pElem);
214 }
215
216 return pSessionProvider;
217}
218
219bool EventPipeSessionProviderList::IsEmpty() const
220{
221 LIMITED_METHOD_CONTRACT;
222
223 return (m_pProviders->IsEmpty() && m_pCatchAllProvider == NULL);
224}
225
226EventPipeSessionProvider::EventPipeSessionProvider(
227 LPCWSTR providerName,
228 UINT64 keywords,
229 EventPipeEventLevel loggingLevel,
230 LPCWSTR filterData)
231{
232 CONTRACTL
233 {
234 THROWS;
235 GC_NOTRIGGER;
236 MODE_ANY;
237 }
238 CONTRACTL_END;
239
240 if(providerName != NULL)
241 {
242 size_t bufSize = wcslen(providerName) + 1;
243 m_pProviderName = new WCHAR[bufSize];
244 wcscpy_s(m_pProviderName, bufSize, providerName);
245 }
246 else
247 {
248 m_pProviderName = NULL;
249 }
250 m_keywords = keywords;
251 m_loggingLevel = loggingLevel;
252
253 if(filterData != NULL)
254 {
255 size_t bufSize = wcslen(filterData) + 1;
256 m_pFilterData = new WCHAR[bufSize];
257 wcscpy_s(m_pFilterData, bufSize, filterData);
258 }
259 else
260 {
261 m_pFilterData = NULL;
262 }
263}
264
265EventPipeSessionProvider::~EventPipeSessionProvider()
266{
267 CONTRACTL
268 {
269 NOTHROW;
270 GC_NOTRIGGER;
271 MODE_ANY;
272 }
273 CONTRACTL_END;
274
275 // C++ standard, $5.3.5/2: Deleting a NULL pointer is safe.
276 delete[] m_pProviderName;
277 m_pProviderName = NULL;
278
279 delete[] m_pFilterData;
280 m_pFilterData = NULL;
281}
282
283LPCWSTR EventPipeSessionProvider::GetProviderName() const
284{
285 LIMITED_METHOD_CONTRACT;
286 return m_pProviderName;
287}
288
289UINT64 EventPipeSessionProvider::GetKeywords() const
290{
291 LIMITED_METHOD_CONTRACT;
292 return m_keywords;
293}
294
295EventPipeEventLevel EventPipeSessionProvider::GetLevel() const
296{
297 LIMITED_METHOD_CONTRACT;
298 return m_loggingLevel;
299}
300
301LPCWSTR EventPipeSessionProvider::GetFilterData() const
302{
303 LIMITED_METHOD_CONTRACT;
304 return m_pFilterData;
305}
306
307#endif // FEATURE_PERFTRACING
308