summaryrefslogtreecommitdiff
path: root/cppu/source/threadpool
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 14:29:57 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 14:29:57 +0000
commitb525a3115f54576017a576ff842dede5e2e3545d (patch)
treec534b95a9e572b63896467624293a5ca1887d3a3 /cppu/source/threadpool
parent9399c662f36c385b0c705eb34e636a9aec450282 (diff)
initial import
Diffstat (limited to 'cppu/source/threadpool')
-rw-r--r--cppu/source/threadpool/jobqueue.cxx223
-rw-r--r--cppu/source/threadpool/jobqueue.hxx112
-rw-r--r--cppu/source/threadpool/makefile.mk88
-rw-r--r--cppu/source/threadpool/thread.cxx170
-rw-r--r--cppu/source/threadpool/thread.hxx102
-rw-r--r--cppu/source/threadpool/threadident.cxx218
-rw-r--r--cppu/source/threadpool/threadpool.cxx473
-rw-r--r--cppu/source/threadpool/threadpool.hxx163
8 files changed, 1549 insertions, 0 deletions
diff --git a/cppu/source/threadpool/jobqueue.cxx b/cppu/source/threadpool/jobqueue.cxx
new file mode 100644
index 000000000000..46f263042221
--- /dev/null
+++ b/cppu/source/threadpool/jobqueue.cxx
@@ -0,0 +1,223 @@
+/*************************************************************************
+ *
+ * $RCSfile: jobqueue.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include "jobqueue.hxx"
+#include "threadpool.hxx"
+
+#include <osl/diagnose.h>
+
+using namespace ::osl;
+
+namespace cppu_threadpool {
+
+ JobQueue::JobQueue( sal_Bool bAsynchron ) :
+ m_cndWait( osl_createCondition() ),
+ m_bSuspended( sal_False ),
+ m_nToDo( 0 )
+ {
+ osl_resetCondition( m_cndWait );
+ }
+
+ JobQueue::~JobQueue()
+ {
+ osl_destroyCondition( m_cndWait );
+ }
+
+
+ void JobQueue::add( void *pThreadSpecificData ,
+ void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ) )
+ {
+ MutexGuard guard( m_mutex );
+ Job job = { pThreadSpecificData , doRequest };
+ m_lstJob.push_back( job );
+ if( ! m_bSuspended )
+ {
+ osl_setCondition( m_cndWait );
+ }
+ m_nToDo ++;
+ }
+
+ void *JobQueue::enter( sal_Int64 nDisposeId , sal_Bool bReturnWhenNoJob )
+ {
+ void *pReturn = 0;
+ {
+ // synchronize with the dispose calls
+ MutexGuard guard( m_mutex );
+ if( DisposedCallerAdmin::getInstance()->isDisposed( nDisposeId ) )
+ {
+ return 0;
+ }
+ m_lstCallstack.push_front( nDisposeId );
+ }
+
+
+ while( sal_True )
+ {
+ if( bReturnWhenNoJob )
+ {
+ MutexGuard guard( m_mutex );
+ if( m_lstJob.empty() )
+ {
+ break;
+ }
+ }
+
+ osl_waitCondition( m_cndWait , 0 );
+
+ struct Job job={0,0};
+ {
+ // synchronize with add and dispose calls
+ MutexGuard guard( m_mutex );
+
+ if( 0 == m_lstCallstack.front() )
+ {
+ // disposed !
+ break;
+ }
+
+ OSL_ASSERT( ! m_lstJob.empty() );
+ if( ! m_lstJob.empty() )
+ {
+ job = m_lstJob.front();
+ m_lstJob.pop_front();
+ }
+ if( m_lstJob.empty() )
+ {
+ osl_resetCondition( m_cndWait );
+ }
+ }
+
+ if( job.doRequest )
+ {
+ job.doRequest( job.pThreadSpecificData );
+ m_nToDo --;
+ }
+ else
+ {
+ m_nToDo --;
+ pReturn = job.pThreadSpecificData;
+ break;
+ }
+ }
+
+ {
+ // synchronize with the dispose calls
+ MutexGuard guard( m_mutex );
+ m_lstCallstack.pop_front();
+ }
+
+ return pReturn;
+ }
+
+ void JobQueue::dispose( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ for( CallStackList::iterator ii = m_lstCallstack.begin() ;
+ ii != m_lstCallstack.end() ;
+ ++ii )
+ {
+ if( (*ii) == nDisposeId )
+ {
+ (*ii) = 0;
+ }
+ }
+
+ if( !m_lstCallstack.empty() && ! m_lstCallstack.front() )
+ {
+ // The thread is waiting for a disposed pCallerId, let it go
+ osl_setCondition( m_cndWait );
+ }
+ }
+
+ void JobQueue::suspend()
+ {
+ MutexGuard guard( m_mutex );
+ m_bSuspended = sal_True;
+ }
+
+ void JobQueue::resume()
+ {
+ MutexGuard guard( m_mutex );
+ m_bSuspended = sal_False;
+ if( ! m_lstJob.empty() )
+ {
+ osl_setCondition( m_cndWait );
+ }
+ }
+
+ sal_Bool JobQueue::isEmpty()
+ {
+ MutexGuard guard( m_mutex );
+ return m_lstJob.empty();
+ }
+
+ sal_Bool JobQueue::isCallstackEmpty()
+ {
+ MutexGuard guard( m_mutex );
+ return m_lstCallstack.empty();
+ }
+
+ sal_Bool JobQueue::isBusy()
+ {
+ return m_nToDo > 0;
+ }
+
+
+}
diff --git a/cppu/source/threadpool/jobqueue.hxx b/cppu/source/threadpool/jobqueue.hxx
new file mode 100644
index 000000000000..53ba018a71a5
--- /dev/null
+++ b/cppu/source/threadpool/jobqueue.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * $RCSfile: jobqueue.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _CPPU_THREADPOOL_JOBQUEUE_HXX_
+#define _CPPU_THREADPOOL_JOBQUEUE_HXX_
+
+#include <list>
+
+#include <osl/types.h>
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+
+namespace cppu_threadpool
+{
+ struct Job
+ {
+ void *pThreadSpecificData;
+ void ( SAL_CALL *doRequest ) ( void * );
+ };
+
+ typedef ::std::list < struct Job > JobList;
+
+ typedef ::std::list < sal_Int64 > CallStackList;
+
+ class JobQueue
+ {
+ public:
+ JobQueue( sal_Bool bAsynchron );
+ ~JobQueue();
+
+ void add( void *pThreadSpecificData ,
+ void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ) );
+
+ void *enter( sal_Int64 nDisposeId , sal_Bool bReturnWhenNoJob = sal_False );
+ void dispose( sal_Int64 nDisposeId );
+
+ void suspend();
+ void resume();
+
+ sal_Bool isEmpty();
+ sal_Bool isCallstackEmpty();
+ sal_Bool isBusy();
+
+ private:
+ ::osl::Mutex m_mutex;
+ JobList m_lstJob;
+ CallStackList m_lstCallstack;
+ sal_Int32 m_nToDo;
+ sal_Bool m_bSuspended;
+ oslCondition m_cndWait;
+ };
+}
+
+#endif
diff --git a/cppu/source/threadpool/makefile.mk b/cppu/source/threadpool/makefile.mk
new file mode 100644
index 000000000000..7a82725ba517
--- /dev/null
+++ b/cppu/source/threadpool/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=cppu
+TARGET=cppu_threadpool
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/makefile.pmk
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/threadpool.obj\
+ $(SLO)$/jobqueue.obj\
+ $(SLO)$/thread.obj\
+ $(SLO)$/threadident.obj
+
+# $(SLO)$/threadpool.obj \
+# $(SLO)$/process.obj \
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/target.pmk
+.INCLUDE : target.mk
diff --git a/cppu/source/threadpool/thread.cxx b/cppu/source/threadpool/thread.cxx
new file mode 100644
index 000000000000..9d006ff142f2
--- /dev/null
+++ b/cppu/source/threadpool/thread.cxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * $RCSfile: thread.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <osl/diagnose.h>
+#include <uno/threadpool.h>
+
+#include "thread.hxx"
+#include "jobqueue.hxx"
+#include "threadpool.hxx"
+
+
+extern "C" {
+
+void SAL_CALL cppu_requestThreadWorker( void *pVoid )
+{
+ ::cppu_threadpool::ORequestThread *pThread = ( ::cppu_threadpool::ORequestThread * ) pVoid;
+
+ pThread->run();
+ pThread->onTerminated();
+}
+
+}
+namespace cppu_threadpool {
+
+ ORequestThread::ORequestThread( JobQueue *pQueue,
+ const ByteSequence &aThreadId,
+ sal_Bool bAsynchron )
+ : m_pQueue( pQueue )
+ , m_thread( 0 )
+ , m_aThreadId( aThreadId )
+ , m_bAsynchron( bAsynchron )
+ {
+
+ }
+
+
+ ORequestThread::~ORequestThread()
+ {
+ if (m_thread != 0)
+ {
+ osl_freeThreadHandle(m_thread);
+ }
+ }
+
+
+ void ORequestThread::setTask( JobQueue *pQueue,
+ const ByteSequence &aThreadId,
+ sal_Bool bAsynchron )
+ {
+ m_pQueue = pQueue;
+ m_aThreadId = aThreadId;
+ m_bAsynchron = bAsynchron;
+ }
+
+ sal_Bool ORequestThread::create()
+ {
+ OSL_ASSERT(m_thread == 0); // only one running thread per instance
+
+ if ( m_thread = osl_createSuspendedThread( cppu_requestThreadWorker, (void*)this))
+ {
+ osl_resumeThread( m_thread );
+ }
+
+ return m_thread != 0;
+ }
+
+ void ORequestThread::onTerminated()
+ {
+ delete this;
+ }
+
+ // hack during no proper threadlocalstorage support
+ void SAL_CALL destructCurrentId();
+
+ void ORequestThread::run()
+ {
+ while ( m_pQueue )
+ {
+ if( ! m_bAsynchron )
+ {
+ sal_Bool bReturn = uno_bindIdToCurrentThread( m_aThreadId.getHandle() );
+ OSL_ASSERT( bReturn );
+ }
+
+ while( ! m_pQueue->isEmpty() )
+ {
+ // Note : Oneways should not get a disposable disposeid,
+ // It does not make sense to dispose a call in this state.
+ // That's way we put it an disposeid, that can't be used otherwise.
+ m_pQueue->enter( (sal_Int64 ) this , sal_True );
+
+ if( m_pQueue->isEmpty() )
+ {
+ ThreadPool::getInstance()->revokeQueue( m_aThreadId , m_bAsynchron );
+ // Note : revokeQueue might have failed because m_pQueue.isEmpty()
+ // may be false (race).
+ }
+ }
+
+ delete m_pQueue;
+ m_pQueue = 0;
+
+ if( ! m_bAsynchron )
+ {
+ uno_releaseIdFromCurrentThread();
+ }
+
+ cppu_threadpool::ThreadPool::getInstance()->waitInPool( this );
+ }
+ destructCurrentId();
+ }
+}
diff --git a/cppu/source/threadpool/thread.hxx b/cppu/source/threadpool/thread.hxx
new file mode 100644
index 000000000000..0099150b71ee
--- /dev/null
+++ b/cppu/source/threadpool/thread.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * $RCSfile: thread.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CPPU_THREADPOOL_THREAD_HXX
+#define _CPPU_THREADPOOL_THREAD_HXX
+
+#include <osl/types.h>
+#include <osl/thread.h>
+
+#include "jobqueue.hxx"
+
+namespace cppu_threadpool {
+
+ class JobQueue;
+
+ //-----------------------------------------
+ // private thread class for the threadpool
+ // independent from vos
+ //-----------------------------------------
+ class ORequestThread
+ {
+ public:
+ ORequestThread( JobQueue * ,
+ const ::rtl::ByteSequence &aThreadId,
+ sal_Bool bAsynchron );
+ ~ORequestThread();
+
+ void setTask( JobQueue * , const ::rtl::ByteSequence & aThreadId , sal_Bool bAsynchron );
+
+ sal_Bool create();
+ void onTerminated();
+ void run();
+
+ private:
+ oslThread m_thread;
+ JobQueue *m_pQueue;
+ ::rtl::ByteSequence m_aThreadId;
+ sal_Bool m_bAsynchron;
+ };
+
+} // end cppu_threadpool
+
+
+#endif
+
diff --git a/cppu/source/threadpool/threadident.cxx b/cppu/source/threadpool/threadident.cxx
new file mode 100644
index 000000000000..cedf69b6e869
--- /dev/null
+++ b/cppu/source/threadpool/threadident.cxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * $RCSfile: threadident.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <assert.h>
+
+#include <list>
+#include <hash_map>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <osl/diagnose.h>
+
+#include <rtl/process.h>
+#include <rtl/byteseq.hxx>
+
+#include <uno/threadpool.h>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+
+static sal_Bool g_bInitialized;
+static oslThreadKey g_key;
+
+namespace cppu_threadpool
+{
+struct IdContainer
+{
+ sal_Sequence *pLocalThreadId;
+ sal_Int32 nRefCountOfCurrentId;
+ sal_Sequence *pCurrentId;
+};
+}
+using namespace cppu_threadpool;
+
+static inline oslThreadKey getKey()
+{
+ if( ! g_bInitialized )
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ if( ! g_bInitialized )
+ {
+ g_key = osl_createThreadKey();
+ g_bInitialized = sal_True;
+ }
+ }
+ return g_key;
+}
+
+static inline void createLocalId( sal_Sequence **ppThreadId )
+{
+ rtl_byte_sequence_constructNoDefault( ppThreadId , 4 + 16 );
+ *((sal_Int32*) ((*ppThreadId)->elements)) = osl_getThreadIdentifier(0);
+
+ rtl_getGlobalProcessId( (sal_uInt8 * ) &( (*ppThreadId)->elements[4]) );
+}
+
+
+static void SAL_CALL destructIdContainer( void *p )
+{
+ if( p )
+ {
+ IdContainer *pId = (IdContainer * ) p;
+ rtl_byte_sequence_release( pId->pLocalThreadId );
+ rtl_byte_sequence_release( pId->pCurrentId );
+ rtl_freeMemory( p );
+ }
+}
+
+
+//--------------------------------------------------------
+// private hack as long as no proper threadlocal storage is provided
+//--------------------------------------------------------
+namespace cppu_threadpool {
+void SAL_CALL destructCurrentId()
+{
+ destructIdContainer( osl_getThreadKeyData( getKey() ) );
+}
+}
+
+
+extern "C" SAL_DLLEXPORT void SAL_CALL
+uno_getIdOfCurrentThread( sal_Sequence **ppThreadId )
+{
+ IdContainer * p = (IdContainer * ) osl_getThreadKeyData( getKey() );
+ if( ! p )
+ {
+ // first time, that the thread enters the bridge
+ createLocalId( ppThreadId );
+
+ // TODO
+ // note : this is a leak !
+ IdContainer *p = (IdContainer *) rtl_allocateMemory( sizeof( IdContainer ) );
+ p->pLocalThreadId = *ppThreadId;
+ p->pCurrentId = *ppThreadId;
+ p->nRefCountOfCurrentId = 1;
+ rtl_byte_sequence_acquire( p->pLocalThreadId );
+ rtl_byte_sequence_acquire( p->pCurrentId );
+
+ OSL_VERIFY( osl_setThreadKeyData( getKey(), p ) );
+ }
+ else
+ {
+ p->nRefCountOfCurrentId ++;
+ if( *ppThreadId )
+ {
+ rtl_byte_sequence_release( *ppThreadId );
+ }
+ *ppThreadId = p->pCurrentId;
+ rtl_byte_sequence_acquire( *ppThreadId );
+ }
+}
+
+
+extern "C" SAL_DLLEXPORT void SAL_CALL uno_releaseIdFromCurrentThread()
+{
+ IdContainer *p = (IdContainer * ) osl_getThreadKeyData( getKey() );
+ OSL_ASSERT( p );
+ OSL_ASSERT( p->nRefCountOfCurrentId );
+
+ p->nRefCountOfCurrentId --;
+ if( ! p->nRefCountOfCurrentId && (p->pLocalThreadId != p->pCurrentId) )
+ {
+ rtl_byte_sequence_assign( &(p->pCurrentId) , p->pLocalThreadId );
+ }
+}
+
+extern "C" SAL_DLLEXPORT sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId )
+{
+ IdContainer *p = (IdContainer * ) osl_getThreadKeyData( getKey() );
+ if( ! p )
+ {
+ IdContainer *p = (IdContainer * ) rtl_allocateMemory( sizeof( IdContainer ) );
+
+ p->pLocalThreadId = 0;
+ createLocalId( &(p->pLocalThreadId) );
+ p->nRefCountOfCurrentId = 1;
+ p->pCurrentId = pThreadId;
+ rtl_byte_sequence_acquire( p->pCurrentId );
+ osl_setThreadKeyData( getKey() , p );
+ }
+ else
+ {
+ OSL_ASSERT( 0 == p->nRefCountOfCurrentId );
+ if( 0 == p->nRefCountOfCurrentId )
+ {
+ rtl_byte_sequence_assign(&( p->pCurrentId ), pThreadId );
+ p->nRefCountOfCurrentId ++;
+ }
+ else
+ {
+ return sal_False;
+ }
+
+ }
+ return sal_True;
+}
diff --git a/cppu/source/threadpool/threadpool.cxx b/cppu/source/threadpool/threadpool.cxx
new file mode 100644
index 000000000000..7133eeb149e3
--- /dev/null
+++ b/cppu/source/threadpool/threadpool.cxx
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *
+ * $RCSfile: threadpool.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+
+#include <uno/threadpool.h>
+
+#include "threadpool.hxx"
+#include "thread.hxx"
+
+using namespace ::std;
+using namespace ::osl;
+
+struct uno_threadpool_Handle
+{
+ /**
+ * Global Threadidentifier of the waiting thread
+ **/
+ uno_threadpool_Handle( const ByteSequence &aThreadId_ , sal_Int64 nDisposeId_ )
+ : aThreadId( aThreadId_ )
+ , nDisposeId( nDisposeId_ )
+ {}
+
+ ByteSequence aThreadId;
+ sal_Int64 nDisposeId;
+};
+
+namespace cppu_threadpool
+{
+ DisposedCallerAdmin *DisposedCallerAdmin::getInstance()
+ {
+ static DisposedCallerAdmin *pDisposedCallerAdmin = 0;
+ if( ! pDisposedCallerAdmin )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pDisposedCallerAdmin )
+ {
+ static DisposedCallerAdmin admin;
+ pDisposedCallerAdmin = &admin;
+ }
+ }
+ return pDisposedCallerAdmin;
+ }
+
+ DisposedCallerAdmin::~DisposedCallerAdmin()
+ {
+#ifdef DEBUG
+ if( !m_lst.empty() )
+ {
+ printf( "DisposedCallerList : %d left\n" , m_lst.size( ));
+ }
+#endif
+ }
+
+ void DisposedCallerAdmin::dispose( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ m_lst.push_back( nDisposeId );
+ }
+
+ void DisposedCallerAdmin::stopDisposing( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ for( DisposedCallerList::iterator ii = m_lst.begin() ;
+ ii != m_lst.end() ;
+ ++ ii )
+ {
+ if( (*ii) == nDisposeId )
+ {
+ m_lst.erase( ii );
+ break;
+ }
+ }
+ }
+
+ sal_Bool DisposedCallerAdmin::isDisposed( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ for( DisposedCallerList::iterator ii = m_lst.begin() ;
+ ii != m_lst.end() ;
+ ++ ii )
+ {
+ if( (*ii) == nDisposeId )
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+ }
+
+
+ //-------------------------------------------------------------------------------
+ ThreadPool::~ThreadPool()
+ {
+#ifdef DEBUG
+ if( m_mapQueue.size() )
+ {
+ printf( "ThreadIdHashMap : %d left\n" , m_mapQueue.size() );
+ }
+#endif
+ }
+ ThreadPool *ThreadPool::getInstance()
+ {
+ static ThreadPool *pThreadPool = 0;
+ if( ! pThreadPool )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pThreadPool )
+ {
+ static ThreadPool pool;
+ pThreadPool = &pool;
+ }
+ }
+ return pThreadPool;
+ }
+
+
+ void ThreadPool::dispose( sal_Int64 nDisposeId )
+ {
+ DisposedCallerAdmin::getInstance()->dispose( nDisposeId );
+
+ MutexGuard guard( m_mutex );
+ for( ThreadIdHashMap::iterator ii = m_mapQueue.begin() ;
+ ii != m_mapQueue.end();
+ ++ii)
+ {
+ if( (*ii).second.first )
+ {
+ (*ii).second.first->dispose( nDisposeId );
+ }
+ if( (*ii).second.second )
+ {
+ (*ii).second.second->dispose( nDisposeId );
+ }
+ }
+ }
+
+ void ThreadPool::stopDisposing( sal_Int64 nDisposeId )
+ {
+ DisposedCallerAdmin::getInstance()->stopDisposing( nDisposeId );
+ }
+
+ /******************
+ * This methods lets the thread wait a certain amount of time. If within this timespan
+ * a new request comes in, this thread is reused. This is done only to improve performance,
+ * it is not required for threadpool functionality.
+ ******************/
+ void ThreadPool::waitInPool( ORequestThread * pThread )
+ {
+ struct WaitingThread waitingThread;
+ waitingThread.condition = osl_createCondition();
+ waitingThread.thread = pThread;
+ {
+ MutexGuard guard( m_mutexWaitingThreadList );
+ m_lstThreads.push_front( &waitingThread );
+ }
+
+ // let the thread wait 2 seconds
+ osl_resetCondition( waitingThread.condition );
+ TimeValue time = { 2 , 0 };
+ osl_waitCondition( waitingThread.condition , &time );
+
+ {
+ MutexGuard guard ( m_mutexWaitingThreadList );
+ if( waitingThread.thread )
+ {
+ // thread wasn't reused, remove it from the list
+ WaitingThreadList::iterator ii = find(
+ m_lstThreads.begin(), m_lstThreads.end(), &waitingThread );
+ OSL_ASSERT( ii != m_lstThreads.end() );
+ m_lstThreads.erase( ii );
+ }
+ }
+
+ osl_destroyCondition( waitingThread.condition );
+ }
+
+ void ThreadPool::createThread( JobQueue *pQueue ,
+ const ByteSequence &aThreadId,
+ sal_Bool bAsynchron )
+ {
+ sal_Bool bCreate = sal_True;
+ {
+ // Can a thread be reused ?
+ MutexGuard guard( m_mutexWaitingThreadList );
+ if( ! m_lstThreads.empty() )
+ {
+ // inform the thread and let it go
+ struct WaitingThread *pWaitingThread = m_lstThreads.back();
+ pWaitingThread->thread->setTask( pQueue , aThreadId , bAsynchron );
+ pWaitingThread->thread = 0;
+
+ // remove from list
+ m_lstThreads.pop_back();
+
+ // let the thread go
+ osl_setCondition( pWaitingThread->condition );
+ bCreate = sal_False;
+ }
+ }
+
+ if( bCreate )
+ {
+ ORequestThread *pThread =
+ new ORequestThread( pQueue , aThreadId, bAsynchron);
+ // deletes itself !
+ pThread->create();
+ }
+ }
+
+ sal_Bool ThreadPool::revokeQueue( const ByteSequence &aThreadId, sal_Bool bAsynchron )
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+ OSL_ASSERT( ii != m_mapQueue.end() );
+
+ if( bAsynchron )
+ {
+ if( ! (*ii).second.second->isEmpty() )
+ {
+ // another thread has put something into the queue
+ return sal_False;
+ }
+
+ (*ii).second.second = 0;
+ if( (*ii).second.first )
+ {
+ // all oneway request have been processed, now
+ // synchronus requests may go on
+ (*ii).second.first->resume();
+ }
+ }
+ else
+ {
+ if( ! (*ii).second.first->isEmpty() )
+ {
+ // another thread has put something into the queue
+ return sal_False;
+ }
+ (*ii).second.first = 0;
+ }
+
+ if( 0 == (*ii).second.first && 0 == (*ii).second.second )
+ {
+ m_mapQueue.erase( ii );
+ }
+
+ return sal_True;
+ }
+
+
+ void ThreadPool::addJob(
+ const ByteSequence &aThreadId ,
+ sal_Bool bAsynchron,
+ void *pThreadSpecificData,
+ void ( SAL_CALL * doRequest ) ( void * ) )
+ {
+ sal_Bool bCreateThread = sal_False;
+ JobQueue *pQueue = 0;
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+
+ if( ii == m_mapQueue.end() )
+ {
+ m_mapQueue[ aThreadId ] = pair < JobQueue * , JobQueue * > ( 0 , 0 );
+ ii = m_mapQueue.find( aThreadId );
+ OSL_ASSERT( ii != m_mapQueue.end() );
+ }
+
+ if( bAsynchron )
+ {
+ if( ! (*ii).second.second )
+ {
+ (*ii).second.second = new JobQueue( bAsynchron );
+ bCreateThread = sal_True;
+ }
+ pQueue = (*ii).second.second;
+ }
+ else
+ {
+ if( ! (*ii).second.first )
+ {
+ (*ii).second.first = new JobQueue( bAsynchron );
+ bCreateThread = sal_True;
+ }
+ pQueue = (*ii).second.first;
+
+ if( (*ii).second.second && ( (*ii).second.second->isBusy() ) )
+ {
+ pQueue->suspend();
+ }
+ }
+ pQueue->add( pThreadSpecificData , doRequest );
+ }
+
+ if( bCreateThread )
+ {
+ createThread( pQueue , aThreadId , bAsynchron);
+ }
+ }
+
+ void ThreadPool::prepare( const ByteSequence &aThreadId )
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+
+ if( ii == m_mapQueue.end() )
+ {
+ JobQueue *p = new JobQueue( sal_False );
+ m_mapQueue[ aThreadId ] = pair< JobQueue * , JobQueue * > ( p , 0 );
+ }
+ else if( 0 == (*ii).second.first )
+ {
+ (*ii).second.first = new JobQueue( sal_False );
+ }
+ }
+
+ void * ThreadPool::enter( const ByteSequence & aThreadId , sal_Int64 nDisposeId )
+ {
+ JobQueue *pQueue = 0;
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+
+ OSL_ASSERT( ii != m_mapQueue.end() );
+ pQueue = (*ii).second.first;
+ }
+
+ OSL_ASSERT( pQueue );
+ void *pReturn = pQueue->enter( nDisposeId );
+
+ if( pQueue->isCallstackEmpty() )
+ {
+ if( revokeQueue( aThreadId , sal_False) )
+ {
+ // remove queue
+ delete pQueue;
+ }
+ }
+ return pReturn;
+ }
+}
+
+
+using namespace cppu_threadpool;
+
+
+//------------------------------
+//
+// The C-Interface
+//
+//-------------------------------
+extern "C" SAL_DLLEXPORT void SAL_CALL uno_threadpool_putRequest(
+ sal_Sequence *pThreadId, void *pThreadSpecificData,
+ void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ), sal_Bool bIsOneway )
+{
+ ThreadPool::getInstance()->addJob( pThreadId, bIsOneway, pThreadSpecificData,doRequest );
+}
+
+
+
+extern "C" SAL_DLLEXPORT void SAL_CALL uno_threadpool_putReply(
+ sal_Sequence *pThreadId, void *pThreadSpecificData )
+{
+ ThreadPool::getInstance()->addJob( pThreadId, sal_False, pThreadSpecificData, 0 );
+}
+
+
+extern "C" SAL_DLLEXPORT struct uno_threadpool_Handle * SAL_CALL
+uno_threadpool_createHandle( sal_Int64 nDisposeId )
+{
+ sal_Sequence *pThreadId = 0;
+ uno_getIdOfCurrentThread( &pThreadId );
+
+ struct uno_threadpool_Handle *pHandle = new uno_threadpool_Handle( pThreadId, nDisposeId );
+ ThreadPool::getInstance()->prepare( pThreadId );
+
+ rtl_byte_sequence_release( pThreadId );
+
+ return pHandle;
+}
+
+extern "C" SAL_DLLEXPORT void SAL_CALL uno_threadpool_enter(
+ struct uno_threadpool_Handle *pHandle , void **ppThreadSpecificData )
+{
+ OSL_ASSERT( ppThreadSpecificData );
+
+ *ppThreadSpecificData =
+ ThreadPool::getInstance()->enter( pHandle->aThreadId , pHandle->nDisposeId );
+
+ uno_releaseIdFromCurrentThread();
+ delete pHandle;
+}
+
+
+extern "C" SAL_DLLEXPORT void SAL_CALL
+uno_threadpool_disposeThreads( sal_Int64 nDisposeId )
+{
+ ThreadPool::getInstance()->dispose( nDisposeId );
+}
+
+extern "C" SAL_DLLEXPORT void SAL_CALL
+uno_threadpool_stopDisposeThreads( sal_Int64 nDisposeId )
+{
+ ThreadPool::getInstance()->stopDisposing( nDisposeId );
+}
diff --git a/cppu/source/threadpool/threadpool.hxx b/cppu/source/threadpool/threadpool.hxx
new file mode 100644
index 000000000000..46b822b8b09b
--- /dev/null
+++ b/cppu/source/threadpool/threadpool.hxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * $RCSfile: threadpool.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:25:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <hash_map>
+
+#include <osl/conditn.h>
+
+#include <rtl/byteseq.hxx>
+
+#include "jobqueue.hxx"
+
+
+using namespace ::rtl;
+namespace cppu_threadpool {
+ class ORequestThread;
+
+ struct EqualThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const
+ {
+ return a == b;
+ }
+ };
+
+ struct HashThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a ) const
+ {
+ if( a.getLength() >= 4 )
+ {
+ return *(sal_Int32 *)a.getConstArray();
+ }
+ return 0;
+ }
+ };
+
+ typedef ::std::hash_map
+ <
+ ByteSequence, // ThreadID
+ ::std::pair < JobQueue * , JobQueue * >,
+ HashThreadId,
+ EqualThreadId
+ > ThreadIdHashMap;
+
+ typedef ::std::list < sal_Int64 > DisposedCallerList;
+
+
+ struct WaitingThread
+ {
+ oslCondition condition;
+ ORequestThread *thread;
+ };
+
+ typedef ::std::list < struct ::cppu_threadpool::WaitingThread * > WaitingThreadList;
+
+ class DisposedCallerAdmin
+ {
+ public:
+ ~DisposedCallerAdmin();
+
+ static DisposedCallerAdmin *getInstance();
+
+ void dispose( sal_Int64 nDisposeId );
+ void stopDisposing( sal_Int64 nDisposeId );
+ sal_Bool isDisposed( sal_Int64 nDisposeId );
+
+ private:
+ ::osl::Mutex m_mutex;
+ DisposedCallerList m_lst;
+ };
+
+ class ThreadPool
+ {
+ public:
+ ~ThreadPool();
+ static ThreadPool *getInstance();
+
+ void dispose( sal_Int64 nDisposeId );
+ void stopDisposing( sal_Int64 nDisposeId );
+
+ void addJob( const ByteSequence &aThreadId,
+ sal_Bool bAsynchron,
+ void *pThreadSpecificData,
+ void ( SAL_CALL * doRequest ) ( void * ) );
+
+ void prepare( const ByteSequence &aThreadId );
+ void * enter( const ByteSequence &aThreadId, sal_Int64 nDisposeId );
+
+ /********
+ * @return true, if queue could be succesfully revoked.
+ ********/
+ sal_Bool revokeQueue( const ByteSequence & aThreadId , sal_Bool bAsynchron );
+
+ void waitInPool( ORequestThread *pThread );
+ private:
+ void createThread( JobQueue *pQueue, const ByteSequence &aThreadId, sal_Bool bAsynchron);
+
+
+ ThreadIdHashMap m_mapQueue;
+ ::osl::Mutex m_mutex;
+
+ ::osl::Mutex m_mutexWaitingThreadList;
+ WaitingThreadList m_lstThreads;
+ };
+
+} // end namespace cppu_threadpool