aboutsummaryrefslogtreecommitdiff
path: root/src/system_wrappers/source/trace_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/system_wrappers/source/trace_impl.cc')
-rw-r--r--src/system_wrappers/source/trace_impl.cc202
1 files changed, 41 insertions, 161 deletions
diff --git a/src/system_wrappers/source/trace_impl.cc b/src/system_wrappers/source/trace_impl.cc
index 0a5f9db461..1156519eb9 100644
--- a/src/system_wrappers/source/trace_impl.cc
+++ b/src/system_wrappers/source/trace_impl.cc
@@ -14,13 +14,12 @@
#include <string.h> // memset
#ifdef _WIN32
-#include "trace_windows.h"
-#include "fix_interlocked_exchange_pointer_windows.h"
+#include "trace_win.h"
#else
#include <stdio.h>
#include <time.h>
#include <stdarg.h>
-#include "trace_linux.h"
+#include "trace_posix.h"
#endif // _WIN32
#define KEY_LEN_CHARS 31
@@ -35,176 +34,41 @@ namespace webrtc {
static WebRtc_UWord32 levelFilter = kTraceDefault;
// Construct On First Use idiom. Avoids "static initialization order fiasco".
-Trace* TraceImpl::StaticInstance(TraceCount inc, const TraceLevel level)
+TraceImpl* TraceImpl::StaticInstance(CountOperation count_operation,
+ const TraceLevel level)
{
- // TODO (hellner): use atomic wrapper instead.
- static volatile long theTraceCount = 0;
- static Trace* volatile theTrace = NULL;
-
- TraceCreate state = WEBRTC_TRACE_EXIST;
-
- // Sanitys to avoid taking lock unless absolutely necessary (for
- // performance reasons). inc == WEBRTC_TRACE_INC_NO_CREATE) implies that
- // a message will be written to file.
- if(level != kTraceAll && inc == WEBRTC_TRACE_INC_NO_CREATE)
+ // Sanities to avoid taking lock unless absolutely necessary (for
+ // performance reasons).
+ // count_operation == kAddRefNoCreate implies that a message will be
+ // written to file.
+ if((level != kTraceAll) && (count_operation == kAddRefNoCreate))
{
if(!(level & levelFilter))
{
return NULL;
}
}
-
-#ifndef _WIN32
- // TODO (pwestin): crtiSect is never reclaimed. Fix memory leak.
- static CriticalSectionWrapper* crtiSect(
- CriticalSectionWrapper::CreateCriticalSection());
- CriticalSectionScoped lock(*crtiSect);
-
- if(inc == WEBRTC_TRACE_INC_NO_CREATE && theTraceCount == 0)
- {
- return NULL;
- }
-
- if(inc == WEBRTC_TRACE_INC || inc == WEBRTC_TRACE_INC_NO_CREATE)
- {
- theTraceCount++;
- if(theTraceCount == 1)
- {
- state = WEBRTC_TRACE_CREATE;
- }
- } else {
- theTraceCount--;
- if(theTraceCount == 0)
- {
- state = WEBRTC_TRACE_DESTROY;
- }
- }
- if(state == WEBRTC_TRACE_CREATE)
- {
- theTrace = TraceImpl::CreateTrace();
-
- } else if(state == WEBRTC_TRACE_DESTROY) {
- Trace* oldValue = theTrace;
- theTrace = NULL;
- // The lock is held by the scoped critical section. Release the lock
- // temporarily so that the trace can be safely deleted. If the lock
- // was kept during the delete, e.g. creating and destroying the trace
- // too quickly may lead to a deadlock.
- // This is due to the fact that starting and stopping a ThreadWrapper
- // thread will trigger writing of trace messages.
- // TODO (hellner): remove the tight coupling with the thread
- // implementation.
- crtiSect->Leave();
- if(oldValue)
- {
- delete static_cast<TraceImpl*>(oldValue);
- }
- // Re-aqcuire the lock.
- crtiSect->Enter();
- return NULL;
- }
-#else // _WIN32
- if(inc == WEBRTC_TRACE_INC_NO_CREATE && theTraceCount == 0)
- {
- return NULL;
- }
- if(inc == WEBRTC_TRACE_INC_NO_CREATE)
- {
- if(1 == InterlockedIncrement(&theTraceCount))
- {
- // The trace has been destroyed by some other thread. Rollback.
- InterlockedDecrement(&theTraceCount);
- assert(false);
- return NULL;
- }
- // Sanity to catch corrupt state.
- if(theTrace == NULL)
- {
- assert(false);
- InterlockedDecrement(&theTraceCount);
- return NULL;
- }
- } else if(inc == WEBRTC_TRACE_INC) {
- if(theTraceCount == 0)
- {
- state = WEBRTC_TRACE_CREATE;
- } else {
- if(1 == InterlockedIncrement(&theTraceCount))
- {
- // InterlockedDecrement because reference count should not be
- // updated just yet (that's done when the trace is created).
- InterlockedDecrement(&theTraceCount);
- state = WEBRTC_TRACE_CREATE;
- }
- }
- } else {
- int newValue = InterlockedDecrement(&theTraceCount);
- if(newValue == 0)
- {
- state = WEBRTC_TRACE_DESTROY;
- }
- }
-
- if(state == WEBRTC_TRACE_CREATE)
- {
- // Create trace and let whichever thread finishes first assign its local
- // copy to the global instance. All other threads reclaim their local
- // copy.
- Trace* newTrace = TraceImpl::CreateTrace();
- if(1 == InterlockedIncrement(&theTraceCount))
- {
- Trace* oldValue = (Trace*)InterlockedExchangePointer(
- reinterpret_cast<void* volatile*>(&theTrace), newTrace);
- assert(oldValue == NULL);
- assert(theTrace);
- } else {
- InterlockedDecrement(&theTraceCount);
- if(newTrace)
- {
- delete static_cast<TraceImpl*>(newTrace);
- }
- }
- return NULL;
- } else if(state == WEBRTC_TRACE_DESTROY)
- {
- Trace* oldValue = (Trace*)InterlockedExchangePointer(
- reinterpret_cast<void* volatile*>(&theTrace), NULL);
- if(oldValue)
- {
- delete static_cast<TraceImpl*>(oldValue);
- }
- return NULL;
- }
-#endif // #ifndef _WIN32
- return theTrace;
-}
-
-void Trace::CreateTrace()
-{
- TraceImpl::StaticInstance(WEBRTC_TRACE_INC);
-}
-
-void Trace::ReturnTrace()
-{
- TraceImpl::StaticInstance(WEBRTC_TRACE_DEC);
+ TraceImpl* impl =
+ GetStaticInstance<TraceImpl>(count_operation);
+ return impl;
}
TraceImpl* TraceImpl::GetTrace(const TraceLevel level)
{
- return (TraceImpl*)StaticInstance(WEBRTC_TRACE_INC_NO_CREATE, level);
+ return StaticInstance(kAddRefNoCreate, level);
}
-Trace* TraceImpl::CreateTrace()
+TraceImpl* TraceImpl::CreateInstance()
{
#if defined(_WIN32)
return new TraceWindows();
#else
- return new TraceLinux();
+ return new TracePosix();
#endif
}
TraceImpl::TraceImpl()
- : _critsectInterface(*CriticalSectionWrapper::CreateCriticalSection()),
+ : _critsectInterface(CriticalSectionWrapper::CreateCriticalSection()),
_callback(NULL),
_rowCountText(0),
_fileCountText(0),
@@ -212,7 +76,7 @@ TraceImpl::TraceImpl()
_thread(*ThreadWrapper::CreateThread(TraceImpl::Run, this,
kHighestPriority, "Trace")),
_event(*EventWrapper::Create()),
- _critsectArray(*CriticalSectionWrapper::CreateCriticalSection()),
+ _critsectArray(CriticalSectionWrapper::CreateCriticalSection()),
_nextFreeIdx(),
_level(),
_length(),
@@ -271,8 +135,8 @@ TraceImpl::~TraceImpl()
delete &_event;
delete &_traceFile;
delete &_thread;
- delete &_critsectInterface;
- delete &_critsectArray;
+ delete _critsectInterface;
+ delete _critsectArray;
for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++)
{
@@ -607,9 +471,12 @@ void TraceImpl::AddMessageToList(
if(_nextFreeIdx[_activeQueue] == WEBRTC_TRACE_MAX_QUEUE-1)
{
- // Loggin more messages than can be worked off. Log a warning.
+ // Logging more messages than can be worked off. Log a warning.
+ const char warning_msg[] = "WARNING MISSING TRACE MESSAGES\n";
+ _level[_activeQueue][_nextFreeIdx[_activeQueue]] = kTraceWarning;
+ _length[_activeQueue][_nextFreeIdx[_activeQueue]] = strlen(warning_msg);
memcpy(_messageQueue[_activeQueue][_nextFreeIdx[_activeQueue]],
- "WARNING MISSING TRACE MESSAGES\n", 32);
+ warning_msg, _length[_activeQueue][idx]);
_nextFreeIdx[_activeQueue]++;
}
}
@@ -832,7 +699,8 @@ bool TraceImpl::UpdateFileName(
}
memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthTo_);
- sprintf(fileNameWithCounterUTF8+lengthTo_, "_%lu%s", newCount,
+ sprintf(fileNameWithCounterUTF8+lengthTo_, "_%lu%s",
+ static_cast<long unsigned int> (newCount),
fileNameUTF8+lengthWithoutFileEnding);
return true;
}
@@ -865,21 +733,32 @@ bool TraceImpl::CreateFileName(
}
memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthWithoutFileEnding);
sprintf(fileNameWithCounterUTF8+lengthWithoutFileEnding, "_%lu%s",
- newCount, fileNameUTF8+lengthWithoutFileEnding);
+ static_cast<long unsigned int> (newCount),
+ fileNameUTF8+lengthWithoutFileEnding);
return true;
}
+void Trace::CreateTrace()
+{
+ TraceImpl::StaticInstance(kAddRef);
+}
+
+void Trace::ReturnTrace()
+{
+ TraceImpl::StaticInstance(kRelease);
+}
+
WebRtc_Word32 Trace::SetLevelFilter(WebRtc_UWord32 filter)
{
levelFilter = filter;
return 0;
-};
+}
WebRtc_Word32 Trace::LevelFilter(WebRtc_UWord32& filter)
{
filter = levelFilter;
return 0;
-};
+}
WebRtc_Word32 Trace::TraceFile(WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize])
{
@@ -946,4 +825,5 @@ void Trace::Add(const TraceLevel level, const TraceModule module,
ReturnTrace();
}
}
+
} // namespace webrtc