| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include <decaf/util/concurrent/PooledThread.h> |
| #include <decaf/util/concurrent/ThreadPool.h> |
| #include <decaf/util/concurrent/TaskListener.h> |
| #include <decaf/lang/exceptions/IllegalArgumentException.h> |
| |
| #include <iostream> |
| |
| using namespace decaf; |
| using namespace decaf::lang; |
| using namespace decaf::lang::exceptions; |
| using namespace decaf::util; |
| using namespace decaf::util::concurrent; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| LOGDECAF_INITIALIZE(logger, PooledThread, "com.activemq.concurrent.PooledThread") |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| PooledThread::PooledThread(ThreadPool* pool) |
| { |
| if(pool == NULL) |
| { |
| throw IllegalArgumentException( __FILE__, __LINE__, |
| "PooledThread::PooledThread"); |
| } |
| |
| busy = false; |
| done = false; |
| |
| listener = NULL; |
| |
| // Store our Pool. |
| this->pool = pool; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| PooledThread::~PooledThread() |
| { |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void PooledThread::run(void) |
| { |
| ThreadPool::Task task; |
| |
| try |
| { |
| while(!done) |
| { |
| //LOGCMS_DEBUG(logger, "PooledThread::run - Entering deQ"); |
| |
| // Blocks until there something to be done |
| task = pool->deQueueTask(); |
| |
| //LOGCMS_DEBUG(logger, "PooledThread::run - Exited deQ"); |
| |
| // Check if the Done Flag is set, in case it happened while we |
| // were waiting for a task |
| if(done) |
| { |
| break; |
| } |
| |
| // If we got here and the runnable was null then something |
| // bad must have happened. Throw an Exception and bail. |
| if(!task.first) |
| { |
| throw Exception( __FILE__, __LINE__, |
| "PooledThread::run - Retrieive NULL task from Pool."); |
| } |
| |
| // Got some work to do, so set flag to busy |
| busy = true; |
| |
| // Inform a listener that we are going to start |
| if(listener) |
| { |
| /*LOGCMS_DEBUG(logger, |
| "PooledThread::run - Inform Listener we are starting");*/ |
| listener->onTaskStarted(this); |
| } |
| |
| // Perform the work |
| task.first->run(); |
| |
| /*LOGCMS_DEBUG(logger, |
| "PooledThread::run - Inform Task Listener we are done");*/ |
| |
| // Notify the Task listener that we are done |
| task.second->onTaskComplete(task.first); |
| |
| // Inform a listener that we are going to stop and wait |
| // for a new task |
| if(listener) |
| { |
| /*LOGCMS_DEBUG(logger, |
| "PooledThread::run - Inform Listener we are done");*/ |
| listener->onTaskCompleted(this); |
| } |
| |
| // Set flag to inactive, we will wait for work |
| busy = false; |
| } |
| } |
| catch( Exception& ex ) |
| { |
| ex.setMark( __FILE__, __LINE__ ); |
| |
| // Notify the Task owner |
| if(task.first && task.second) |
| { |
| task.second->onTaskException(task.first, ex); |
| } |
| |
| busy = false; |
| |
| // Notify the PooledThreadListener |
| if(listener) |
| { |
| listener->onTaskException(this, ex); |
| } |
| } |
| catch(...) |
| { |
| Exception ex( |
| __FILE__, __LINE__, |
| "PooledThread::run - Caught Unknown Exception"); |
| |
| // Notify the Task owner |
| if(task.first && task.second) |
| { |
| task.second->onTaskException(task.first, ex); |
| } |
| |
| busy = false; |
| |
| // Notify the PooledThreadListener |
| if(listener) |
| { |
| listener->onTaskException(this, ex); |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| void PooledThread::stop(void) throw ( Exception ) |
| { |
| done = true; |
| } |