From: Bastiaan B. <bas...@li...> - 2002-08-01 23:20:37
|
Hi Emiliano, Thanks for the contribution. It has been committed, together with some crude m4 stuff to add a '--with-pthreads' option to ./configure. On RH Linux 7.3 this builds and passes 'make check' without problems. Of course the 'tests' directory does not contain any concurrency checks yet. Any volunteers to write some? =20 Now if I only finish the PropertyConfigurator stuff we can push 0.3.2 out the door. Cheers, Bastiaan Bakker LifeLine Networks bv On Thu, 2002-08-01 at 21:34, Emiliano Martin wrote: > Hi: >=20 > I'd like the idea, and i have done. This is a a Pthread implementation.=20 > I've tested with a multithreaded > program that i'm developing and seems to be ok, i expect it's ok with=20 > the philosofpy of log4cpp. > Any suggestion or thing you think must be changed, tell me please. > I expect new version be soon released. >=20 > Regards, >=20 > Emiliano Mart=EDn >=20 >=20 > Bastiaan Bakker wrote: >=20 > >Hi Emiliano, > > > >log4cpp 0.2.x does not explicitly support multithreading. > >But with some restrictions it still can be used in a multithreading > >environment: > >* don't change your logging configuration when you have multiple threads > >running. In most cases you'll setup your Category hierarchy before the > >application starts logging anyway, so this is not a large problem. Calls > >to setPriority() are still permitted. > >* The append function must be atomic. Log4cpp's appenders have been > >written in a way that requires only 1 call to the underlying system to > >write a log message (i.e. a single write() for the FileAppender). If > >your OS handles this atomically, the logfile will be OK. Otherwise you > >could end up with intertwined log messages. The latter appears to be the > >case at least with OstreamAppender on Win32 platforms. > > > >If you want to have full MT support, you'll be happy to know that as of > >version 0.3.0 log4cpp includes code for multithreading. Currently > >(release 0.3.2rc1) it supports Omnithreads and Win32 threads, but > >support for POSIX threads should not be too difficult to add: it > >requires an adapter implementation for a simple Mutex, ScopedLock and > >ThreadLocalData. You're very welcome to help in this area, if you like. > > > >Regards, > > > >Bastiaan Bakker > >LifeLine Networks bv > > =20 > > > >On Tue, 2002-06-18 at 18:05, Emiliano Martin wrote: > > =20 > > > >>Hi: > >> > >>I've read log4ccp does not suppport multithreading, can i do something= =20 > >>like this to assure atomic access=BF=BF > >>or it's very restrictive?? (or stupid) > >> > >> > >>void Category::_logUnconditionally(Priority::Value priority, > >> const char* format, > >> va_list arguments) throw() { > >> OstringStream messageBuffer; > >> > >> pthread_mutex_lock(writeMutex); > >> messageBuffer.vform(format, arguments); > >> _logUnconditionally2(priority, messageBuffer.str()); > >> pthread_mutex_unlock(writeMutex); > >> } > >> =20 > >>thanks in advance > >> > >> > >>-----------------------------------------------------------------------= ----- > >> Bringing you mounds of caffeinated joy > >> >>> http://thinkgeek.com/sf <<< > >> > >>_______________________________________________ > >>Log4cpp-devel mailing list > >>Log...@li... > >>https://lists.sourceforge.net/lists/listinfo/log4cpp-devel > >> =20 > >> > > > > > > > > =20 > > >=20 > ---- >=20 > /* > * PThreads.hh > * > * Copyright 2002, Emiliano Martin emi...@te... All rights reserve= d. > * > * See the COPYING file for the terms of usage and distribution. > */ >=20 > #ifndef _LOG4CPP_THREADING_PTHREADS_HH > #define _LOG4CPP_THREADING_PTHREADS_HH >=20 > #include <log4cpp/Portability.hh> > #include <stdio.h> > #include <pthread.h> > #include <string> > #include <assert.h> >=20 >=20 > namespace log4cpp { > namespace threading { >=20 > /**=20 > * returns the thread ID > **/ > static std::string getThreadId()=20 > { > char buffer[16]; > sprintf(buffer, "%ld", pthread_self()); > return std::string(buffer); =20 > } > =20 > /** > **/ > class Mutex=20 > { > private: > pthread_mutex_t mutex; >=20 > public: > inline Mutex() > { > pthread_mutex_init(&mutex, NULL); > } >=20 > inline void lock() > { > pthread_mutex_lock(&mutex); > } >=20 > inline void unlock() > { > pthread_mutex_unlock(&mutex); > } >=20 > inline ~Mutex() > { > pthread_mutex_destroy(&mutex); > } >=20 > inline void operator=3D(const Mutex &m) > { > mutex =3D m.mutex; > } > }; >=20 > /** > * definition of ScopedLock; > **/ > class ScopedLock > { > private: > Mutex _mutex; >=20 > public: > inline ScopedLock(const Mutex &mutex)=20 > {=20 > _mutex =3D mutex;=20 > _mutex.lock(); > } >=20 > inline ~ScopedLock()=20 > { > _mutex.unlock(); > } > }; >=20 > /** > *=20 > **/ > template<typename T> class ThreadLocalDataHolder=20 > { > private: =20 > pthread_key_t _key; =20 >=20 > public: > typedef T data_type; >=20 > inline ThreadLocalDataHolder()=20 > { > pthread_key_create(&_key, freeHolder); =20 > } >=20 > inline static void freeHolder(void *p) > { > assert(p !=3D NULL); > T *data =3D (T *) p; > delete p; > } >=20 > inline ~ThreadLocalDataHolder()=20 > { > T *data =3D get(); > if (data !=3D NULL) > {=20 > delete data; > } > pthread_key_delete(_key); > } > =20 > inline T* get() const=20 > { > return (T *) pthread_getspecific(_key);=20 > } >=20 > inline T* operator->() const { return get(); } > inline T& operator*() const { return *get(); } >=20 > inline T* release()=20 > { > T* result =3D get(); > pthread_setspecific(_key, NULL);=20 >=20 > return result; > } >=20 > inline void reset(T* p =3D NULL)=20 > { > T *data =3D get(); > if (data !=3D NULL)=20 > { > delete data; > } > pthread_setspecific(_key, p);=20 > } > }; >=20 > } > } > #endif |