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
00026 #include "DynThreads.hh"
00027
00028
00029 extern "C"
00030 {
00031
00032 void *WrapDynThreadBase (void *vpParam)
00033 {
00034 clDynThreadsBase::stpParams spParams =
00035 (clDynThreadsBase::stpParams) vpParam;
00036 clDynThreadsBase *Klass = spParams->Klass;
00037 void *vpICParam = spParams->vpParam;
00038
00039 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00040 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00041
00042 delete spParams;
00043 return Klass->InternalCaller(vpICParam);
00044 }
00045
00046 }
00047
00048
00049 clDynThreadsBase::clDynThreadsBase ()
00050 {
00051 iThreadCount = 0;
00052 }
00053
00054
00055 clDynThreadsBase::~clDynThreadsBase ()
00056 {
00057 try
00058 {
00059 MtxBase.Wait();
00060
00061 ThreadMap_t::iterator iterThreads;
00062
00063 iterThreads = mapThreads.begin();
00064 while (iterThreads != mapThreads.end())
00065 {
00066 pthread_cancel((*iterThreads).second);
00067 pthread_join((*iterThreads).second, NULL);
00068 iterThreads++;
00069 }
00070
00071 MtxBase.Release();
00072 }
00073 catch (...)
00074 {
00075 }
00076 }
00077
00078
00079 int clDynThreadsBase::Create (void *vpParam, bool bDetached)
00080 {
00081 stpParams spParams;
00082 pthread_t ptidThread;
00083 int iThreadHandle = -1;
00084
00085 spParams = new stParams;
00086 spParams->Klass = this;
00087 spParams->vpParam = vpParam;
00088
00089 pthread_create(&ptidThread, NULL, WrapDynThreadBase, (void *) spParams);
00090 if (!bDetached)
00091 {
00092 MtxBase.Wait();
00093
00094 while (mapThreads.find(iThreadCount) != mapThreads.end())
00095 {
00096 iThreadCount++;
00097 if (iThreadCount >= INT_MAX)
00098 iThreadCount = 0;
00099 }
00100 iThreadHandle = iThreadCount;
00101 mapThreads[iThreadCount++] = ptidThread;
00102 if (iThreadCount >= INT_MAX)
00103 iThreadCount = 0;
00104
00105 MtxBase.Release();
00106 }
00107 else
00108 {
00109 pthread_detach(ptidThread);
00110 }
00111 return iThreadHandle;
00112 }
00113
00114
00115 void *clDynThreadsBase::Wait (int iThreadHandle)
00116 {
00117 MtxBase.Wait();
00118
00119 ThreadMap_t::iterator iterThread;
00120 void *vpReturn = NULL;
00121
00122 iterThread = mapThreads.find(iThreadHandle);
00123 if (iterThread != mapThreads.end())
00124 {
00125 MtxBase.Release();
00126
00127 pthread_join((*iterThread).second, &vpReturn);
00128
00129 MtxBase.Wait();
00130
00131 mapThreads.erase(iterThread);
00132 }
00133
00134 MtxBase.Release();
00135
00136 return vpReturn;
00137 }
00138
00139
00140 bool clDynThreadsBase::SetSched (pthread_t ptidThread, int iPolicy, int iDelta)
00141 {
00142 int iEC;
00143 uid_t uidCurrent;
00144 struct sched_param sSchedParam;
00145
00146
00147 MtxBase.Wait();
00148 uidCurrent = getuid();
00149 setuid(0);
00150 # ifndef BSDSYS
00151 sSchedParam.sched_priority = sched_get_priority_min(iPolicy) + iDelta;
00152 # else
00153 sSchedParam.sched_priority = iDelta;
00154 # endif
00155 iEC = pthread_setschedparam(pthread_self(), iPolicy, &sSchedParam);
00156 setuid(uidCurrent);
00157 MtxBase.Release();
00158 if (iEC != 0) return false;
00159 return true;
00160 }