// Module: Log4CPLUS
// File: threads.cxx
// Created: 6/2001
// Author: Tad E. Smith
//
//
// Copyright (C) Tad E. Smith All rights reserved.
//
// This software is published under the terms of the Apache Software
// License version 1.1, a copy of which has been included with this
// distribution in the LICENSE.APL file.
//
// $Log: threads.cxx,v $
// Revision 1.18 2003/10/22 06:41:11 tcsmith
// Modified getCurrentThreadName() so that it always uses an ostream to
// convert the Thread ID to a string.
//
// Revision 1.17 2003/09/10 07:01:36 tcsmith
// Added support for NetBSD.
//
// Revision 1.16 2003/08/27 15:22:38 tcsmith
// Corrected the getCurrentThreadName() method for MacOS X and DEC cxx.
//
// Revision 1.15 2003/08/09 06:58:21 tcsmith
// Fixed the getCurrentThreadName() method for MacOS X.
//
// Revision 1.14 2003/08/04 01:10:12 tcsmith
// Modified the getCurrentThreadName() method to use convertIntegerToString().
//
// Revision 1.13 2003/07/19 15:41:04 tcsmith
// Cleaned up the threadStartFunc() method.
//
// Revision 1.12 2003/06/29 16:48:25 tcsmith
// Modified to support that move of the getLogLog() method into the LogLog
// class.
//
// Revision 1.11 2003/06/13 15:25:07 tcsmith
// Added the getCurrentThreadName() function.
//
// Revision 1.10 2003/06/04 18:56:41 tcsmith
// Modified to use the new timehelper.h header.
//
// Revision 1.9 2003/05/22 21:17:32 tcsmith
// Moved the sleep() method into sleep.cxx
//
// Revision 1.8 2003/04/29 17:38:45 tcsmith
// Added "return NULL" to the threadStartFunc() method to make the Sun Forte
// compiler happy.
//
// Revision 1.7 2003/04/18 21:58:47 tcsmith
// Converted from std::string to log4cplus::tstring.
//
// Revision 1.6 2003/04/03 01:31:43 tcsmith
// Standardized the formatting.
//
#ifndef LOG4CPLUS_SINGLE_THREADED
#include <log4cplus/helpers/threads.h>
#include <log4cplus/streams.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/timehelper.h>
#include <exception>
#include <stdexcept>
#include <errno.h>
#if defined(LOG4CPLUS_USE_PTHREADS)
# include <sched.h>
#endif
using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;
///////////////////////////////////////////////////////////////////////////////
// public methods
///////////////////////////////////////////////////////////////////////////////
LOG4CPLUS_MUTEX_PTR_DECLARE
log4cplus::thread::createNewMutex()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
pthread_mutex_t* m = new pthread_mutex_t();
pthread_mutex_init(m, NULL);
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
CRITICAL_SECTION* m = new CRITICAL_SECTION();
InitializeCriticalSection(m);
#endif
return m;
}
void
log4cplus::thread::deleteMutex(LOG4CPLUS_MUTEX_PTR_DECLARE m)
{
#if defined(LOG4CPLUS_USE_PTHREADS)
pthread_mutex_destroy(m);
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
DeleteCriticalSection(m);
#endif
delete m;
}
#if defined(LOG4CPLUS_USE_PTHREADS)
pthread_key_t*
log4cplus::thread::createPthreadKey()
{
pthread_key_t* key = new pthread_key_t();
pthread_key_create(key, NULL);
return key;
}
#endif
void
log4cplus::thread::yield()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
::sched_yield();
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
::Sleep(0);
#endif
}
log4cplus::tstring
log4cplus::thread::getCurrentThreadName()
{
#if 1
log4cplus::tostringstream tmp;
tmp << LOG4CPLUS_GET_CURRENT_THREAD;
return tmp.str();
#else
return convertIntegerToString(LOG4CPLUS_GET_CURRENT_THREAD);
#endif
}
#if defined(LOG4CPLUS_USE_PTHREADS)
void*
log4cplus::thread::threadStartFunc(void* arg)
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
DWORD WINAPI
log4cplus::thread::threadStartFunc(LPVOID arg)
#endif
{
SharedObjectPtr<LogLog> loglog = LogLog::getLogLog();
if(arg == NULL) {
loglog->error(LOG4CPLUS_TEXT("log4cplus::thread::threadStartFunc()- arg is NULL"));
}
else {
AbstractThread* ptr = static_cast<AbstractThread*>(arg);
log4cplus::helpers::SharedObjectPtr<AbstractThread> thread(ptr);
try {
thread->run();
}
catch(std::exception& e) {
tstring err = LOG4CPLUS_TEXT("log4cplus::thread::threadStartFunc()- run() terminated with an exception: ");
err += LOG4CPLUS_C_STR_TO_TSTRING(e.what());
loglog->warn(err);
}
catch(...) {
loglog->warn(LOG4CPLUS_TEXT("log4cplus::thread::threadStartFunc()- run() terminated with an exception."));
}
thread->running = false;
getNDC().remove();
}
#if defined(LOG4CPLUS_USE_PTHREADS)
pthread_exit(NULL);
#endif
return NULL;
}
///////////////////////////////////////////////////////////////////////////////
// log4cplus::thread::AbstractThread ctor and dtor
///////////////////////////////////////////////////////////////////////////////
log4cplus::thread::AbstractThread::AbstractThread()
: running(false)
{
}
log4cplus::thread::AbstractThread::~AbstractThread()
{
}
///////////////////////////////////////////////////////////////////////////////
// log4cplus::thread::AbstractThread public methods
///////////////////////////////////////////////////////////////////////////////
void
log4cplus::thread::AbstractThread::start()
{
running = true;
#if defined(LOG4CPLUS_USE_PTHREADS)
if( pthread_create(&threadId, NULL, threadStartFunc, this) ) {
throw std::runtime_error(LOG4CPLUS_TEXT("Thread creation was not successful"));
}
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
HANDLE h = CreateThread(NULL, 0, threadStartFunc, (LPVOID)this, 0, &threadId);
CloseHandle(h);
#endif
}
#endif // LOG4CPLUS_SINGLE_THREADED
syntax highlighted by Code2HTML, v. 0.9.1