00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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 }