blob: c3c6849c82fb0d99a971f2ee2da9898bc55f193b [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{
150 switch (level)
151 {
152 case kTraceStateInfo:
153 sprintf (szMessage, "STATEINFO ; ");
154 break;
155 case kTraceWarning:
156 sprintf (szMessage, "WARNING ; ");
157 break;
158 case kTraceError:
159 sprintf (szMessage, "ERROR ; ");
160 break;
161 case kTraceCritical:
162 sprintf (szMessage, "CRITICAL ; ");
163 break;
164 case kTraceInfo:
165 sprintf (szMessage, "DEBUGINFO ; ");
166 break;
167 case kTraceModuleCall:
168 sprintf (szMessage, "MODULECALL; ");
169 break;
170 case kTraceMemory:
171 sprintf (szMessage, "MEMORY ; ");
172 break;
173 case kTraceTimer:
174 sprintf (szMessage, "TIMER ; ");
175 break;
176 case kTraceStream:
177 sprintf (szMessage, "STREAM ; ");
178 break;
179 case kTraceApiCall:
180 sprintf (szMessage, "APICALL ; ");
181 break;
182 case kTraceDebug:
183 sprintf (szMessage, "DEBUG ; ");
184 break;
185 default:
186 assert(false);
187 return 0;
188 }
189 // All messages are 12 characters.
190 return 12;
191}
192
193WebRtc_Word32 TraceImpl::AddModuleAndId(char* traceMessage,
194 const TraceModule module,
195 const WebRtc_Word32 id) const
196{
197 // Use long int to prevent problems with different definitions of
198 // WebRtc_Word32.
199 // TODO (hellner): is this actually a problem? If so, it should be better to
200 // clean up WebRtc_Word32
201 const long int idl = id;
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000202 const int kMessageLength = 25;
niklase@google.com470e71d2011-07-07 08:21:25 +0000203 if(idl != -1)
204 {
205 const unsigned long int idEngine = id>>16;
206 const unsigned long int idChannel = id & 0xffff;
207
208 switch (module)
209 {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000210 case kTraceUndefined:
211 // Add the appropriate amount of whitespace.
212 memset(traceMessage, ' ', kMessageLength);
213 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000214 case kTraceVoice:
215 sprintf(traceMessage, " VOICE:%5ld %5ld;", idEngine,
216 idChannel);
217 break;
218 case kTraceVideo:
219 sprintf(traceMessage, " VIDEO:%5ld %5ld;", idEngine,
220 idChannel);
221 break;
222 case kTraceUtility:
223 sprintf(traceMessage, " UTILITY:%5ld %5ld;", idEngine,
224 idChannel);
225 break;
226 case kTraceRtpRtcp:
227 sprintf(traceMessage, " RTP/RTCP:%5ld %5ld;", idEngine,
228 idChannel);
229 break;
230 case kTraceTransport:
231 sprintf(traceMessage, " TRANSPORT:%5ld %5ld;", idEngine,
232 idChannel);
233 break;
234 case kTraceAudioCoding:
235 sprintf(traceMessage, "AUDIO CODING:%5ld %5ld;", idEngine,
236 idChannel);
237 break;
238 case kTraceSrtp:
239 sprintf(traceMessage, " SRTP:%5ld %5ld;", idEngine,
240 idChannel);
241 break;
242 case kTraceAudioMixerServer:
243 sprintf(traceMessage, " AUDIO MIX/S:%5ld %5ld;", idEngine,
244 idChannel);
245 break;
246 case kTraceAudioMixerClient:
247 sprintf(traceMessage, " AUDIO MIX/C:%5ld %5ld;", idEngine,
248 idChannel);
249 break;
250 case kTraceVideoCoding:
251 sprintf(traceMessage, "VIDEO CODING:%5ld %5ld;", idEngine,
252 idChannel);
253 break;
254 case kTraceVideoMixer:
255 // Print sleep time and API call
256 sprintf(traceMessage, " VIDEO MIX:%5ld %5ld;", idEngine,
257 idChannel);
258 break;
259 case kTraceFile:
260 sprintf(traceMessage, " FILE:%5ld %5ld;", idEngine,
261 idChannel);
262 break;
263 case kTraceAudioProcessing:
264 sprintf(traceMessage, " AUDIO PROC:%5ld %5ld;", idEngine,
265 idChannel);
266 break;
267 case kTraceAudioDevice:
268 sprintf(traceMessage, "AUDIO DEVICE:%5ld %5ld;", idEngine,
269 idChannel);
270 break;
271 case kTraceVideoRenderer:
272 sprintf(traceMessage, "VIDEO RENDER:%5ld %5ld;", idEngine,
273 idChannel);
274 break;
275 case kTraceVideoCapture:
276 sprintf(traceMessage, "VIDEO CAPTUR:%5ld %5ld;", idEngine,
277 idChannel);
278 break;
279 case kTraceVideoPreocessing:
280 sprintf(traceMessage, " VIDEO PROC:%5ld %5ld;", idEngine,
281 idChannel);
282 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000283 }
284 } else {
285 switch (module)
286 {
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000287 case kTraceUndefined:
288 // Add the appropriate amount of whitespace.
289 memset(traceMessage, ' ', kMessageLength);
290 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000291 case kTraceVoice:
292 sprintf (traceMessage, " VOICE:%11ld;", idl);
293 break;
294 case kTraceVideo:
295 sprintf (traceMessage, " VIDEO:%11ld;", idl);
296 break;
297 case kTraceUtility:
298 sprintf (traceMessage, " UTILITY:%11ld;", idl);
299 break;
300 case kTraceRtpRtcp:
301 sprintf (traceMessage, " RTP/RTCP:%11ld;", idl);
302 break;
303 case kTraceTransport:
304 sprintf (traceMessage, " TRANSPORT:%11ld;", idl);
305 break;
306 case kTraceAudioCoding:
307 sprintf (traceMessage, "AUDIO CODING:%11ld;", idl);
308 break;
309 case kTraceSrtp:
310 sprintf (traceMessage, " SRTP:%11ld;", idl);
311 break;
312 case kTraceAudioMixerServer:
313 sprintf (traceMessage, " AUDIO MIX/S:%11ld;", idl);
314 break;
315 case kTraceAudioMixerClient:
316 sprintf (traceMessage, " AUDIO MIX/C:%11ld;", idl);
317 break;
318 case kTraceVideoCoding:
319 sprintf (traceMessage, "VIDEO CODING:%11ld;", idl);
320 break;
321 case kTraceVideoMixer:
322 sprintf (traceMessage, " VIDEO MIX:%11ld;", idl);
323 break;
324 case kTraceFile:
325 sprintf (traceMessage, " FILE:%11ld;", idl);
326 break;
327 case kTraceAudioProcessing:
328 sprintf (traceMessage, " AUDIO PROC:%11ld;", idl);
329 break;
330 case kTraceAudioDevice:
331 sprintf (traceMessage, "AUDIO DEVICE:%11ld;", idl);
332 break;
333 case kTraceVideoRenderer:
334 sprintf (traceMessage, "VIDEO RENDER:%11ld;", idl);
335 break;
336 case kTraceVideoCapture:
337 sprintf (traceMessage, "VIDEO CAPTUR:%11ld;", idl);
338 break;
339 case kTraceVideoPreocessing:
340 sprintf (traceMessage, " VIDEO PROC:%11ld;", idl);
341 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 }
343 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000344 return kMessageLength;
niklase@google.com470e71d2011-07-07 08:21:25 +0000345}
346
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000347WebRtc_Word32 TraceImpl::SetTraceFileImpl(const char* fileNameUTF8,
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 const bool addFileCounter)
349{
350 CriticalSectionScoped lock(_critsectInterface);
351
352 _traceFile.Flush();
353 _traceFile.CloseFile();
354
355 if(fileNameUTF8)
356 {
357 if(addFileCounter)
358 {
359 _fileCountText = 1;
360
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000361 char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 CreateFileName(fileNameUTF8, fileNameWithCounterUTF8,
363 _fileCountText);
364 if(_traceFile.OpenFile(fileNameWithCounterUTF8, false, false,
365 true) == -1)
366 {
367 return -1;
368 }
369 }else {
370 _fileCountText = 0;
371 if(_traceFile.OpenFile(fileNameUTF8, false, false, true) == -1)
372 {
373 return -1;
374 }
375 }
376 }
377 _rowCountText = 0;
378 return 0;
379}
380
381WebRtc_Word32 TraceImpl::TraceFileImpl(
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000382 char fileNameUTF8[FileWrapper::kMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000383{
384 CriticalSectionScoped lock(_critsectInterface);
385 return _traceFile.FileName(fileNameUTF8, FileWrapper::kMaxFileNameSize);
386}
387
388WebRtc_Word32 TraceImpl::SetTraceCallbackImpl(TraceCallback* callback)
389{
390 CriticalSectionScoped lock(_critsectInterface);
391 _callback = callback;
392 return 0;
393}
394
395WebRtc_Word32 TraceImpl::AddMessage(
396 char* traceMessage,
397 const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE],
398 const WebRtc_UWord16 writtenSoFar) const
399
400{
401 int length = 0;
402 if(writtenSoFar >= WEBRTC_TRACE_MAX_MESSAGE_SIZE)
403 {
404 return -1;
405 }
406 // - 2 to leave room for newline and NULL termination
407#ifdef _WIN32
408 length = _snprintf(traceMessage,
409 WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2,
410 "%s",msg);
411 if(length < 0)
412 {
413 length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2;
414 traceMessage[length] = 0;
415 }
416#else
417 length = snprintf(traceMessage,
418 WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar-2, "%s",msg);
419 if(length < 0 || length > WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar - 2)
420 {
421 length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2;
422 traceMessage[length] = 0;
423 }
424#endif
425 // Length with NULL termination.
426 return length+1;
427}
428
429void TraceImpl::AddMessageToList(
430 const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE],
431 const WebRtc_UWord16 length,
pwestin@webrtc.org27fe1b72012-04-04 08:08:30 +0000432 const TraceLevel level) {
433#ifdef WEBRTC_DIRECT_TRACE
434 if (_callback) {
435 _callback->Print(level, traceMessage, length);
436 }
437 return;
438#endif
439
niklase@google.com470e71d2011-07-07 08:21:25 +0000440 CriticalSectionScoped lock(_critsectArray);
441
442 if(_nextFreeIdx[_activeQueue] >= WEBRTC_TRACE_MAX_QUEUE)
443 {
444 if( ! _traceFile.Open() &&
445 !_callback)
446 {
447 // Keep at least the last 1/4 of old messages when not logging.
448 // TODO (hellner): isn't this redundant. The user will make it known
449 // when to start logging. Why keep messages before
450 // that?
451 for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE/4; n++)
452 {
453 const int lastQuarterOffset = (3*WEBRTC_TRACE_MAX_QUEUE/4);
454 memcpy(_messageQueue[_activeQueue][n],
455 _messageQueue[_activeQueue][n + lastQuarterOffset],
456 WEBRTC_TRACE_MAX_MESSAGE_SIZE);
457 }
458 _nextFreeIdx[_activeQueue] = WEBRTC_TRACE_MAX_QUEUE/4;
459 } else {
460 // More messages are being written than there is room for in the
461 // buffer. Drop any new messages.
462 // TODO (hellner): its probably better to drop old messages instead
463 // of new ones. One step further: if this happens
464 // it's due to writing faster than what can be
465 // processed. Maybe modify the filter at this point.
466 // E.g. turn of STREAM.
467 return;
468 }
469 }
470
471 WebRtc_UWord16 idx = _nextFreeIdx[_activeQueue];
472 _nextFreeIdx[_activeQueue]++;
473
474 _level[_activeQueue][idx] = level;
475 _length[_activeQueue][idx] = length;
476 memcpy(_messageQueue[_activeQueue][idx], traceMessage, length);
477
henrike@webrtc.orge341fd62012-10-25 22:02:50 +0000478 if(_nextFreeIdx[_activeQueue] == WEBRTC_TRACE_MAX_QUEUE - 1)
niklase@google.com470e71d2011-07-07 08:21:25 +0000479 {
henrike@webrtc.org1a2933c2011-10-06 17:55:56 +0000480 // Logging more messages than can be worked off. Log a warning.
481 const char warning_msg[] = "WARNING MISSING TRACE MESSAGES\n";
482 _level[_activeQueue][_nextFreeIdx[_activeQueue]] = kTraceWarning;
483 _length[_activeQueue][_nextFreeIdx[_activeQueue]] = strlen(warning_msg);
niklase@google.com470e71d2011-07-07 08:21:25 +0000484 memcpy(_messageQueue[_activeQueue][_nextFreeIdx[_activeQueue]],
henrike@webrtc.orge341fd62012-10-25 22:02:50 +0000485 warning_msg, strlen(warning_msg));
niklase@google.com470e71d2011-07-07 08:21:25 +0000486 _nextFreeIdx[_activeQueue]++;
487 }
488}
489
490bool TraceImpl::Run(void* obj)
491{
492 return static_cast<TraceImpl*>(obj)->Process();
493}
494
495bool TraceImpl::Process()
496{
497 if(_event.Wait(1000) == kEventSignaled)
498 {
499 if(_traceFile.Open() || _callback)
500 {
501 // File mode (not calback mode).
502 WriteToFile();
503 }
504 } else {
505 _traceFile.Flush();
506 }
507 return true;
508}
509
510void TraceImpl::WriteToFile()
511{
512 WebRtc_UWord8 localQueueActive = 0;
513 WebRtc_UWord16 localNextFreeIdx = 0;
514
515 // There are two buffer. One for reading (for writing to file) and one for
516 // writing (for storing new messages). Let new messages be posted to the
517 // unused buffer so that the current buffer can be flushed safely.
518 {
519 CriticalSectionScoped lock(_critsectArray);
520 localNextFreeIdx = _nextFreeIdx[_activeQueue];
521 _nextFreeIdx[_activeQueue] = 0;
522 localQueueActive = _activeQueue;
523 if(_activeQueue == 0)
524 {
525 _activeQueue = 1;
526 } else
527 {
528 _activeQueue = 0;
529 }
530 }
531 if(localNextFreeIdx == 0)
532 {
533 return;
534 }
535
536 CriticalSectionScoped lock(_critsectInterface);
537
538 for(WebRtc_UWord16 idx = 0; idx <localNextFreeIdx; idx++)
539 {
540 TraceLevel localLevel = _level[localQueueActive][idx];
541 if(_callback)
542 {
543 _callback->Print(localLevel, _messageQueue[localQueueActive][idx],
544 _length[localQueueActive][idx]);
545 }
546 if(_traceFile.Open())
547 {
548 if(_rowCountText > WEBRTC_TRACE_MAX_FILE_SIZE)
549 {
550 // wrap file
551 _rowCountText = 0;
552 _traceFile.Flush();
553
554 if(_fileCountText == 0)
555 {
556 _traceFile.Rewind();
557 } else
558 {
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000559 char oldFileName[FileWrapper::kMaxFileNameSize];
560 char newFileName[FileWrapper::kMaxFileNameSize];
niklase@google.com470e71d2011-07-07 08:21:25 +0000561
562 // get current name
563 _traceFile.FileName(oldFileName,
564 FileWrapper::kMaxFileNameSize);
565 _traceFile.CloseFile();
566
567 _fileCountText++;
568
569 UpdateFileName(oldFileName, newFileName, _fileCountText);
570
571 if(_traceFile.OpenFile(newFileName, false, false,
572 true) == -1)
573 {
574 return;
575 }
576 }
577 }
578 if(_rowCountText == 0)
579 {
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000580 char message[WEBRTC_TRACE_MAX_MESSAGE_SIZE + 1];
niklase@google.com470e71d2011-07-07 08:21:25 +0000581 WebRtc_Word32 length = AddDateTimeInfo(message);
582 if(length != -1)
583 {
584 message[length] = 0;
585 message[length-1] = '\n';
586 _traceFile.Write(message, length);
587 _rowCountText++;
588 }
589 length = AddBuildInfo(message);
590 if(length != -1)
591 {
592 message[length+1] = 0;
593 message[length] = '\n';
594 message[length-1] = '\n';
595 _traceFile.Write(message, length+1);
596 _rowCountText++;
597 _rowCountText++;
598 }
599 }
600 WebRtc_UWord16 length = _length[localQueueActive][idx];
601 _messageQueue[localQueueActive][idx][length] = 0;
602 _messageQueue[localQueueActive][idx][length-1] = '\n';
603 _traceFile.Write(_messageQueue[localQueueActive][idx], length);
604 _rowCountText++;
605 }
606 }
607}
608
609void TraceImpl::AddImpl(const TraceLevel level, const TraceModule module,
610 const WebRtc_Word32 id,
611 const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE])
612{
613 if (TraceCheck(level))
614 {
615 char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000616 char* messagePtr = traceMessage;
niklase@google.com470e71d2011-07-07 08:21:25 +0000617
618 WebRtc_Word32 len = 0;
619 WebRtc_Word32 ackLen = 0;
620
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000621 len = AddLevel(messagePtr, level);
niklase@google.com470e71d2011-07-07 08:21:25 +0000622 if(len == -1)
623 {
624 return;
625 }
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000626 messagePtr += len;
niklase@google.com470e71d2011-07-07 08:21:25 +0000627 ackLen += len;
628
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000629 len = AddTime(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 = AddModuleAndId(messagePtr, module, id);
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 = AddThreadId(messagePtr);
pwestin@webrtc.orgb54d7272012-01-11 08:28:04 +0000646 if(len < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000647 {
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 = AddMessage(messagePtr, msg, (WebRtc_UWord16)ackLen);
niklase@google.com470e71d2011-07-07 08:21:25 +0000654 if(len == -1)
655 {
656 return;
657 }
658 ackLen += len;
659 AddMessageToList(traceMessage,(WebRtc_UWord16)ackLen, level);
660
661 // Make sure that messages are written as soon as possible.
662 _event.Set();
663 }
664}
665
666bool TraceImpl::TraceCheck(const TraceLevel level) const
667{
668 return (level & levelFilter)? true:false;
669}
670
671bool TraceImpl::UpdateFileName(
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000672 const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
673 char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
niklase@google.com470e71d2011-07-07 08:21:25 +0000674 const WebRtc_UWord32 newCount) const
675{
676 WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
677 if(length < 0)
678 {
679 return false;
680 }
681
682 WebRtc_Word32 lengthWithoutFileEnding = length-1;
683 while(lengthWithoutFileEnding > 0)
684 {
685 if(fileNameUTF8[lengthWithoutFileEnding] == '.')
686 {
687 break;
688 } else {
689 lengthWithoutFileEnding--;
690 }
691 }
692 if(lengthWithoutFileEnding == 0)
693 {
694 lengthWithoutFileEnding = length;
695 }
696 WebRtc_Word32 lengthTo_ = lengthWithoutFileEnding - 1;
697 while(lengthTo_ > 0)
698 {
699 if(fileNameUTF8[lengthTo_] == '_')
700 {
701 break;
702 } else {
703 lengthTo_--;
704 }
705 }
706
707 memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthTo_);
hellner@google.com064a8df2011-08-16 15:52:28 +0000708 sprintf(fileNameWithCounterUTF8+lengthTo_, "_%lu%s",
709 static_cast<long unsigned int> (newCount),
niklase@google.com470e71d2011-07-07 08:21:25 +0000710 fileNameUTF8+lengthWithoutFileEnding);
711 return true;
712}
713
714bool TraceImpl::CreateFileName(
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000715 const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
716 char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
niklase@google.com470e71d2011-07-07 08:21:25 +0000717 const WebRtc_UWord32 newCount) const
718{
719 WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
720 if(length < 0)
721 {
722 return false;
723 }
724
725 WebRtc_Word32 lengthWithoutFileEnding = length-1;
726 while(lengthWithoutFileEnding > 0)
727 {
728 if(fileNameUTF8[lengthWithoutFileEnding] == '.')
729 {
730 break;
731 }else
732 {
733 lengthWithoutFileEnding--;
734 }
735 }
736 if(lengthWithoutFileEnding == 0)
737 {
738 lengthWithoutFileEnding = length;
739 }
740 memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthWithoutFileEnding);
741 sprintf(fileNameWithCounterUTF8+lengthWithoutFileEnding, "_%lu%s",
hellner@google.com064a8df2011-08-16 15:52:28 +0000742 static_cast<long unsigned int> (newCount),
743 fileNameUTF8+lengthWithoutFileEnding);
niklase@google.com470e71d2011-07-07 08:21:25 +0000744 return true;
745}
746
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000747void Trace::CreateTrace()
748{
henrike@webrtc.org315282c2011-12-09 17:46:20 +0000749 TraceImpl::StaticInstance(kAddRef);
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000750}
751
752void Trace::ReturnTrace()
753{
henrike@webrtc.org315282c2011-12-09 17:46:20 +0000754 TraceImpl::StaticInstance(kRelease);
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000755}
756
niklase@google.com470e71d2011-07-07 08:21:25 +0000757WebRtc_Word32 Trace::SetLevelFilter(WebRtc_UWord32 filter)
758{
759 levelFilter = filter;
760 return 0;
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000761}
niklase@google.com470e71d2011-07-07 08:21:25 +0000762
763WebRtc_Word32 Trace::LevelFilter(WebRtc_UWord32& filter)
764{
765 filter = levelFilter;
766 return 0;
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000767}
niklase@google.com470e71d2011-07-07 08:21:25 +0000768
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000769WebRtc_Word32 Trace::TraceFile(char fileName[FileWrapper::kMaxFileNameSize])
niklase@google.com470e71d2011-07-07 08:21:25 +0000770{
771 TraceImpl* trace = TraceImpl::GetTrace();
772 if(trace)
773 {
774 int retVal = trace->TraceFileImpl(fileName);
775 ReturnTrace();
776 return retVal;
777 }
778 return -1;
779}
780
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000781WebRtc_Word32 Trace::SetTraceFile(const char* fileName,
niklase@google.com470e71d2011-07-07 08:21:25 +0000782 const bool addFileCounter)
783{
784 TraceImpl* trace = TraceImpl::GetTrace();
785 if(trace)
786 {
787 int retVal = trace->SetTraceFileImpl(fileName, addFileCounter);
788 ReturnTrace();
789 return retVal;
790 }
791 return -1;
792}
793
794WebRtc_Word32 Trace::SetTraceCallback(TraceCallback* callback)
795{
796 TraceImpl* trace = TraceImpl::GetTrace();
797 if(trace)
798 {
799 int retVal = trace->SetTraceCallbackImpl(callback);
800 ReturnTrace();
801 return retVal;
802 }
803 return -1;
804}
805
806void Trace::Add(const TraceLevel level, const TraceModule module,
807 const WebRtc_Word32 id, const char* msg, ...)
808
809{
810 TraceImpl* trace = TraceImpl::GetTrace(level);
811 if(trace)
812 {
813 if(trace->TraceCheck(level))
814 {
815 char tempBuff[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
816 char* buff = 0;
817 if(msg)
818 {
819 va_list args;
820 va_start(args, msg);
821#ifdef _WIN32
822 _vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args);
823#else
824 vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args);
825#endif
826 va_end(args);
827 buff = tempBuff;
828 }
829 trace->AddImpl(level, module, id, buff);
830 }
831 ReturnTrace();
832 }
833}
tommi@webrtc.orgcde1e7f2011-11-15 12:23:36 +0000834
niklase@google.com470e71d2011-07-07 08:21:25 +0000835} // namespace webrtc