/*************************************************************************** * Copyright (C) 2005 by Jeff Ferr * * root@sat * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "jthread.h" #include "jthreadexception.h" #include namespace jthread { Thread::Thread() { _is_running = false; } Thread::~Thread() { // Interrupt(); } /** Private */ void * Thread::ThreadMain(void *owner_) { if (owner_ == NULL) { return NULL; } Thread *owner = (Thread *)(owner_); if (owner->SetUp() == 0) { owner->_is_running = true; owner->Run(); owner->_is_running = false; owner->CleanUp(); } owner->SignalThreadDead(); // pthread_exit(NULL); return NULL; } void Thread::SignalThreadDead() { // _condition.Notify(); } /** End */ /** Protected */ int Thread::SetUp() { return 0; } void Thread::Run() { return; } int Thread::CleanUp() { return 0; } /** End */ void Thread::Start() throw(ThreadException) { /** * Permitir criar varias instancias na chamada de Start() */ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == EINVAL) { throw ThreadException("Interrupt is not allowed !"); } if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == EINVAL) { throw ThreadException("Thread is not asynchronous !"); } if (pthread_create(&_thread, NULL, &(Thread::ThreadMain), this)) { throw ThreadException("Unable to create a process to suport the ... !"); } pthread_detach(_thread); } void Thread::Interrupt() throw(ThreadException) { if (_is_running == true) { _is_running = false; SignalThreadDead(); if (pthread_cancel(_thread) == ESRCH) { // throw ThreadException("Thread cancel exception !"); } } } void Thread::Suspend() { } void Thread::Resume() { } bool Thread::IsStarted() { return _is_running; } void Thread::SetPolicy(thread_policy_t policy, thread_priority_t priority) throw(ThreadException) { struct sched_param param; param.__sched_priority = priority; int result; result = pthread_setschedparam(_thread, policy, ¶m); if (result == EINVAL) { throw ThreadException("Policy is not defined !"); } else if (result == EPERM) { throw ThreadException("The process does not have superuser permission !"); } else if (result == ESRCH) { throw ThreadException("This thread has already terminated !"); } else if (result < 0) { throw ThreadException("Unknown exception in set policy !"); } } void Thread::GetPolicy(thread_policy_t *policy, thread_priority_t *priority) throw(ThreadException) { struct sched_param param; int policy_int, result; result = pthread_getschedparam(_thread, &policy_int, ¶m); if (result == ESRCH) { throw ThreadException("This thread has already terminated !"); } else if (result < 0) { throw ThreadException("Unknown exception in set policy !"); } switch (param.__sched_priority) { case 0: (*priority) = LOW_PRIORITY; break; case 1: case 2: case 3: case 4: case 5: (*priority) = NORMAL_PRIORITY; break; case 6: case 7: case 8: case 9: case 10: (*priority) = HIGH_PRIORITY; break; default: (*priority) = NORMAL_PRIORITY; break; } switch (policy_int) { case SCHED_OTHER: (*policy) = POLICY_OTHER; break; case SCHED_FIFO: (*policy) = POLICY_FIFO; break; case SCHED_RR: (*policy) = POLICY_ROUND_ROBIN; break; } } void Thread::WaitThread() { /* while (_is_running == true) { _condition.Wait(); } */ sleep(1); } };