|
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
|