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

ArThread_WIN.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
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 If you wish to redistribute ARIA under different terms, contact 
00021 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 // ArThread.cc -- Thread classes
00029 
00030 
00031 #include "ariaOSDef.h"
00032 #include <list>
00033 #include "ArThread.h"
00034 #include "ArLog.h"
00035 #include "ArSignalHandler.h"
00036 
00037 
00038 static DWORD WINAPI run(void *arg)
00039 {
00040   ArThread *t=(ArThread*)arg;
00041   void *ret=NULL;
00042 
00043   if (t->getBlockAllSignals())
00044     ArSignalHandler::blockCommonThisThread();
00045 
00046   if (dynamic_cast<ArRetFunctor<void*>*>(t->getFunc()))
00047     ret=((ArRetFunctor<void*>*)t->getFunc())->invokeR();
00048   else
00049     t->getFunc()->invoke();
00050 
00051   return((DWORD)ret);
00052 }
00053 
00054 void ArThread::init()
00055 {
00056   ArThread *main;
00057   ThreadType pt;
00058   MapType::iterator iter;
00059 
00060   pt=GetCurrentThread();
00061 
00062   ourThreadsMutex.lock();
00063   if (ourThreads.size())
00064   {
00065     ourThreadsMutex.unlock();
00066     return;
00067   }
00068   main=new ArThread;
00069   main->myJoinable=true;
00070   main->myRunning=true;
00071   main->myThread=pt;
00072   ourThreads.insert(MapType::value_type(pt, main));
00073   ourThreadsMutex.unlock();
00074 }
00075 
00076 
00077 ArThread * ArThread::self()
00078 {
00079   ThreadType pt;
00080   MapType::iterator iter;
00081 
00082   ourThreadsMutex.lock();
00083   pt=GetCurrentThread();
00084   iter=ourThreads.find(pt);
00085   ourThreadsMutex.unlock();
00086 
00087   if (iter != ourThreads.end())
00088     return((*iter).second);
00089   else
00090     return(NULL);
00091 }
00092 
00093 void ArThread::cancelAll()
00094 {
00095   DWORD ret=0;
00096   MapType::iterator iter;
00097 
00098   ourThreadsMutex.lock();
00099   for (iter=ourThreads.begin(); iter != ourThreads.end(); ++iter)
00100     TerminateThread((*iter).first, ret);
00101   ourThreads.clear();
00102   ourThreadsMutex.unlock();
00103 }
00104 
00105 int ArThread::create(ArFunctor *func, bool joinable,
00106                               bool lowerPriority)
00107 {
00108   DWORD ret=0, err;
00109 
00110   myJoinable=joinable;
00111   myFunc=func;
00112   myRunning=true;
00113 
00114   myThread=CreateThread(0, 0, &run, this, 0, &ret);
00115   err=GetLastError();
00116   if (myThread == 0)
00117   {
00118     ArLog::log(ArLog::Terse, "ArThread::create: Failed to create thread.");
00119     return(STATUS_FAILED);
00120   }
00121   else
00122   {
00123     if (myName.size() == 0)
00124       ArLog::log(ourLogLevel, "Created anonymous thread with ID %d", 
00125                  myThread);
00126     else
00127       ArLog::log(ourLogLevel, "Created %s thread with ID %d", myName.c_str(),
00128                  myThread);
00129     ourThreadsMutex.lock();
00130     ourThreads.insert(MapType::value_type(myThread, this));
00131     ourThreadsMutex.unlock();
00132     if (lowerPriority)
00133       SetThreadPriority(myThread, THREAD_PRIORITY_IDLE);
00134     return(0);
00135   }
00136 }
00137 
00138 int ArThread::doJoin(void **iret)
00139 {
00140   DWORD ret;
00141 
00142   ret=WaitForSingleObject(myThread, INFINITE);
00143   if (ret == WAIT_FAILED)
00144   {
00145     ArLog::log(ArLog::Terse, "ArThread::doJoin: Failed to join on thread.");
00146     return(STATUS_FAILED);
00147   }
00148 
00149   return(0);
00150 }
00151 
00152 int ArThread::detach()
00153 {
00154   return(0);
00155 }
00156 
00157 void ArThread::cancel()
00158 {
00159   DWORD ret=0;
00160 
00161   ourThreadsMutex.lock();
00162   ourThreads.erase(myThread);
00163   ourThreadsMutex.unlock();
00164   TerminateThread(myThread, ret);
00165 }
00166 
00167 void ArThread::yieldProcessor()
00168 {
00169   Sleep(0);
00170 }
00171 
00172 
00173 void ArThread::threadStarted(void)
00174 {
00175   if (myName.size() == 0)
00176     ArLog::log(ourLogLevel, "Anonymous thread (%d) is running",
00177                myThread);
00178   else
00179     ArLog::log(ourLogLevel, "Thread %s (%d) is running", 
00180                myName.c_str(), myThread);
00181 }
00182 
00183 void ArThread::logThreadInfo(void)
00184 {
00185   if (myName.size() == 0)
00186     ArLog::log(ourLogLevel, "Anonymous thread (%d) is running",
00187                myThread);
00188   else
00189     ArLog::log(ourLogLevel, "Thread %s (%d) is running", 
00190                myName.c_str(), myThread);
00191 }

Generated on Wed Oct 19 12:56:37 2005 for Aria by  doxygen 1.4.0