Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 12, 2008, 6:33:03 PM (17 years ago)
Author:
landauf
Message:

fixed some bugs

Location:
code/branches/console/src/core
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/console/src/core/TclThreadManager.cc

    r1255 r1257  
    4343#include "util/Convert.h"
    4444
    45 #define TCLTHREADMANAGER_MAX_QUEUE_LENGTH 1024
     45#define TCLTHREADMANAGER_MAX_QUEUE_LENGTH 100
    4646#define TCLTHREADMANAGER_MAX_CPU_USAGE 0.50
    4747
     
    6565        this->orxonoxInterpreterBundle_.id_ = 0;
    6666        this->orxonoxInterpreterBundle_.interpreter_ = TclBind::getInstance().getTclInterpreter();
     67        this->threadID_ = boost::this_thread::get_id();
    6768    }
    6869
     
    7576    unsigned int TclThreadManager::create()
    7677    {
    77         boost::mutex::scoped_lock lock(TclThreadManager::getInstance().bundlesMutex_);
     78        boost::mutex::scoped_lock bundles_lock(TclThreadManager::getInstance().bundlesMutex_);
    7879        TclThreadManager::getInstance().threadCounter_++;
    7980        std::string name = getConvertedValue<unsigned int, std::string>(TclThreadManager::getInstance().threadCounter_);
     
    8485        bundle->interpreterName_ = name;
    8586        bundle->running_ = true;
     87        bundle->finished_ = true;
    8688
    8789        TclThreadManager::getInstance().interpreterBundles_[TclThreadManager::getInstance().threadCounter_] = bundle;
     
    9698        {
    9799            {
    98                 boost::mutex::scoped_lock lock(bundle->runningMutex_);
     100                boost::mutex::scoped_lock running_lock(bundle->runningMutex_);
    99101                bundle->running_ = false;
    100102            }
    101             {
    102                 boost::mutex::scoped_lock lock(bundle->finishedMutex_);
    103                 while (!bundle->finished_)
    104                     bundle->finishedCondition_.wait(lock);
    105             }
    106             {
    107                 boost::mutex::scoped_lock lock(bundle->interpreterMutex_);
    108                 delete bundle->interpreter_;
    109             }
    110             delete bundle;
    111             {
    112                 boost::mutex::scoped_lock lock(TclThreadManager::getInstance().bundlesMutex_);
    113                 TclThreadManager::getInstance().interpreterBundles_.erase(threadID);
    114             }
     103            while (true)
     104            {
     105                {
     106                    boost::mutex::scoped_lock finished_lock(bundle->finishedMutex_);
     107                    if (bundle->finished_)
     108                    {
     109                        boost::mutex::scoped_lock bundles_lock(TclThreadManager::getInstance().bundlesMutex_);
     110                        boost::mutex::scoped_lock interpreter_lock(bundle->interpreterMutex_, boost::defer_lock_t());
     111                        try
     112                        {
     113                            while (!interpreter_lock.try_lock())
     114                            {
     115                                TclThreadManager::getInstance().orxonoxEvalCondition_.notify_one();
     116                                boost::this_thread::yield();
     117                            }
     118                        } catch (...) {}
     119                        delete bundle->interpreter_;
     120                        delete bundle;
     121                        TclThreadManager::getInstance().interpreterBundles_.erase(threadID);
     122                        break;
     123                    }
     124                }
     125
     126                TclThreadManager::getInstance().orxonoxEvalCondition_.notify_one();
     127                boost::this_thread::yield();
     128            }
     129
     130            COUT(0) << "Destroyed Tcl-interpreter with ID " << threadID << std::endl;
    115131        }
    116132    }
     
    158174        if (bundle)
    159175        {
    160             boost::mutex::scoped_lock lock(bundle->runningMutex_);
     176            boost::mutex::scoped_lock running_lock(bundle->runningMutex_);
    161177            return bundle->running_;
    162178        }
     
    201217    TclInterpreterBundle* TclThreadManager::getInterpreterBundle(unsigned int threadID)
    202218    {
    203         if (threadID == 0)
    204             return &this->orxonoxInterpreterBundle_;
    205 
    206         boost::mutex::scoped_lock lock(this->bundlesMutex_);
     219        boost::mutex::scoped_lock bundles_lock(this->bundlesMutex_);
    207220        std::map<unsigned int, TclInterpreterBundle*>::iterator it = this->interpreterBundles_.find(threadID);
    208221        if (it != this->interpreterBundles_.end())
     
    212225        else
    213226        {
    214             this->forceCommandToFrontOfQueue("error Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(threadID) + " existing.");
     227            this->error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(threadID) + " existing.");
    215228            return 0;
    216229        }
     
    230243    }
    231244
     245    void TclThreadManager::error(const std::string& error)
     246    {
     247        if (boost::this_thread::get_id() != this->threadID_)
     248        {
     249            boost::mutex::scoped_lock queue_lock(this->orxonoxInterpreterBundle_.queueMutex_);
     250            if (this->orxonoxInterpreterBundle_.queue_.size() >= TCLTHREADMANAGER_MAX_QUEUE_LENGTH)
     251                return;
     252        }
     253
     254        this->forceCommandToFrontOfQueue("error " + error);
     255    }
     256
    232257    void TclThreadManager::pushCommandToQueue(const std::string& command)
    233258    {
    234         boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.queueMutex_);
     259        boost::mutex::scoped_lock queue_lock(this->orxonoxInterpreterBundle_.queueMutex_);
    235260        while (this->orxonoxInterpreterBundle_.queue_.size() >= TCLTHREADMANAGER_MAX_QUEUE_LENGTH)
    236             this->fullQueueCondition_.wait(lock);
     261            this->fullQueueCondition_.wait(queue_lock);
    237262
    238263        this->orxonoxInterpreterBundle_.queue_.push_back(command);
     
    241266    void TclThreadManager::forceCommandToFrontOfQueue(const std::string& command)
    242267    {
    243         boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.queueMutex_);
     268        boost::mutex::scoped_lock queue_lock(this->orxonoxInterpreterBundle_.queueMutex_);
    244269        this->orxonoxInterpreterBundle_.queue_.push_front(command);
    245270    }
     
    247272    std::string TclThreadManager::popCommandFromQueue()
    248273    {
    249         boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.queueMutex_);
     274        boost::mutex::scoped_lock queue_lock(this->orxonoxInterpreterBundle_.queueMutex_);
    250275        std::string temp = this->orxonoxInterpreterBundle_.queue_.front();
    251276        this->orxonoxInterpreterBundle_.queue_.pop_front();
     
    256281    bool TclThreadManager::queueIsEmpty()
    257282    {
    258         boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.queueMutex_);
     283        boost::mutex::scoped_lock queue_lock(this->orxonoxInterpreterBundle_.queueMutex_);
    259284        return this->orxonoxInterpreterBundle_.queue_.empty();
    260285    }
     
    265290        if (bundle)
    266291        {
    267             boost::mutex::scoped_lock lock(bundle->queueMutex_);
     292            boost::mutex::scoped_lock queue_lock(bundle->queueMutex_);
    268293            if (bundle->queue_.size() >= TCLTHREADMANAGER_MAX_QUEUE_LENGTH)
    269294            {
    270                 this->forceCommandToFrontOfQueue("error Error: Queue of Tcl-interpreter " + getConvertedValue<unsigned int, std::string>(threadID) + " is full, couldn't add command.");
     295                this->error("Error: Queue of Tcl-interpreter " + getConvertedValue<unsigned int, std::string>(threadID) + " is full, couldn't add command.");
    271296                return;
    272297            }
     
    281306        if (bundle)
    282307        {
    283             boost::mutex::scoped_lock lock(bundle->queueMutex_);
     308            boost::mutex::scoped_lock queue_lock(bundle->queueMutex_);
    284309            std::string temp = bundle->queue_.front();
    285310            bundle->queue_.pop_front();
     
    294319        if (bundle)
    295320        {
    296             boost::mutex::scoped_lock lock(bundle->queueMutex_);
     321            boost::mutex::scoped_lock queue_lock(bundle->queueMutex_);
    297322            return bundle->queue_.empty();
    298323        }
     
    305330            return false;
    306331
    307         boost::mutex::scoped_lock lock(target->queriersMutex_);
    308 
    309         {
    310             boost::mutex::scoped_lock lock(querier->queriersMutex_);
     332        boost::mutex::scoped_lock queriers_lock(target->queriersMutex_);
     333
     334        {
     335            boost::mutex::scoped_lock queriers_lock(querier->queriersMutex_);
    311336            target->queriers_.insert(target->queriers_.end(), querier->queriers_.begin(), querier->queriers_.end());
    312337        }
     
    316341        if (std::find(target->queriers_.begin(), target->queriers_.end(), target->id_) != target->queriers_.end())
    317342        {
    318             this->forceCommandToFrontOfQueue("error Error: Circular query (" + this->dumpList(target->queriers_) + " -> " + getConvertedValue<unsigned int, std::string>(target->id_) + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target->id_) + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(querier->id_) + ".");
     343            this->error("Error: Circular query (" + this->dumpList(target->queriers_) + " -> " + getConvertedValue<unsigned int, std::string>(target->id_) + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target->id_) + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(querier->id_) + ".");
    319344            return false;
    320345        }
     
    331356            if (this->updateQueriersList(querier, &this->orxonoxInterpreterBundle_))
    332357            {
    333                 boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.interpreterMutex_);
    334                 this->orxonoxEvalCondition_.wait(lock);
     358                boost::mutex::scoped_lock interpreter_lock(this->orxonoxInterpreterBundle_.interpreterMutex_);
     359                this->orxonoxEvalCondition_.wait(interpreter_lock);
    335360
    336361                if (!CommandExecutor::execute(command, false))
    337                     this->forceCommandToFrontOfQueue("error Error: Can't execute command \"" + command + "\"!");
     362                    this->error("Error: Can't execute command \"" + command + "\"!");
    338363
    339364                if (CommandExecutor::getLastEvaluation().hasReturnvalue())
     
    341366            }
    342367
    343             boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.queriersMutex_);
     368            boost::mutex::scoped_lock queriers_lock(this->orxonoxInterpreterBundle_.queriersMutex_);
    344369            this->orxonoxInterpreterBundle_.queriers_.clear();
    345370        }
     
    349374    std::string TclThreadManager::evalQuery(unsigned int querierID, unsigned int threadID, const std::string& command)
    350375    {
    351         TclInterpreterBundle* target = this->getInterpreterBundle(threadID);
     376        TclInterpreterBundle* target = 0;
     377        if (threadID)
     378            target = this->getInterpreterBundle(threadID);
     379        else
     380            target = &this->orxonoxInterpreterBundle_;
     381
    352382        std::string output = "";
    353383        if (target)
     
    363393                if (this->updateQueriersList(querier, target))
    364394                {
    365                     boost::mutex::scoped_lock lock(target->interpreterMutex_, boost::defer_lock_t());
     395                    boost::mutex::scoped_lock interpreter_lock(target->interpreterMutex_, boost::defer_lock_t());
    366396                    bool successfullyLocked = false;
    367397                    try
    368398                    {
    369399                        if (querierID == 0 || std::find(querier->queriers_.begin(), querier->queriers_.end(), (unsigned int)0) != querier->queriers_.end())
    370                             successfullyLocked = lock.try_lock();
     400                            successfullyLocked = interpreter_lock.try_lock();
    371401                        else
    372402                        {
    373                             while (!lock.try_lock())
     403                            while (!interpreter_lock.try_lock())
    374404                                boost::this_thread::yield();
    375405
     
    383413                        {   output = (std::string)target->interpreter_->eval(command);   }
    384414                        catch (Tcl::tcl_error const &e)
    385                         {   this->forceCommandToFrontOfQueue("error Tcl error: " + (std::string)e.what());   }
     415                        {   this->error("Tcl error: " + (std::string)e.what());   }
    386416                        catch (std::exception const &e)
    387                         {   this->forceCommandToFrontOfQueue("error Error while executing Tcl: " + (std::string)e.what());   }
     417                        {   this->error("Error while executing Tcl: " + (std::string)e.what());   }
    388418                    }
    389419                    else
    390420                    {
    391                         this->forceCommandToFrontOfQueue("error Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(threadID) + ", interpreter is busy right now.");
     421                        this->error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(threadID) + ", interpreter is busy right now.");
    392422                    }
    393423                }
    394424
    395                 boost::mutex::scoped_lock lock(target->queriersMutex_);
     425                boost::mutex::scoped_lock queriers_lock(target->queriersMutex_);
    396426                target->queriers_.clear();
    397427            }
     
    408438
    409439        {
    410             boost::mutex::scoped_lock lock(this->bundlesMutex_);
     440            boost::mutex::scoped_lock bundles_lock(this->bundlesMutex_);
    411441            for (std::map<unsigned int, TclInterpreterBundle*>::iterator it = this->interpreterBundles_.begin(); it != this->interpreterBundles_.end(); ++it)
    412442            {
    413                 boost::mutex::scoped_lock lock((*it).second->queueMutex_);
     443                boost::mutex::scoped_lock queue_lock((*it).second->queueMutex_);
    414444                if (!(*it).second->queue_.empty())
    415445                {
    416446                    std::string command = (*it).second->queue_.front();
    417447                    (*it).second->queue_.pop_front();
    418 
    419448                    {
    420                         boost::mutex::scoped_lock lock((*it).second->finishedMutex_);
     449                        boost::mutex::scoped_lock finished_lock((*it).second->finishedMutex_);
    421450                        (*it).second->finished_ = false;
    422451                    }
    423 
    424452                    boost::thread(boost::bind(&tclThread, (*it).second, command));
    425453                }
     
    428456
    429457        {
    430             boost::mutex::scoped_lock lock(this->orxonoxInterpreterBundle_.interpreterMutex_);
     458            boost::mutex::scoped_lock interpreter_lock(this->orxonoxInterpreterBundle_.interpreterMutex_);
    431459            unsigned long maxtime = (unsigned long)(dt * 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE);
    432460            Ogre::Timer timer;
     
    442470    void tclThread(TclInterpreterBundle* interpreterBundle, std::string command)
    443471    {
     472        boost::mutex::scoped_lock interpreter_lock(interpreterBundle->interpreterMutex_);
    444473        try
    445474        {
    446             boost::mutex::scoped_lock lock(interpreterBundle->interpreterMutex_);
    447475            interpreterBundle->interpreter_->eval(command);
    448476        }
    449477        catch (Tcl::tcl_error const &e)
    450478        {
    451             TclThreadManager::getInstance().forceCommandToFrontOfQueue("error Tcl (ID " + getConvertedValue<unsigned int, std::string>(interpreterBundle->id_) + ") error: " + e.what());
     479            TclThreadManager::getInstance().error("Tcl (ID " + getConvertedValue<unsigned int, std::string>(interpreterBundle->id_) + ") error: " + e.what());
    452480        }
    453481        catch (std::exception const &e)
    454482        {
    455             TclThreadManager::getInstance().forceCommandToFrontOfQueue("error Error while executing Tcl (ID " + getConvertedValue<unsigned int, std::string>(interpreterBundle->id_) + "): " + e.what());
    456         }
    457 
    458         boost::mutex::scoped_lock lock(interpreterBundle->finishedMutex_);
     483            TclThreadManager::getInstance().error("Error while executing Tcl (ID " + getConvertedValue<unsigned int, std::string>(interpreterBundle->id_) + "): " + e.what());
     484        }
     485
     486        boost::mutex::scoped_lock finished_lock(interpreterBundle->finishedMutex_);
    459487        interpreterBundle->finished_ = true;
    460488        interpreterBundle->finishedCondition_.notify_all();
  • code/branches/console/src/core/TclThreadManager.h

    r1255 r1257  
    8585            TclInterpreterBundle* getInterpreterBundle(unsigned int threadID);
    8686            std::string dumpList(const std::list<unsigned int>& list);
     87            void error(const std::string& error);
    8788
    8889            void pushCommandToQueue(const std::string& command);
     
    113114            boost::condition fullQueueCondition_;
    114115            boost::condition orxonoxEvalCondition_;
     116            boost::thread::id threadID_;
    115117    };
    116118
Note: See TracChangeset for help on using the changeset viewer.