Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

DynThreads.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Class/template system for threading using pthreads
00004     Copyright (C) 2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <cstdio>
00024 #include <climits>
00025 #ifndef USE_NPTL
00026 #include <pthread.h>
00027 #else
00028 #include <nptl/pthread.h>
00029 #endif
00030 
00031 #include "DynThreads.hh"
00032 
00033 
00034 extern "C"
00035 {
00036 
00037 void *WrapDynThreadBase (void *vpParam)
00038 {
00039     clDynThreadsBase::stpParams spParams =
00040         (clDynThreadsBase::stpParams) vpParam;
00041     clDynThreadsBase *Klass = spParams->Klass;
00042     void *vpICParam = spParams->vpParam;
00043 
00044     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00045     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00046     
00047     delete spParams;
00048     return Klass->InternalCaller(vpICParam);
00049 }
00050 
00051 }
00052 
00053 
00054 clDynThreadsBase::clDynThreadsBase ()
00055 {
00056     iThreadCount = 0;
00057 }
00058 
00059 
00060 clDynThreadsBase::~clDynThreadsBase ()
00061 {
00062     try
00063     {
00064         MtxBase.Wait();
00065 
00066         ThreadMap_t::iterator iterThreads;
00067     
00068         iterThreads = mapThreads.begin();
00069         while (iterThreads != mapThreads.end())
00070         {
00071             pthread_cancel((*iterThreads).second);
00072             pthread_join((*iterThreads).second, NULL);
00073             iterThreads++;
00074         }
00075 
00076         MtxBase.Release();
00077     }
00078     catch (...)
00079     {
00080     }
00081 }
00082 
00083 
00084 int clDynThreadsBase::Create (void *vpParam, bool bDetached)
00085 {
00086     stpParams spParams;
00087     pthread_t ptidThread;
00088     int iThreadHandle = -1;
00089     
00090     spParams = new stParams;
00091     spParams->Klass = this;
00092     spParams->vpParam = vpParam;
00093 
00094     pthread_create(&ptidThread, NULL, WrapDynThreadBase, (void *) spParams);
00095     if (!bDetached)
00096     {
00097         MtxBase.Wait();
00098 
00099         while (mapThreads.find(iThreadCount) != mapThreads.end())
00100         {
00101             iThreadCount++;
00102             if (iThreadCount >= INT_MAX)
00103                 iThreadCount = 0;
00104         }
00105         iThreadHandle = iThreadCount;
00106         mapThreads[iThreadCount++] = ptidThread;
00107         if (iThreadCount >= INT_MAX)
00108             iThreadCount = 0;
00109 
00110         MtxBase.Release();
00111     }
00112     else
00113     {
00114         pthread_detach(ptidThread);
00115     }
00116     return iThreadHandle;
00117 }
00118 
00119 
00120 void *clDynThreadsBase::Wait (int iThreadHandle)
00121 {
00122     MtxBase.Wait();
00123 
00124     ThreadMap_t::iterator iterThread;
00125     void *vpReturn = NULL;
00126 
00127     iterThread = mapThreads.find(iThreadHandle);
00128     if (iterThread != mapThreads.end())
00129     {
00130         MtxBase.Release();
00131 
00132         pthread_join((*iterThread).second, &vpReturn);
00133 
00134         MtxBase.Wait();
00135 
00136         mapThreads.erase(iterThread);
00137     }
00138 
00139     MtxBase.Release();
00140 
00141     return vpReturn;
00142 }
00143 
00144 
00145 bool clDynThreadsBase::SetSched (pthread_t ptidThread, int iPolicy, int iDelta)
00146 {
00147     int iEC;
00148     uid_t uidCurrent;
00149     struct sched_param sSchedParam;
00150 
00151     // Serialize uid operations
00152     MtxBase.Wait();
00153     uidCurrent = getuid();
00154     setuid(0);
00155 #   ifndef BSDSYS
00156     sSchedParam.sched_priority = sched_get_priority_min(iPolicy) + iDelta;
00157 #   else
00158     sSchedParam.sched_priority = iDelta;
00159 #   endif
00160     iEC = pthread_setschedparam(pthread_self(), iPolicy, &sSchedParam);
00161     setuid(uidCurrent);
00162     MtxBase.Release();
00163     if (iEC != 0) return false;
00164     return true;
00165 }

Generated on Tue Mar 2 19:46:44 2004 for libDSP by doxygen 1.3.6