blob: 96ad3993fb8725f24a5947d1ad6863da484ddd71 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "trace_impl.h"
12
13#include <cassert>
14#include <string.h> // memset
15
16#ifdef _WIN32
andrew@webrtc.org59ccd5c2011-12-15 00:17:43 +000017#include "trace_win.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000018#else
19#include <stdio.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000020#include <stdarg.h>
ajm@google.comb5c49ff2011-08-01 17:04:04 +000021#include "trace_posix.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000022#endif // _WIN32
23
hta@webrtc.org41adcdb2012-06-18 11:24:57 +000024#include "system_wrappers/interface/sleep.h"
25
niklase@google.com470e71d2011-07-07 08:21:25 +000026#define KEY_LEN_CHARS 31
27
28#ifdef _WIN32
andrew@webrtc.org5dffebc2012-08-16 04:24:05 +000029#pragma warning(disable:4355)
niklase@google.com470e71d2011-07-07 08:21:25 +000030#endif // _WIN32
31
32namespace webrtc {
33static WebRtc_UWord32 levelFilter = kTraceDefault;
34
35// Construct On First Use idiom. Avoids "static initialization order fiasco".
henrike@webrtc.org315282c2011-12-09 17:46:20 +000036TraceImpl* TraceImpl::StaticInstance(CountOperation count_operation,
37 const TraceLevel level)
niklase@google.com470e71d2011-07-07 08:21:25 +000038{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000039 // Sanities to avoid taking lock unless absolutely necessary (for
40 // performance reasons).
41 // count_operation == kAddRefNoCreate implies that a message will be
42 // written to file.
43 if((level != kTraceAll) && (count_operation == kAddRefNoCreate))
niklase@google.com470e71d2011-07-07 08:21:25 +000044 {
45 if(!(level & levelFilter))
46 {
47 return NULL;
48 }
49 }
henrike@webrtc.org315282c2011-12-09 17:46:20 +000050 TraceImpl* impl =
51 GetStaticInstance<TraceImpl>(count_operation);
52 return impl;
niklase@google.com470e71d2011-07-07 08:21:25 +000053}
54
niklase@google.com470e71d2011-07-07 08:21:25 +000055TraceImpl* TraceImpl::GetTrace(const TraceLevel level)
56{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000057 return StaticInstance(kAddRefNoCreate, level);
niklase@google.com470e71d2011-07-07 08:21:25 +000058}
59
henrike@webrtc.org315282c2011-12-09 17:46:20 +000060TraceImpl* TraceImpl::CreateInstance()
niklase@google.com470e71d2011-07-07 08:21:25 +000061{
henrike@webrtc.org2f47b5a2011-12-10 00:44:47 +000062#if defined(_WIN32)
niklase@google.com470e71d2011-07-07 08:21:25 +000063 return new TraceWindows();
64#else
ajm@google.comb5c49ff2011-08-01 17:04:04 +000065 return new TracePosix();
niklase@google.com470e71d2011-07-07 08:21:25 +000066#endif
67}
68
69TraceImpl::TraceImpl()
henrike@webrtc.orgbfa80ce2011-12-15 17:59:58 +000070 : _critsectInterface(CriticalSectionWrapper::CreateCriticalSection()),
niklase@google.com470e71d2011-07-07 08:21:25 +000071 _callback(NULL),
72 _rowCountText(0),
73 _fileCountText(0),
74 _traceFile(*FileWrapper::Create()),
75 _thread(*ThreadWrapper::CreateThread(TraceImpl::Run, this,
76 kHighestPriority, "Trace")),
77 _event(*EventWrapper::Create()),
henrike@webrtc.orgbfa80ce2011-12-15 17:59:58 +000078 _critsectArray(CriticalSectionWrapper::CreateCriticalSection()),
niklase@google.com470e71d2011-07-07 08:21:25 +000079 _nextFreeIdx(),
80 _level(),
81 _length(),
82 _messageQueue(),
83 _activeQueue(0)
84{
85 _nextFreeIdx[0] = 0;
86 _nextFreeIdx[1] = 0;
87
88 unsigned int tid = 0;
89 _thread.Start(tid);
90
91 for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++)
92 {
93 for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++)
94 {
95 _messageQueue[m][n] = new
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +000096 char[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
niklase@google.com470e71d2011-07-07 08:21:25 +000097 }
98 }
99}
100
101bool TraceImpl::StopThread()
102{
103 // Release the worker thread so that it can flush any lingering messages.
104 _event.Set();
105
106 // Allow 10 ms for pending messages to be flushed out.
107 // TODO (hellner): why not use condition variables to do this? Or let the
108 // worker thread die and let this thread flush remaining
109 // messages?
hta@webrtc.org41adcdb2012-06-18 11:24:57 +0000110 SleepMs(10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111
112 _thread.SetNotAlive();
113 // Make sure the thread finishes as quickly as possible (instead of having
114 // to wait for the timeout).
115 _event.Set();
116 bool stopped = _thread.Stop();
117
118 CriticalSectionScoped lock(_critsectInterface);
119 _traceFile.Flush();
120 _traceFile.CloseFile();
121 return stopped;
122}
123
124TraceImpl::~TraceImpl()
125{
126 StopThread();
127 delete &_event;
128 delete &_traceFile;
129 delete &_thread;
henrike@webrtc.orgbfa80ce2011-12-15 17:59:58 +0000130 delete _critsectInterface;
131 delete _critsectArray;
niklase@google.com470e71d2011-07-07 08:21:25 +0000132
133 for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++)
134 {
135 for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++)
136 {
137 delete [] _messageQueue[m][n];
138 }
139 }
140}
141
pwestin@webrtc.orgb54d7272012-01-11 08:28:04 +0000142WebRtc_Word32 TraceImpl::AddThreadId(char* traceMessage) const {
143 WebRtc_UWord32 threadId = ThreadWrapper::GetThreadId();
144 // Messages is 12 characters.
145 return sprintf(traceMessage, "%10u; ", threadId);
146}
147
niklase@google.com470e71d2011-07-07 08:21:25 +0000148WebRtc_Word32 TraceImpl::AddLevel(char* szMessage, const TraceLevel level) const
149{
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000150 const int kMessageLength = 12;
niklase@google.com470e71d2011-07-07 08:21:25 +0000151 switch (level)
152 {
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000153 case kTraceTerseInfo:
154 // Add the appropriate amount of whitespace.
155 memset(szMessage, ' ', kMessageLength);
156 szMessage[kMessageLength] = '\0';
157 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000158 case kTraceStateInfo:
159 sprintf (szMessage, "STATEINFO ; ");
160 break;
161 case kTraceWarning:
162 sprintf (szMessage, "WARNING ; ");
163 break;
164 case kTraceError:
165 sprintf (szMessage, "ERROR ; ");
166 break;
167 case kTraceCritical:
168 sprintf (szMessage, "CRITICAL ; ");
169 break;
170 case kTraceInfo:
171 sprintf (szMessage, "DEBUGINFO ; ");
172 break;
173 case kTraceModuleCall:
174 sprintf (szMessage, "MODULECALL; ");
175 break;
176 case kTraceMemory:
177 sprintf (szMessage, "MEMORY ; ");
178 break;
179 case kTraceTimer:
180 sprintf (szMessage, "TIMER ; ");
181 break;
182 case kTraceStream:
183 sprintf (szMessage, "STREAM ; ");
184 break;
185 case kTraceApiCall:
186 sprintf (szMessage, "APICALL ; ");
187 break;
188 case kTraceDebug:
189 sprintf (szMessage, "DEBUG ; ");
190 break;
191 default:
192 assert(false);
193 return 0;
194 }
195 // All messages are 12 characters.
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000196 return kMessageLength;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197}
198
199WebRtc_Word32 TraceImpl::AddModuleAndId(char* traceMessage,
200 const TraceModule module,
201 const WebRtc_Word32 id) const
202{
203 // Use long int to prevent problems with different definitions of
204 // WebRtc_Word32.
205 // TODO (hellner): is this actually a problem? If so, it should be better to
206 // clean up WebRtc_Word32
207 const long int idl = id;
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000208 const int kMessageLength = 25;
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 if(idl != -1)
210 {
211 const unsigned long int idEngine = id>>16;
212 const unsigned long int idChannel = id & 0xffff;
213
214 switch (module)
215 {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000216 case kTraceUndefined:
217 // Add the appropriate amount of whitespace.
218 memset(traceMessage, ' ', kMessageLength);
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000219 traceMessage[kMessageLength] = '\0';
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000220 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000221 case kTraceVoice:
222 sprintf(traceMessage, " VOICE:%5ld %5ld;", idEngine,
223 idChannel);
224 break;
225 case kTraceVideo:
226 sprintf(traceMessage, " VIDEO:%5ld %5ld;", idEngine,
227 idChannel);
228 break;
229 case kTraceUtility:
230 sprintf(traceMessage, " UTILITY:%5ld %5ld;", idEngine,
231 idChannel);
232 break;
233 case kTraceRtpRtcp:
234 sprintf(traceMessage, " RTP/RTCP:%5ld %5ld;", idEngine,
235 idChannel);
236 break;
237 case kTraceTransport:
238 sprintf(traceMessage, " TRANSPORT:%5ld %5ld;", idEngine,
239 idChannel);
240 break;
241 case kTraceAudioCoding:
242 sprintf(traceMessage, "AUDIO CODING:%5ld %5ld;", idEngine,
243 idChannel);
244 break;
245 case kTraceSrtp:
246 sprintf(traceMessage, " SRTP:%5ld %5ld;", idEngine,
247 idChannel);
248 break;
249 case kTraceAudioMixerServer:
250 sprintf(traceMessage, " AUDIO MIX/S:%5ld %5ld;", idEngine,
251 idChannel);
252 break;
253 case kTraceAudioMixerClient:
254 sprintf(traceMessage, " AUDIO MIX/C:%5ld %5ld;", idEngine,
255 idChannel);
256 break;
257 case kTraceVideoCoding:
258 sprintf(traceMessage, "VIDEO CODING:%5ld %5ld;", idEngine,
259 idChannel);
260 break;
261 case kTraceVideoMixer:
262 // Print sleep time and API call
263 sprintf(traceMessage, " VIDEO MIX:%5ld %5ld;", idEngine,
264 idChannel);
265 break;
266 case kTraceFile:
267 sprintf(traceMessage, " FILE:%5ld %5ld;", idEngine,
268 idChannel);
269 break;
270 case kTraceAudioProcessing:
271 sprintf(traceMessage, " AUDIO PROC:%5ld %5ld;", idEngine,
272 idChannel);
273 break;
274 case kTraceAudioDevice:
275 sprintf(traceMessage, "AUDIO DEVICE:%5ld %5ld;", idEngine,
276 idChannel);
277 break;
278 case kTraceVideoRenderer:
279 sprintf(traceMessage, "VIDEO RENDER:%5ld %5ld;", idEngine,
280 idChannel);
281 break;
282 case kTraceVideoCapture:
283 sprintf(traceMessage, "VIDEO CAPTUR:%5ld %5ld;", idEngine,
284 idChannel);
285 break;
286 case kTraceVideoPreocessing:
287 sprintf(traceMessage, " VIDEO PROC:%5ld %5ld;", idEngine,
288 idChannel);
289 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000290 }
291 } else {
292 switch (module)
293 {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000294 case kTraceUndefined:
295 // Add the appropriate amount of whitespace.
296 memset(traceMessage, ' ', kMessageLength);
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000297 traceMessage[kMessageLength] = '\0';
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000298 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 case kTraceVoice:
300 sprintf (traceMessage, " VOICE:%11ld;", idl);
301 break;
302 case kTraceVideo:
303 sprintf (traceMessage, " VIDEO:%11ld;", idl);
304 break;
305 case kTraceUtility:
306 sprintf (traceMessage, " UTILITY:%11ld;", idl);
307 break;
308 case kTraceRtpRtcp:
309 sprintf (traceMessage, " RTP/RTCP:%11ld;", idl);
310 break;
311 case kTraceTransport:
312 sprintf (traceMessage, " TRANSPORT:%11ld;", idl);
313 break;
314 case kTraceAudioCoding:
315 sprintf (traceMessage, "AUDIO CODING:%11ld;", idl);
316 break;
317 case kTraceSrtp:
318 sprintf (traceMessage, " SRTP:%11ld;", idl);
319 break;
320 case kTraceAudioMixerServer:
321 sprintf (traceMessage, " AUDIO MIX/S:%11ld;", idl);
322 break;
323 case kTraceAudioMixerClient:
324 sprintf (traceMessage, " AUDIO MIX/C:%11ld;", idl);
325 break;
326 case kTraceVideoCoding:
327 sprintf (traceMessage, "VIDEO CODING:%11ld;", idl);
328 break;
329 case kTraceVideoMixer:
330 sprintf (traceMessage, " VIDEO MIX:%11ld;", idl);
331 break;
332 case kTraceFile:
333 sprintf (traceMessage, " FILE:%11ld;", idl);
334 break;
335 case kTraceAudioProcessing:
336 sprintf (traceMessage, " AUDIO PROC:%11ld;", idl);
337 break;
338 case kTraceAudioDevice:
339 sprintf (traceMessage, "AUDIO DEVICE:%11ld;", idl);
340 break;
341 case kTraceVideoRenderer:
342 sprintf (traceMessage, "VIDEO RENDER:%11ld;", idl);
343 break;
344 case kTraceVideoCapture:
345 sprintf (traceMessage, "VIDEO CAPTUR:%11ld;", idl);
346 break;
347 case kTraceVideoPreocessing:
348 sprintf (traceMessage, " VIDEO PROC:%11ld;", idl);
349 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000350 }
351 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000352 return kMessageLength;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353}
354
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000355WebRtc_Word32 TraceImpl::SetTraceFileImpl(const char* fileNameUTF8,
niklase@google.com470e71d2011-07-07 08:21:25 +0000356 const bool addFileCounter)
357{
358 CriticalSectionScoped lock(_critsectInterface);
359
360 _traceFile.Flush();
361 _traceFile.CloseFile();
362
363 if(fileNameUTF8)
364 {
365 if(addFileCounter)
366 {
367 _fileCountText = 1;
368
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000369 char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000370 CreateFileName(fileNameUTF8, fileNameWithCounterUTF8,
371 _fileCountText);
372 if(_traceFile.OpenFile(fileNameWithCounterUTF8, false, false,
373 true) == -1)
374 {
375 return -1;
376 }
377 }else {
378 _fileCountText = 0;
379 if(_traceFile.OpenFile(fileNameUTF8, false, false, true) == -1)
380 {
381 return -1;
382 }
383 }
384 }
385 _rowCountText = 0;
386 return 0;
387}
388
389WebRtc_Word32 TraceImpl::TraceFileImpl(
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000390 char fileNameUTF8[FileWrapper::kMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000391{
392 CriticalSectionScoped lock(_critsectInterface);
393 return _traceFile.FileName(fileNameUTF8, FileWrapper::kMaxFileNameSize);
394}
395
396WebRtc_Word32 TraceImpl::SetTraceCallbackImpl(TraceCallback* callback)
397{
398 CriticalSectionScoped lock(_critsectInterface);
399 _callback = callback;
400 return 0;
401}
402
403WebRtc_Word32 TraceImpl::AddMessage(
404 char* traceMessage,
405 const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE],
406 const WebRtc_UWord16 writtenSoFar) const
407
408{
409 int length = 0;
410 if(writtenSoFar >= WEBRTC_TRACE_MAX_MESSAGE_SIZE)
411 {
412 return -1;
413 }
414 // - 2 to leave room for newline and NULL termination
415#ifdef _WIN32
416 length = _snprintf(traceMessage,
417 WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2,
418 "%s",msg);
419 if(length < 0)
420 {
421 length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2;
422 traceMessage[length] = 0;
423 }
424#else
425 length = snprintf(traceMessage,
426 WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar-2, "%s",msg);
427 if(length < 0 || length > WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar - 2)
428 {
429 length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2;
430 traceMessage[length] = 0;
431 }
432#endif
433 // Length with NULL termination.
434 return length+1;
435}
436
437void TraceImpl::AddMessageToList(
438 const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE],
439 const WebRtc_UWord16 length,
pwestin@webrtc.org27fe1b72012-04-04 08:08:30 +0000440 const TraceLevel level) {
441#ifdef WEBRTC_DIRECT_TRACE
442 if (_callback) {
443 _callback->Print(level, traceMessage, length);
444 }
445 return;
446#endif
447
niklase@google.com470e71d2011-07-07 08:21:25 +0000448 CriticalSectionScoped lock(_critsectArray);
449
450 if(_nextFreeIdx[_activeQueue] >= WEBRTC_TRACE_MAX_QUEUE)
451 {
452 if( ! _traceFile.Open() &&
453 !_callback)
454 {
455 // Keep at least the last 1/4 of old messages when not logging.
456 // TODO (hellner): isn't this redundant. The user will make it known
457 // when to start logging. Why keep messages before
458 // that?
459 for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE/4; n++)
460 {
461 const int lastQuarterOffset = (3*WEBRTC_TRACE_MAX_QUEUE/4);
462 memcpy(_messageQueue[_activeQueue][n],
463 _messageQueue[_activeQueue][n + lastQuarterOffset],
464 WEBRTC_TRACE_MAX_MESSAGE_SIZE);
465 }
466 _nextFreeIdx[_activeQueue] = WEBRTC_TRACE_MAX_QUEUE/4;
467 } else {
468 // More messages are being written than there is room for in the
469 // buffer. Drop any new messages.
470 // TODO (hellner): its probably better to drop old messages instead
471 // of new ones. One step further: if this happens
472 // it's due to writing faster than what can be
473 // processed. Maybe modify the filter at this point.
474 // E.g. turn of STREAM.
475 return;
476 }
477 }
478
479 WebRtc_UWord16 idx = _nextFreeIdx[_activeQueue];
480 _nextFreeIdx[_activeQueue]++;
481
482 _level[_activeQueue][idx] = level;
483 _length[_activeQueue][idx] = length;
484 memcpy(_messageQueue[_activeQueue][idx], traceMessage, length);
485
henrike@webrtc.orge341fd62012-10-25 22:02:50 +0000486 if(_nextFreeIdx[_activeQueue] == WEBRTC_TRACE_MAX_QUEUE - 1)
niklase@google.com470e71d2011-07-07 08:21:25 +0000487 {
henrike@webrtc.org1a2933c2011-10-06 17:55:56 +0000488 // Logging more messages than can be worked off. Log a warning.
489 const char warning_msg[] = "WARNING MISSING TRACE MESSAGES\n";
490 _level[_activeQueue][_nextFreeIdx[_activeQueue]] = kTraceWarning;
491 _length[_activeQueue][_nextFreeIdx[_activeQueue]] = strlen(warning_msg);
niklase@google.com470e71d2011-07-07 08:21:25 +0000492 memcpy(_messageQueue[_activeQueue][_nextFreeIdx[_activeQueue]],
henrike@webrtc.orge341fd62012-10-25 22:02:50 +0000493 warning_msg, strlen(warning_msg));
niklase@google.com470e71d2011-07-07 08:21:25 +0000494 _nextFreeIdx[_activeQueue]++;
495 }
496}
497
498bool TraceImpl::Run(void* obj)
499{
500 return static_cast<TraceImpl*>(obj)->Process();
501}
502
503bool TraceImpl::Process()
504{
505 if(_event.Wait(1000) == kEventSignaled)
506 {
507 if(_traceFile.Open() || _callback)
508 {
509 // File mode (not calback mode).
510 WriteToFile();
511 }
512 } else {
513 _traceFile.Flush();
514 }
515 return true;
516}
517
518void TraceImpl::WriteToFile()
519{
520 WebRtc_UWord8 localQueueActive = 0;
521 WebRtc_UWord16 localNextFreeIdx = 0;
522
523 // There are two buffer. One for reading (for writing to file) and one for
524 // writing (for storing new messages). Let new messages be posted to the
525 // unused buffer so that the current buffer can be flushed safely.
526 {
527 CriticalSectionScoped lock(_critsectArray);
528 localNextFreeIdx = _nextFreeIdx[_activeQueue];
529 _nextFreeIdx[_activeQueue] = 0;
530 localQueueActive = _activeQueue;
531 if(_activeQueue == 0)
532 {
533 _activeQueue = 1;
534 } else
535 {
536 _activeQueue = 0;
537 }
538 }
539 if(localNextFreeIdx == 0)
540 {
541 return;
542 }
543
544 CriticalSectionScoped lock(_critsectInterface);
545
546 for(WebRtc_UWord16 idx = 0; idx <localNextFreeIdx; idx++)
547 {
548 TraceLevel localLevel = _level[localQueueActive][idx];
549 if(_callback)
550 {
551 _callback->Print(localLevel, _messageQueue[localQueueActive][idx],
552 _length[localQueueActive][idx]);
553 }
554 if(_traceFile.Open())
555 {
556 if(_rowCountText > WEBRTC_TRACE_MAX_FILE_SIZE)
557 {
558 // wrap file
559 _rowCountText = 0;
560 _traceFile.Flush();
561
562 if(_fileCountText == 0)
563 {
564 _traceFile.Rewind();
565 } else
566 {
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000567 char oldFileName[FileWrapper::kMaxFileNameSize];
568 char newFileName[FileWrapper::kMaxFileNameSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000569
570 // get current name
571 _traceFile.FileName(oldFileName,
572 FileWrapper::kMaxFileNameSize);
573 _traceFile.CloseFile();
574
575 _fileCountText++;
576
577 UpdateFileName(oldFileName, newFileName, _fileCountText);
578
579 if(_traceFile.OpenFile(newFileName, false, false,
580 true) == -1)
581 {
582 return;
583 }
584 }
585 }
586 if(_rowCountText == 0)
587 {
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000588 char message[WEBRTC_TRACE_MAX_MESSAGE_SIZE + 1];
niklase@google.com470e71d2011-07-07 08:21:25 +0000589 WebRtc_Word32 length = AddDateTimeInfo(message);
590 if(length != -1)
591 {
592 message[length] = 0;
593 message[length-1] = '\n';
594 _traceFile.Write(message, length);
595 _rowCountText++;
596 }
597 length = AddBuildInfo(message);
598 if(length != -1)
599 {
600 message[length+1] = 0;
601 message[length] = '\n';
602 message[length-1] = '\n';
603 _traceFile.Write(message, length+1);
604 _rowCountText++;
605 _rowCountText++;
606 }
607 }
608 WebRtc_UWord16 length = _length[localQueueActive][idx];
609 _messageQueue[localQueueActive][idx][length] = 0;
610 _messageQueue[localQueueActive][idx][length-1] = '\n';
611 _traceFile.Write(_messageQueue[localQueueActive][idx], length);
612 _rowCountText++;
613 }
614 }
615}
616
617void TraceImpl::AddImpl(const TraceLevel level, const TraceModule module,
618 const WebRtc_Word32 id,
619 const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE])
620{
621 if (TraceCheck(level))
622 {
623 char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000624 char* messagePtr = traceMessage;
niklase@google.com470e71d2011-07-07 08:21:25 +0000625
626 WebRtc_Word32 len = 0;
627 WebRtc_Word32 ackLen = 0;
628
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000629 len = AddLevel(messagePtr, level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000630 if(len == -1)
631 {
632 return;
633 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000634 messagePtr += len;
niklase@google.com470e71d2011-07-07 08:21:25 +0000635 ackLen += len;
636
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000637 len = AddTime(messagePtr, level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000638 if(len == -1)
639 {
640 return;
641 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000642 messagePtr += len;
niklase@google.com470e71d2011-07-07 08:21:25 +0000643 ackLen += len;
644
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000645 len = AddModuleAndId(messagePtr, module, id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000646 if(len == -1)
647 {
648 return;
649 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000650 messagePtr += len;
niklase@google.com470e71d2011-07-07 08:21:25 +0000651 ackLen += len;
652
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000653 len = AddThreadId(messagePtr);
pwestin@webrtc.orgb54d7272012-01-11 08:28:04 +0000654 if(len < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000655 {
656 return;
657 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000658 messagePtr += len;
niklase@google.com470e71d2011-07-07 08:21:25 +0000659 ackLen += len;
660
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000661 len = AddMessage(messagePtr, msg, (WebRtc_UWord16)ackLen);
niklase@google.com470e71d2011-07-07 08:21:25 +0000662 if(len == -1)
663 {
664 return;
665 }
666 ackLen += len;
667 AddMessageToList(traceMessage,(WebRtc_UWord16)ackLen, level);
668
669 // Make sure that messages are written as soon as possible.
670 _event.Set();
671 }
672}
673
674bool TraceImpl::TraceCheck(const TraceLevel level) const
675{
676 return (level & levelFilter)? true:false;
677}
678
679bool TraceImpl::UpdateFileName(
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000680 const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
681 char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
niklase@google.com470e71d2011-07-07 08:21:25 +0000682 const WebRtc_UWord32 newCount) const
683{
684 WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
685 if(length < 0)
686 {
687 return false;
688 }
689
690 WebRtc_Word32 lengthWithoutFileEnding = length-1;
691 while(lengthWithoutFileEnding > 0)
692 {
693 if(fileNameUTF8[lengthWithoutFileEnding] == '.')
694 {
695 break;
696 } else {
697 lengthWithoutFileEnding--;
698 }
699 }
700 if(lengthWithoutFileEnding == 0)
701 {
702 lengthWithoutFileEnding = length;
703 }
704 WebRtc_Word32 lengthTo_ = lengthWithoutFileEnding - 1;
705 while(lengthTo_ > 0)
706 {
707 if(fileNameUTF8[lengthTo_] == '_')
708 {
709 break;
710 } else {
711 lengthTo_--;
712 }
713 }
714
715 memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthTo_);
hellner@google.com064a8df2011-08-16 15:52:28 +0000716 sprintf(fileNameWithCounterUTF8+lengthTo_, "_%lu%s",
717 static_cast<long unsigned int> (newCount),
niklase@google.com470e71d2011-07-07 08:21:25 +0000718 fileNameUTF8+lengthWithoutFileEnding);
719 return true;
720}
721
722bool TraceImpl::CreateFileName(
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000723 const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
724 char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
niklase@google.com470e71d2011-07-07 08:21:25 +0000725 const WebRtc_UWord32 newCount) const
726{
727 WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
728 if(length < 0)
729 {
730 return false;
731 }
732
733 WebRtc_Word32 lengthWithoutFileEnding = length-1;
734 while(lengthWithoutFileEnding > 0)
735 {
736 if(fileNameUTF8[lengthWithoutFileEnding] == '.')
737 {
738 break;
739 }else
740 {
741 lengthWithoutFileEnding--;
742 }
743 }
744 if(lengthWithoutFileEnding == 0)
745 {
746 lengthWithoutFileEnding = length;
747 }
748 memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthWithoutFileEnding);
749 sprintf(fileNameWithCounterUTF8+lengthWithoutFileEnding, "_%lu%s",
hellner@google.com064a8df2011-08-16 15:52:28 +0000750 static_cast<long unsigned int> (newCount),
751 fileNameUTF8+lengthWithoutFileEnding);
niklase@google.com470e71d2011-07-07 08:21:25 +0000752 return true;
753}
754
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000755void Trace::CreateTrace()
756{
henrike@webrtc.org315282c2011-12-09 17:46:20 +0000757 TraceImpl::StaticInstance(kAddRef);
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000758}
759
760void Trace::ReturnTrace()
761{
henrike@webrtc.org315282c2011-12-09 17:46:20 +0000762 TraceImpl::StaticInstance(kRelease);
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000763}
764
niklase@google.com470e71d2011-07-07 08:21:25 +0000765WebRtc_Word32 Trace::SetLevelFilter(WebRtc_UWord32 filter)
766{
767 levelFilter = filter;
768 return 0;
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000769}
niklase@google.com470e71d2011-07-07 08:21:25 +0000770
771WebRtc_Word32 Trace::LevelFilter(WebRtc_UWord32& filter)
772{
773 filter = levelFilter;
774 return 0;
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000775}
niklase@google.com470e71d2011-07-07 08:21:25 +0000776
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000777WebRtc_Word32 Trace::TraceFile(char fileName[FileWrapper::kMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000778{
779 TraceImpl* trace = TraceImpl::GetTrace();
780 if(trace)
781 {
782 int retVal = trace->TraceFileImpl(fileName);
783 ReturnTrace();
784 return retVal;
785 }
786 return -1;
787}
788
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000789WebRtc_Word32 Trace::SetTraceFile(const char* fileName,
niklase@google.com470e71d2011-07-07 08:21:25 +0000790 const bool addFileCounter)
791{
792 TraceImpl* trace = TraceImpl::GetTrace();
793 if(trace)
794 {
795 int retVal = trace->SetTraceFileImpl(fileName, addFileCounter);
796 ReturnTrace();
797 return retVal;
798 }
799 return -1;
800}
801
802WebRtc_Word32 Trace::SetTraceCallback(TraceCallback* callback)
803{
804 TraceImpl* trace = TraceImpl::GetTrace();
805 if(trace)
806 {
807 int retVal = trace->SetTraceCallbackImpl(callback);
808 ReturnTrace();
809 return retVal;
810 }
811 return -1;
812}
813
814void Trace::Add(const TraceLevel level, const TraceModule module,
815 const WebRtc_Word32 id, const char* msg, ...)
816
817{
818 TraceImpl* trace = TraceImpl::GetTrace(level);
819 if(trace)
820 {
821 if(trace->TraceCheck(level))
822 {
823 char tempBuff[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
824 char* buff = 0;
825 if(msg)
826 {
827 va_list args;
828 va_start(args, msg);
829#ifdef _WIN32
830 _vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args);
831#else
832 vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args);
833#endif
834 va_end(args);
835 buff = tempBuff;
836 }
837 trace->AddImpl(level, module, id, buff);
838 }
839 ReturnTrace();
840 }
841}
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000842
niklase@google.com470e71d2011-07-07 08:21:25 +0000843} // namespace webrtc